7.1 KiB
phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics, requirements
| phase | plan | subsystem | tags | dependency_graph | tech_stack | key_files | decisions | metrics | requirements | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 34-i18n-foundation | 06 | client/i18n |
|
|
|
|
|
|
|
Phase 34 Plan 06: i18n Gap Closure — Routes and Components Summary
Wired useTranslation into all routes and components that had hardcoded English strings, closing the UAT-identified gap where only the settings page, nav bar, and FAB were translated.
What Was Built
Task 1 — Routes and settings currency suggestion (commit 755c0ab):
routes/index.tsx: Section headings (Popular Setups, Recently Added, Trending Categories) now uset("home.*")fromcommonnamespaceroutes/profile.tsx: All sections (Account, Security, Danger Zone) fully translated — email management, password change, account deletion flowroutes/settings.tsx: Currency suggestion banner text usest("currency.suggestion", { symbol, code })with interpolation; Switch button and Dismiss aria-label use t()- Added
home,profile,imageUploadsections to en/de common.json - Added
currency.suggestion,currency.switch,showConversionsto en/de settings.json
Task 2 — 10 remaining components (commit 480abdd):
ThreadTabs.tsx: Tab labels (My Gear → Gear, Planning, Setups) viacollectionnamespacePlanningView.tsx: Section heading, active/resolved tabs, full empty state (title + 3 steps + CTA), "No threads found" — viathreadsnamespaceTotalsBar.tsx: "Sign in" link viacommon.auth.signInThreadCard.tsx: "Resolved" badge and candidate count with plural form ({{count}} candidates/{{count}} candidate)PublicSetupCard.tsx: "by {{name}}" and "Anonymous" fallback; item count with plural formSetupImpactSelector.tsx: "Compare with setup..." placeholder optionClassificationBadge.tsx: base/worn/consumable labels viacollection.classificationBadge.*with defaultValue fallbackImpactDeltaBadge.tsx: "(add)" mode label viasetups.impact.addingImageUpload.tsx: "Click to add photo", invalid type error, file too large error, upload failed errorDashboardCard.tsx: Correctly skipped — all strings are props from caller
New Locale Keys Added
en/de common.json: home.{popularSetups,recentlyAdded,trendingCategories}, imageUpload.{clickToAdd,invalidType,tooLarge,uploadFailed}, profile.{title,account,accountInfo,email,noEmail,change,newEmailPlaceholder,updating,updateEmail,emailUpdated,memberSince,security,managePassword,currentPassword,newPassword,password,confirmPassword,passwordRequirements,passwordUpdated,changingPassword,changePassword,setPassword,dangerZone,dangerZoneDescription,deleteAccount,deleteConfirmMessage,deleteConfirmPlaceholder}
en/de settings.json: currency.{suggestion,switch}, showConversions.{title,description}
en/de collection.json: tabs.setups, totals.{totalWeight,totalCost}, classificationBadge.{base,worn,consumable}
en/de setups.json: card.{by,anonymous}, impact.compareWith
en/de threads.json: card.{candidates,candidates_one}, planning.{title,emptyTitle,createFirst,step1Title,step1Description,step2Title,step2Description,step3Title,step3Description}
Deviations from Plan
Auto-fixed Issues
1. [Rule 1 - Bug] Fixed hardcoded en-US locale in profile.tsx date formatting
- Found during: Task 1
- Issue:
Intl.DateTimeFormat("en-US", ...)for "Member since" date used hardcoded locale - Fix: Changed to
Intl.DateTimeFormat(undefined, ...)to use browser's locale - Files modified: src/client/routes/profile.tsx
2. [Rule 2 - Missing] Fixed ASCII fallbacks in de/common.json filter section
- Found during: Task 1 locale update
- Issue: Existing de/common.json had
"Gegenstaenden"instead of"Gegenständen"in filter.showing - Fix: Updated to use proper umlauts when touching those strings
- Files modified: src/client/locales/de/common.json
Verification
grep -c "useTranslation" src/client/routes/index.tsx→ 4grep -c "useTranslation" src/client/routes/profile.tsx→ 5grep -c "useTranslation" src/client/routes/settings.tsx→ 1 (already had it)- All 10 components (minus DashboardCard which has no hardcoded strings) have useTranslation
bun run buildpasses with no errorsbun test tests/i18n/locales.test.ts→ 19 pass, 0 fail
Commits
| Task | Commit | Description |
|---|---|---|
| Task 1 | 755c0ab |
feat(34-06): wire useTranslation into routes and settings currency suggestion |
| Task 2 | 480abdd |
feat(34-06): wire useTranslation into 10 remaining components |
Known Stubs
None — all translated strings are wired to real locale data.
Threat Flags
None — translation strings are static bundled content, not user input. React JSX escaping prevents XSS per T-34-07.
Self-Check: PASSED
- src/client/routes/index.tsx: exists, contains useTranslation
- src/client/routes/profile.tsx: exists, contains useTranslation
- src/client/routes/settings.tsx: exists, contains useTranslation
- All 10 components modified: confirmed via grep
- Commits
755c0aband480abdd: confirmed in git log - Build: passed
- i18n parity tests: 19/19 passed