-
-
Notifications
You must be signed in to change notification settings - Fork 0
Propagate changes from main into development #430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Co-authored-by: Wikid82 <176516789+Wikid82@users.noreply.github.com>
Co-authored-by: Wikid82 <176516789+Wikid82@users.noreply.github.com>
Co-authored-by: Wikid82 <176516789+Wikid82@users.noreply.github.com>
Co-authored-by: Wikid82 <176516789+Wikid82@users.noreply.github.com>
Co-authored-by: Wikid82 <176516789+Wikid82@users.noreply.github.com>
…ssue-33 feat: implement multi-language support (i18n) for UI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR propagates i18n (internationalization) implementation changes from main into development, adding comprehensive multi-language support to the Charon application with 5 languages (English, Spanish, French, German, and Chinese).
Key Changes:
- Complete i18n infrastructure using i18next with automatic language detection and localStorage persistence
- 5 translation files with 130+ keys each covering UI elements, navigation, errors, and notifications
- New LanguageSelector component integrated into System Settings for instant language switching
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
frontend/src/i18n.ts |
Core i18n configuration with language detection and fallback settings |
frontend/src/context/LanguageContext.tsx |
React context provider for language state management |
frontend/src/context/LanguageContextValue.ts |
TypeScript types for language context |
frontend/src/hooks/useLanguage.ts |
Custom hook for accessing language context |
frontend/src/components/LanguageSelector.tsx |
UI component for language selection dropdown |
frontend/src/main.tsx |
Integration of LanguageProvider into app root |
frontend/src/pages/SystemSettings.tsx |
Addition of language selector to settings page |
frontend/src/locales/*/translation.json |
Translation files for 5 languages (en, es, fr, de, zh) |
frontend/src/__tests__/i18n.test.ts |
Unit tests for i18n configuration |
frontend/src/hooks/__tests__/useLanguage.test.tsx |
Unit tests for language hook |
frontend/src/components/__tests__/LanguageSelector.test.tsx |
Unit tests for language selector component |
frontend/src/pages/__tests__/SystemSettings.test.tsx |
Updated tests with LanguageProvider and i18next mock |
frontend/package.json |
Added i18next dependencies (i18next, react-i18next, i18next-browser-languagedetector) |
frontend/package-lock.json |
Dependency lock file updates for new packages |
CONTRIBUTING_TRANSLATIONS.md |
Comprehensive guide for contributing translations |
docs/i18n-examples.md |
Developer guide with implementation examples |
docs/features.md |
Updated with multi-language feature documentation |
I18N_IMPLEMENTATION_SUMMARY.md |
Complete implementation summary and metrics |
Files not reviewed (1)
- frontend/package-lock.json: Language not supported
| const setLanguage = (lang: Language) => { | ||
| setLanguageState(lang) | ||
| localStorage.setItem('charon-language', lang) | ||
| i18n.changeLanguage(lang) |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The setLanguage function calls i18n.changeLanguage twice unnecessarily. When setLanguage is called, it invokes i18n.changeLanguage on line 19. Then, the useEffect hook on lines 12-14 detects the state change and calls i18n.changeLanguage again. This creates redundant language change operations. Remove the i18n.changeLanguage call from the setLanguage function since the useEffect will handle the language change whenever the state updates.
| i18n.changeLanguage(lang) |
| export function LanguageProvider({ children }: { children: ReactNode }) { | ||
| const { i18n } = useTranslation() | ||
| const [language, setLanguageState] = useState<Language>(() => { | ||
| const saved = localStorage.getItem('charon-language') | ||
| return (saved as Language) || 'en' |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The saved language from localStorage is not validated before use. If a user manually modifies localStorage to contain an invalid language code, it will be cast to the Language type without validation, potentially causing runtime errors. Add validation to ensure the saved value is one of the supported languages before using it.
| export function LanguageProvider({ children }: { children: ReactNode }) { | |
| const { i18n } = useTranslation() | |
| const [language, setLanguageState] = useState<Language>(() => { | |
| const saved = localStorage.getItem('charon-language') | |
| return (saved as Language) || 'en' | |
| const SUPPORTED_LANGUAGES: Language[] = ['en', 'es', 'fr', 'de', 'zh'] | |
| export function LanguageProvider({ children }: { children: ReactNode }) { | |
| const { i18n } = useTranslation() | |
| const [language, setLanguageState] = useState<Language>(() => { | |
| const saved = localStorage.getItem('charon-language') | |
| if (saved && (SUPPORTED_LANGUAGES as readonly string[]).includes(saved)) { | |
| return saved as Language | |
| } | |
| return 'en' |
Automated PR to propagate changes from main into development.
Triggered by push to main.