fix(web): флаги стран, FormDatePicker и плоские таблицы без двойной рамки
SVG-флаги через flagcdn и resolveCountryCode; поле «Оплачено до» — компактный Popover+Calendar на русском; DataGridCard без вложенной обводки. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import type { DateSelectorI18nConfig } from '@/components/reui/date-selector'
|
||||
|
||||
/** Русская локализация ReUI DateSelector (фильтры, не формы). */
|
||||
export const RU_DATE_SELECTOR_I18N: DateSelectorI18nConfig = {
|
||||
selectDate: 'Выберите дату',
|
||||
apply: 'Применить',
|
||||
cancel: 'Отмена',
|
||||
clear: 'Очистить',
|
||||
today: 'Сегодня',
|
||||
filterTypes: {
|
||||
is: 'равно',
|
||||
before: 'до',
|
||||
after: 'после',
|
||||
between: 'между',
|
||||
},
|
||||
periodTypes: {
|
||||
day: 'День',
|
||||
month: 'Месяц',
|
||||
quarter: 'Квартал',
|
||||
halfYear: 'Полгода',
|
||||
year: 'Год',
|
||||
},
|
||||
months: [
|
||||
'Январь',
|
||||
'Февраль',
|
||||
'Март',
|
||||
'Апрель',
|
||||
'Май',
|
||||
'Июнь',
|
||||
'Июль',
|
||||
'Август',
|
||||
'Сентябрь',
|
||||
'Октябрь',
|
||||
'Ноябрь',
|
||||
'Декабрь',
|
||||
],
|
||||
monthsShort: [
|
||||
'Янв',
|
||||
'Фев',
|
||||
'Мар',
|
||||
'Апр',
|
||||
'Май',
|
||||
'Июн',
|
||||
'Июл',
|
||||
'Авг',
|
||||
'Сен',
|
||||
'Окт',
|
||||
'Ноя',
|
||||
'Дек',
|
||||
],
|
||||
quarters: ['1 кв.', '2 кв.', '3 кв.', '4 кв.'],
|
||||
halfYears: ['1 пол.', '2 пол.'],
|
||||
weekdays: [
|
||||
'воскресенье',
|
||||
'понедельник',
|
||||
'вторник',
|
||||
'среда',
|
||||
'четверг',
|
||||
'пятница',
|
||||
'суббота',
|
||||
],
|
||||
weekdaysShort: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
|
||||
placeholder: 'Выберите дату…',
|
||||
rangePlaceholder: 'Выберите период…',
|
||||
}
|
||||
@@ -1,4 +1,9 @@
|
||||
import type { Settings, RatesData, Vps, Provider } from '@/types/entities'
|
||||
import { COUNTRIES, COUNTRY_BY_CODE, COUNTRY_BY_NAME_RU } from '@cfdm/shared/geo'
|
||||
|
||||
const COUNTRY_BY_NAME_EN: Record<string, { code: string }> = Object.fromEntries(
|
||||
COUNTRIES.map((c) => [c.nameEn.toLowerCase(), c]),
|
||||
)
|
||||
|
||||
export function uid(): string {
|
||||
if (typeof crypto !== 'undefined' && crypto.randomUUID) return crypto.randomUUID()
|
||||
@@ -30,11 +35,32 @@ const COUNTRY_CODE_BY_NAME: Record<string, string> = {
|
||||
canada: 'CA', brazil: 'BR', turkey: 'TR', georgia: 'GE', kazakhstan: 'KZ',
|
||||
}
|
||||
|
||||
/** ISO 3166-1 alpha-2 по русскому/английскому названию или коду. */
|
||||
export function resolveCountryCode(country?: string): string | undefined {
|
||||
if (!country) return undefined
|
||||
const normalized = country.trim()
|
||||
const lower = normalized.toLowerCase()
|
||||
if (/^[a-z]{2}$/i.test(normalized)) {
|
||||
const upper = normalized.toUpperCase()
|
||||
if (COUNTRY_BY_CODE[upper]) return upper
|
||||
}
|
||||
return (
|
||||
COUNTRY_BY_NAME_RU[lower]?.code
|
||||
?? COUNTRY_BY_NAME_EN[lower]?.code
|
||||
?? COUNTRY_CODE_BY_NAME[lower]
|
||||
)
|
||||
}
|
||||
|
||||
/** URL SVG-флага (flagcdn). */
|
||||
export function getCountryFlagUrl(code?: string): string | undefined {
|
||||
if (!code || code.length !== 2) return undefined
|
||||
return `https://flagcdn.com/${code.toLowerCase()}.svg`
|
||||
}
|
||||
|
||||
export function getCountryFlagEmoji(country?: string): string {
|
||||
if (!country) return '🌐'
|
||||
const code = COUNTRY_CODE_BY_NAME[country.trim().toLowerCase()]
|
||||
const code = resolveCountryCode(country)
|
||||
if (!code) return '🌐'
|
||||
return code.toUpperCase().split('').map((c) => String.fromCodePoint(127397 + c.charCodeAt(0))).join('')
|
||||
return getCountryFlagEmojiByCode(code)
|
||||
}
|
||||
|
||||
/** Флаг по ISO 3166-1 alpha-2 коду страны. */
|
||||
|
||||
Reference in New Issue
Block a user