diff --git a/src/components/shared/LanguageSwitcher.tsx b/src/components/shared/LanguageSwitcher.tsx new file mode 100644 index 0000000..335059a --- /dev/null +++ b/src/components/shared/LanguageSwitcher.tsx @@ -0,0 +1,36 @@ +import {useLanguage, SUPPORTED_LANGUAGES} from '@/hooks/useLanguage'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu'; +import {Button} from '@/components/ui/button'; +import {Globe} from 'lucide-react'; + +export function LanguageSwitcher() { + const {currentLanguage, changeLanguage} = useLanguage(); + + return ( + + + + + + {SUPPORTED_LANGUAGES.map((lang) => ( + changeLanguage(lang.code)} + className={lang.code === currentLanguage.code ? 'bg-accent' : ''} + > + {lang.nativeName} + {lang.name} + + ))} + + + ); +} diff --git a/src/hooks/useLanguage.ts b/src/hooks/useLanguage.ts new file mode 100644 index 0000000..46f3cc2 --- /dev/null +++ b/src/hooks/useLanguage.ts @@ -0,0 +1,29 @@ +import {useTranslation} from 'react-i18next'; + +export const SUPPORTED_LANGUAGES = [ + {code: 'en', name: 'English', nativeName: 'English'}, + {code: 'zh', name: 'Chinese', nativeName: '中文'}, + {code: 'de', name: 'German', nativeName: 'Deutsch'}, + {code: 'fr', name: 'French', nativeName: 'Français'}, +] as const; + +export type SupportedLanguage = (typeof SUPPORTED_LANGUAGES)[number]['code']; + +export function useLanguage() { + const {i18n} = useTranslation(); + + const currentLanguage = SUPPORTED_LANGUAGES.find( + (lang) => lang.code === i18n.language, + ) ?? SUPPORTED_LANGUAGES[0]; + + const changeLanguage = (langCode: SupportedLanguage) => { + i18n.changeLanguage(langCode); + }; + + return { + currentLanguage, + changeLanguage, + supportedLanguages: SUPPORTED_LANGUAGES, + isLoading: !i18n.isInitialized, + }; +}