mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-30 02:23:47 +00:00
Мультиязычность: - LanguageSwitcher на публичной странице покупки - Вкладки локалей в админ-редакторе (ru/en/zh/fa) - LocaleTabs и LocalizedInput компоненты - Типы: LocaleDict, AdminLandingFeature, toLocaleDict хелпер - ?lang= параметр при запросе конфига лендинга Исправления по ревью: - contentIndicators включает все локализуемые поля - LocaleTabs вынесен над секциями аккордеона - text-left → text-start для RTL - nonEmptyDict: защита от undefined - featureIds/methodIds обёрнуты в useMemo - toggleSection/updateFeature* обёрнуты в useCallback - formatPrice вынесен в shared utils/format.ts - RTL через LOCALE_META.rtl вместо хардкода - Переводы zh/fa для валидации и landing - Variable shadowing: t → tariff
71 lines
1.6 KiB
TypeScript
71 lines
1.6 KiB
TypeScript
import { LOCALE_META, type LocaleDict, type SupportedLocale } from '../../api/landings';
|
|
import { cn } from '../../lib/utils';
|
|
|
|
interface LocalizedInputProps {
|
|
value: LocaleDict;
|
|
onChange: (value: LocaleDict) => void;
|
|
locale: SupportedLocale;
|
|
placeholder?: string;
|
|
multiline?: boolean;
|
|
rows?: number;
|
|
maxLength?: number;
|
|
id?: string;
|
|
className?: string;
|
|
}
|
|
|
|
/**
|
|
* An input (or textarea) that edits a single locale key within a LocaleDict.
|
|
* Shows `value[locale]` and updates the dict immutably on change.
|
|
*/
|
|
export function LocalizedInput({
|
|
value,
|
|
onChange,
|
|
locale,
|
|
placeholder,
|
|
multiline = false,
|
|
rows = 2,
|
|
maxLength,
|
|
id,
|
|
className,
|
|
}: LocalizedInputProps) {
|
|
const currentValue = value[locale] ?? '';
|
|
const isRtl = LOCALE_META[locale].rtl;
|
|
|
|
const handleChange = (newText: string) => {
|
|
onChange({ ...value, [locale]: newText });
|
|
};
|
|
|
|
const inputClasses = cn(
|
|
'w-full rounded-lg border border-dark-700 bg-dark-800 px-3 py-2 text-sm text-dark-100 outline-none focus:border-accent-500',
|
|
className,
|
|
);
|
|
|
|
if (multiline) {
|
|
return (
|
|
<textarea
|
|
id={id}
|
|
dir={isRtl ? 'rtl' : 'ltr'}
|
|
value={currentValue}
|
|
onChange={(e) => handleChange(e.target.value)}
|
|
placeholder={placeholder}
|
|
rows={rows}
|
|
maxLength={maxLength}
|
|
className={inputClasses}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<input
|
|
id={id}
|
|
type="text"
|
|
dir={isRtl ? 'rtl' : 'ltr'}
|
|
value={currentValue}
|
|
onChange={(e) => handleChange(e.target.value)}
|
|
placeholder={placeholder}
|
|
maxLength={maxLength}
|
|
className={inputClasses}
|
|
/>
|
|
);
|
|
}
|