diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 0e8dd00..c910e5e 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -249,7 +249,7 @@ Plans: | 31. Mobile Polish | v2.2 | 2/2 | Complete | 2026-04-12 | | 32. Setup Sharing System | v2.3 | 0/4 | Planned | — | | 33. Currency System | v2.3 | 6/6 | Complete | 2026-04-13 | -| 34. i18n Foundation | v2.3 | 0/5 | Complete | 2026-04-13 | +| 34. i18n Foundation | v2.3 | 2/8 | In Progress| | ## Backlog diff --git a/.planning/STATE.md b/.planning/STATE.md index 5848c62..84cd610 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,15 +3,15 @@ gsd_state_version: 1.0 milestone: v2.3 milestone_name: Global & Social Ready status: executing -stopped_at: Phase 34 context gathered -last_updated: "2026-04-13T16:27:56.612Z" -last_activity: 2026-04-13 -- Phase 34 execution started +stopped_at: Completed 34-02-PLAN.md +last_updated: "2026-04-18T12:02:16.063Z" +last_activity: 2026-04-18 progress: total_phases: 16 completed_phases: 6 - total_plans: 26 - completed_plans: 21 - percent: 81 + total_plans: 29 + completed_plans: 23 + percent: 79 --- # Project State @@ -26,9 +26,9 @@ See: .planning/PROJECT.md (updated 2026-04-09) ## Current Position Phase: 34 (i18n-foundation) — EXECUTING -Plan: 1 of 5 -Status: Executing Phase 34 -Last activity: 2026-04-13 -- Phase 34 execution started +Plan: 2 of 5 +Status: Ready to execute +Last activity: 2026-04-18 Progress: [░░░░░░░░░░] 0% @@ -83,6 +83,8 @@ v2.1 decisions: - [Phase 32]: Visibility→private deactivates share links; switching back reactivates non-expired ones - [Phase 32]: /s/:token short URL redirects to /setups/:id?share=token; /api/shared/:token returns setup data without auth - [Phase 32]: ShareModal replaces old globe toggle — Google Docs-style with visibility picker + link management +- [Phase 34]: Created catalog namespace for global-items/discover page +- [Phase 34]: Static lookup tables (icons, CSS) kept at module level; only label strings moved inside components for t() access ### Pending Todos @@ -99,9 +101,10 @@ None. | 260411-022 | Fix global items search bar layout - too tall and hard to navigate back | 2026-04-10 | ef48891 | [260411-022-fix-global-items-search-bar-layout-too-t](./quick/260411-022-fix-global-items-search-bar-layout-too-t/) | | 260411-0zq | Redesign search UX — real nav search bar navigating to /global-items?q= | 2026-04-10 | 334bf33 | [260411-0zq-redesign-search-ux-bigger-nav-search-bar](./quick/260411-0zq-redesign-search-ux-bigger-nav-search-bar/) | | 260411-1h2 | Rebuild global items page with sticky toolbar and inline filters | 2026-04-10 | ee3b6f7 | [260411-1h2-rebuild-global-items-page-with-sticky-se](./quick/260411-1h2-rebuild-global-items-page-with-sticky-se/) | +| Phase 34 P02 | 122 | 5 tasks | 25 files | ## Session Continuity -Last session: 2026-04-13T16:00:10.938Z -Stopped at: Phase 34 context gathered -Resume file: .planning/phases/34-i18n-foundation/34-CONTEXT.md +Last session: 2026-04-18T12:02:16.060Z +Stopped at: Completed 34-02-PLAN.md +Resume file: None diff --git a/.planning/phases/34-i18n-foundation/34-02-SUMMARY.md b/.planning/phases/34-i18n-foundation/34-02-SUMMARY.md new file mode 100644 index 0000000..d131107 --- /dev/null +++ b/.planning/phases/34-i18n-foundation/34-02-SUMMARY.md @@ -0,0 +1,116 @@ +--- +phase: "34" +plan: "02" +subsystem: "client-i18n" +tags: ["i18n", "react-i18next", "locale", "hardcoded-strings"] +dependency_graph: + requires: ["34-01"] + provides: ["all-ui-strings-translated"] + affects: ["client/components", "client/routes", "client/locales"] +tech_stack: + added: ["catalog namespace (en/de)"] + patterns: ["useTranslation hook", "multi-namespace pattern", "t() interpolation with variables"] +key_files: + created: + - src/client/locales/en/catalog.json + - src/client/locales/de/catalog.json + modified: + - src/client/components/AddToCollectionModal.tsx + - src/client/routes/collection/index.tsx + - src/client/routes/threads/$threadId/index.tsx + - src/client/routes/items/$itemId.tsx + - src/client/routes/setups/$setupId.tsx + - src/client/routes/users/$userId.tsx + - src/client/routes/global-items/index.tsx + - src/client/locales/en/collection.json + - src/client/locales/en/threads.json + - src/client/locales/en/setups.json + - src/client/locales/en/common.json + - src/client/locales/de/collection.json + - src/client/locales/de/threads.json + - src/client/locales/de/setups.json + - src/client/locales/de/common.json + - src/client/lib/i18n.ts +decisions: + - "Created catalog namespace for global-items/discover page rather than reusing common" + - "Language option labels (English/Deutsch) left as literals — native names are not translated by convention" + - "Static data (icon names, CSS classes) kept as module-level constants; only label strings moved inside components" +metrics: + duration: "~4 hours (multi-session)" + completed: "2026-04-18" + tasks_completed: 5 + files_modified: 25 +--- + +# Phase 34 Plan 02: Extract Hardcoded UI Strings Summary + +All hardcoded English strings in UI components replaced with react-i18next `t()` calls, with full English and German locale coverage added for all new keys. + +## Tasks Completed + +| Task | Description | Commit | +|------|-------------|--------| +| 1 | Audit hardcoded strings across all components | (analysis only) | +| 2 | i18n collection and item components | c5af124 | +| 3 | Extract strings from thread/candidate components | 6fd8874 | +| 4 | Extract strings from modals, routes, and catalog | 2aa156a | +| 5 | Onboarding and settings (already i18n — no changes needed) | — | + +## Scope + +Components updated in Task 2-3 (from prior session): +- CandidateCard, CandidateListItem, CandidateForm, ComparisonTable, StatusBadge +- CreateThreadModal, AddToThreadModal +- SetupsView, SetupCard, ShareModal + +Components updated in Task 4 (this session): +- AddToCollectionModal +- routes/collection/index.tsx (tab labels) +- routes/threads/$threadId/index.tsx (thread detail + AddCandidateModal) +- routes/items/$itemId.tsx (item detail page) +- routes/setups/$setupId.tsx (setup detail page) +- routes/users/$userId.tsx (public profile page) +- routes/global-items/index.tsx (catalog/discover page) + +## Locale Files Extended + +### English +- `collection.json`: added `addToCollection`, `item` sections +- `threads.json`: added `candidateForm.priceLabel`, `detail` section +- `setups.json`: added `namePlaceholder`, `creating`, `emptyState`, `detail`, `profile` sections +- `common.json`: added `actions.duplicate` +- `catalog.json`: created new namespace for global-items page + +### German (parity with English) +- `collection.json`: added all missing sections to reach parity with English +- `threads.json`: added all missing sections (card, candidateCard, candidateForm, comparisonTable, addToThread, statusBadge, planning, detail) +- `setups.json`: added namePlaceholder, creating, emptyState, detail, profile, impact.compareWith +- `common.json`: added actions.duplicate, home, imageUpload, profile sections +- `catalog.json`: created new namespace with German translations + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 2 - Missing functionality] Created catalog.json namespace** +- **Found during:** Task 4 (global-items route) +- **Issue:** No dedicated namespace existed for the catalog/discover page strings +- **Fix:** Created `src/client/locales/en/catalog.json` and `src/client/locales/de/catalog.json`, registered in i18n.ts +- **Files modified:** `src/client/lib/i18n.ts`, both catalog.json files +- **Commit:** 2aa156a + +**2. [Rule 2 - Missing functionality] German locale parity** +- **Found during:** Task 4 completion +- **Issue:** German locale files were missing large sections added to English in this plan +- **Fix:** Added all missing German translations for collection, threads, setups, common namespaces +- **Files modified:** de/collection.json, de/threads.json, de/setups.json, de/common.json +- **Commit:** 2aa156a + +### Skipped Items +- Task 5 (onboarding + settings): All 5 onboarding components and settings.tsx were already fully i18n-wired with `useTranslation`. Only language option labels (`"English"`, `"Deutsch"`) remain as literals — these are native language names conventionally left untranslated. + +## Known Stubs + +None — all t() calls reference real locale keys that exist in both en and de files. + +## Self-Check: PASSED