import { useEffect, useMemo, useState } from 'react' import { Languages, Loader2 } from 'lucide-react' import { useTranslation } from 'react-i18next' import { toast } from 'sonner' import { useAuthStore } from '@/stores/auth-store' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { TitledCard } from '@/components/ui/titled-card' import { updateUserLanguage } from '../api' import { parseUserSettings } from '../lib' import type { UserProfile } from '../types' const LANGUAGE_OPTIONS = [ { value: 'zh', label: '简体中文' }, { value: 'en', label: 'English' }, { value: 'fr', label: 'Français' }, { value: 'ru', label: 'Русский' }, { value: 'ja', label: '日本語' }, { value: 'vi', label: 'Tiếng Việt' }, ] as const function normalizeLanguage(value?: string | null): string { if (!value) return 'en' const normalized = value.trim().replace(/_/g, '-').toLowerCase() if (normalized.startsWith('zh')) return 'zh' return LANGUAGE_OPTIONS.some((lang) => lang.value === normalized) ? normalized : 'en' } type LanguagePreferencesCardProps = { profile: UserProfile | null onProfileUpdate: () => void } export function LanguagePreferencesCard(props: LanguagePreferencesCardProps) { const { t, i18n } = useTranslation() const { auth } = useAuthStore() const [saving, setSaving] = useState(false) const savedLanguage = useMemo(() => { const settings = parseUserSettings(props.profile?.setting) return normalizeLanguage(settings.language || i18n.language) }, [props.profile?.setting, i18n.language]) const [currentLanguage, setCurrentLanguage] = useState(savedLanguage) useEffect(() => { setCurrentLanguage(savedLanguage) }, [savedLanguage]) const handleLanguageChange = async (language: string) => { const nextLanguage = normalizeLanguage(language) if (nextLanguage === currentLanguage) return const previousLanguage = currentLanguage setCurrentLanguage(nextLanguage) setSaving(true) await i18n.changeLanguage(nextLanguage) try { const response = await updateUserLanguage(nextLanguage) if (!response.success) { throw new Error(response.message || t('Failed to update settings')) } if (auth.user) { const existingSetting = typeof auth.user.setting === 'string' ? parseUserSettings(auth.user.setting) : (auth.user.setting ?? {}) auth.setUser({ ...auth.user, setting: JSON.stringify({ ...existingSetting, language: nextLanguage, }), }) } props.onProfileUpdate() toast.success(t('Language preference saved')) } catch (_error) { setCurrentLanguage(previousLanguage) await i18n.changeLanguage(previousLanguage) toast.error(t('Failed to update settings')) } finally { setSaving(false) } } return ( } >
{t('Interface Language')}

{t( 'Language preferences sync across your signed-in devices and affect API error messages.' )}

{saving && ( )}
) }