From 2dddf02a216d14c53af6d5bcb585aa2ce346f36f Mon Sep 17 00:00:00 2001 From: Tam Nhu Tran Date: Tue, 3 Mar 2026 01:34:41 +0700 Subject: [PATCH] docs(i18n): add dashboard localization guide and links --- README.md | 2 + docs/i18n-dashboard.md | 113 ++++++++++++++++++++++++++++ docs/project-roadmap.md | 1 + docs/system-architecture/index.md | 4 +- ui/README.md | 119 ++++++++++++++---------------- 5 files changed, 173 insertions(+), 66 deletions(-) create mode 100644 docs/i18n-dashboard.md diff --git a/README.md b/README.md index d626d812..a86b76d6 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ The dashboard provides visual management for all account types: - **Factory Droid**: Track Droid install location and BYOK settings health - **Updates Center**: Track support rollouts (Droid target, CLIProxy provider changes, WebSearch integrations) - **Health Monitor**: Real-time status across all profiles +- **Language Switcher**: Toggle dashboard locale between English and Simplified Chinese **Analytics Dashboard** @@ -515,6 +516,7 @@ See [Remote Proxy documentation](https://docs.ccs.kaitran.ca/features/remote-pro | API Profiles | [docs.ccs.kaitran.ca/providers/api-profiles](https://docs.ccs.kaitran.ca/providers/api-profiles) | | Remote Proxy | [docs.ccs.kaitran.ca/features/remote-proxy](https://docs.ccs.kaitran.ca/features/remote-proxy) | | Cursor IDE (local guide) | [./docs/cursor-integration.md](./docs/cursor-integration.md) | +| Dashboard i18n (local guide) | [./docs/i18n-dashboard.md](./docs/i18n-dashboard.md) | | CLI Reference | [docs.ccs.kaitran.ca/reference/cli-commands](https://docs.ccs.kaitran.ca/reference/cli-commands) | | Architecture | [docs.ccs.kaitran.ca/reference/architecture](https://docs.ccs.kaitran.ca/reference/architecture) | | Troubleshooting | [docs.ccs.kaitran.ca/reference/troubleshooting](https://docs.ccs.kaitran.ca/reference/troubleshooting) | diff --git a/docs/i18n-dashboard.md b/docs/i18n-dashboard.md new file mode 100644 index 00000000..29cb28d4 --- /dev/null +++ b/docs/i18n-dashboard.md @@ -0,0 +1,113 @@ +# Dashboard i18n Guide + +Last Updated: 2026-03-02 + +This document describes the internationalization (i18n) architecture used by the CCS Dashboard (`ui/`), how locale selection works, and how to add new languages safely. + +--- + +## Scope + +Dashboard i18n currently covers UI text rendered by React components. + +- Supported locales today: + - `en` (English) + - `zh-CN` (Simplified Chinese) +- Locale state is persisted in browser localStorage using `ccs-ui-locale`. +- Fallback language is `en`. + +Out of scope: + +- CLI terminal output localization +- Backend/API payload localization + +--- + +## Architecture + +### Initialization + +- File: `ui/src/App.tsx` +- `import '@/lib/i18n'` initializes i18next once before routes render. + +### Translation resources + +- File: `ui/src/lib/i18n.ts` +- Contains `resources` object with locale blocks: + - `en.translation` + - `zh-CN.translation` +- Uses `initReactI18next` for React integration. + +### Locale utilities + +- File: `ui/src/lib/locales.ts` +- Core helpers: + - `normalizeLocale(locale)` maps browser/storage values to supported app locales. + - `getInitialLocale` chooses stored locale, then browser locale, then `en`. + - `persistLocale` writes normalized locale to localStorage. + +### Language switcher + +- File: `ui/src/components/layout/language-switcher.tsx` +- Uses `react-i18next` + shadcn `Select`. +- Calls `persistLocale` and `i18n.changeLanguage` on selection. + +--- + +## Key Conventions + +### Translation key naming + +Use dot-notation namespaces by feature area: + +- `nav.home` +- `cursorPage.title` +- `settingsTabs.web` + +Keep key names stable and semantic to minimize churn across locales. + +### Pluralization + +For count-based strings, use i18next suffix rules: + +- `_one` +- `_other` + +Examples exist in sync/account counters. + +### Interpolation and rich text + +- Use interpolation for runtime values: `t('key', { value })`. +- Prefer plain text keys whenever possible. +- If formatting is required (for example bold segments), use `` instead of `dangerouslySetInnerHTML`. + +--- + +## Adding a New Locale + +When adding a locale such as Vietnamese (`vi`): + +1. Add locale id to the supported locale list in `ui/src/lib/locales.ts`. +2. Add locale display label under `translation.locale` in `ui/src/lib/i18n.ts`. +3. Add a full `.translation` block with all keys. +4. Verify fallback behavior remains `en` for missing keys. +5. Run UI validation and i18n tests: + - `cd ui && bun run validate` + - `cd ui && bun run test:run tests/unit/ui/i18n/language-switcher.test.tsx` +6. Add or update key-parity tests to catch locale drift. + +Tracking issue for comprehensive Vietnamese locale: + +- https://github.com/kaitranntt/ccs/issues/659 + +--- + +## Contributor Checklist + +Before opening a PR that touches i18n: + +- [ ] New UI strings are translated in all supported locales. +- [ ] No raw key literals appear in UI at runtime. +- [ ] No unsafe HTML injection path introduced for translated content. +- [ ] `ui` validate/test commands pass. +- [ ] This document is updated if architecture or conventions changed. diff --git a/docs/project-roadmap.md b/docs/project-roadmap.md index 2ef26085..8a721c93 100644 --- a/docs/project-roadmap.md +++ b/docs/project-roadmap.md @@ -86,6 +86,7 @@ All major modularization work is complete. The codebase evolved from monolithic |-------|-------|------| | #137 | CCS Cannot Connect to IDE, but Native Claude Works | support | | #89 | Add Claude Code CLI flag passthrough for delegation | enhancement | +| #659 | Comprehensive Vietnamese i18n for dashboard | enhancement | ### Low Priority / Questions diff --git a/docs/system-architecture/index.md b/docs/system-architecture/index.md index 38f64bf0..02b3d450 100644 --- a/docs/system-architecture/index.md +++ b/docs/system-architecture/index.md @@ -1,6 +1,6 @@ # CCS System Architecture -Last Updated: 2026-02-16 +Last Updated: 2026-03-02 High-level architecture overview for the CCS (Claude Code Switch) system. @@ -15,6 +15,8 @@ The system consists of two main components: 1. **CLI Application** (`src/`) - Node.js TypeScript CLI 2. **Dashboard UI** (`ui/`) - React web application served by Express +Dashboard localization (i18n) architecture and contributor workflow are documented in [Dashboard i18n Guide](../i18n-dashboard.md). + CCS v7.34 adds Image Analysis Hook for vision model proxying through CLIProxy with automatic injection for all profile types. ``` diff --git a/ui/README.md b/ui/README.md index d2e77611..e65660cd 100644 --- a/ui/README.md +++ b/ui/README.md @@ -1,73 +1,62 @@ -# React + TypeScript + Vite +# CCS Dashboard UI -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. +React + TypeScript + Vite frontend for the CCS local dashboard. -Currently, two official plugins are available: +This UI is served by the CCS web server and is accessed via: -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh - -## React Compiler - -The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). - -## Expanding the ESLint configuration - -If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: - -```js -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... - - // Remove tseslint.configs.recommended and replace with this - tseslint.configs.recommendedTypeChecked, - // Alternatively, use this for stricter rules - tseslint.configs.strictTypeChecked, - // Optionally, add this for stylistic rules - tseslint.configs.stylisticTypeChecked, - - // Other configs... - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]) +```bash +ccs config ``` -You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: +--- -```js -// eslint.config.js -import reactX from 'eslint-plugin-react-x' -import reactDom from 'eslint-plugin-react-dom' +## Development -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... - // Enable lint rules for React - reactX.configs['recommended-typescript'], - // Enable lint rules for React DOM - reactDom.configs.recommended, - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]) +From project root: + +```bash +bun run dev ``` + +This starts the CCS server and serves the dashboard at `http://localhost:3000`. + +From `ui/` only (frontend dev server): + +```bash +cd ui +bun run dev +``` + +--- + +## Quality Commands + +```bash +cd ui +bun run typecheck +bun run lint +bun run validate +bun run test:run +``` + +--- + +## i18n + +Dashboard localization uses `react-i18next`. + +- Main setup: `ui/src/lib/i18n.ts` +- Locale helpers: `ui/src/lib/locales.ts` +- Language switcher: `ui/src/components/layout/language-switcher.tsx` + +For full architecture, conventions, and locale onboarding, see: + +- [`../docs/i18n-dashboard.md`](../docs/i18n-dashboard.md) + +--- + +## Notes + +- UI locale persistence uses browser localStorage key `ccs-ui-locale`. +- Current supported locales are managed in `ui/src/lib/locales.ts`. +- Fallback locale is English (`en`).