Files
konstruct/.planning/phases/07-multilanguage/07-03-PLAN.md

14 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
07-multilanguage 03 execute 2
07-01
07-02
packages/portal/components/nav.tsx
packages/portal/components/agent-designer.tsx
packages/portal/components/billing-status.tsx
packages/portal/components/budget-alert-badge.tsx
packages/portal/components/chat-message.tsx
packages/portal/components/chat-sidebar.tsx
packages/portal/components/chat-window.tsx
packages/portal/components/employee-wizard.tsx
packages/portal/components/impersonation-banner.tsx
packages/portal/components/message-volume-chart.tsx
packages/portal/components/onboarding-stepper.tsx
packages/portal/components/provider-cost-chart.tsx
packages/portal/components/subscription-card.tsx
packages/portal/components/template-gallery.tsx
packages/portal/components/tenant-form.tsx
packages/portal/components/tenant-switcher.tsx
packages/portal/app/(dashboard)/dashboard/page.tsx
packages/portal/app/(dashboard)/agents/page.tsx
packages/portal/app/(dashboard)/agents/[id]/page.tsx
packages/portal/app/(dashboard)/agents/new/page.tsx
packages/portal/app/(dashboard)/agents/new/templates/page.tsx
packages/portal/app/(dashboard)/agents/new/wizard/page.tsx
packages/portal/app/(dashboard)/agents/new/advanced/page.tsx
packages/portal/app/(dashboard)/chat/page.tsx
packages/portal/app/(dashboard)/billing/page.tsx
packages/portal/app/(dashboard)/usage/page.tsx
packages/portal/app/(dashboard)/usage/[tenantId]/page.tsx
packages/portal/app/(dashboard)/settings/api-keys/page.tsx
packages/portal/app/(dashboard)/users/page.tsx
packages/portal/app/(dashboard)/admin/users/page.tsx
packages/portal/app/(dashboard)/tenants/page.tsx
packages/portal/app/(dashboard)/tenants/new/page.tsx
packages/portal/app/(dashboard)/tenants/[id]/page.tsx
packages/portal/app/(dashboard)/onboarding/page.tsx
packages/portal/app/(dashboard)/onboarding/steps/connect-channel.tsx
packages/portal/app/(dashboard)/onboarding/steps/configure-agent.tsx
packages/portal/app/(dashboard)/onboarding/steps/test-message.tsx
packages/portal/app/invite/[token]/page.tsx
packages/portal/components/wizard-steps/step-role.tsx
packages/portal/components/wizard-steps/step-persona.tsx
packages/portal/components/wizard-steps/step-tools.tsx
packages/portal/components/wizard-steps/step-channels.tsx
packages/portal/components/wizard-steps/step-escalation.tsx
packages/portal/components/wizard-steps/step-review.tsx
true
I18N-01
I18N-04
I18N-05
truths artifacts key_links
Every user-visible string in the portal uses useTranslations() instead of hardcoded English
Navigation labels render in the selected language
Agent designer, wizard, and template gallery are fully translated
Onboarding flow steps are fully translated
Error messages and validation text render in the selected language
Chat UI, billing, usage, and all other pages are translated
path provides contains
packages/portal/components/nav.tsx Translated navigation labels useTranslations
path provides contains
packages/portal/components/employee-wizard.tsx Translated wizard UI useTranslations
path provides contains
packages/portal/components/template-gallery.tsx Translated template cards with locale-aware API calls useTranslations
path provides contains
packages/portal/app/(dashboard)/chat/page.tsx Translated chat interface useTranslations
from to via pattern
All portal components packages/portal/messages/{locale}.json useTranslations() hook reading from NextIntlClientProvider context useTranslations
from to via pattern
packages/portal/components/template-gallery.tsx /api/portal/templates?locale= Locale query param passed to templates API locale
Extract all hardcoded English strings from every portal page and component, replacing them with `useTranslations()` calls that read from the en/es/pt message files created in Plan 02.

Purpose: This is the core localization work. Every user-visible string in every TSX file must be replaced with a t('key') call. Without this, the message files and i18n infrastructure from Plan 02 have no effect. Output: All 40+ portal TSX files updated with useTranslations() calls. Zero hardcoded English strings remain in user-visible UI.

<execution_context> @/home/adelorenzo/.claude/get-shit-done/workflows/execute-plan.md @/home/adelorenzo/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/07-multilanguage/07-CONTEXT.md @.planning/phases/07-multilanguage/07-RESEARCH.md @.planning/phases/07-multilanguage/07-01-SUMMARY.md @.planning/phases/07-multilanguage/07-02-SUMMARY.md ```typescript // In Client Components ('use client'): import { useTranslations } from 'next-intl'; const t = useTranslations('namespace'); // Then:

{t('title')}

// In Server Components: import { useTranslations } from 'next-intl'; const t = useTranslations('namespace'); // Same API — works in both

// Message file structure (from Plan 02): // messages/en.json has nested keys: nav.dashboard, agents.pageTitle, etc. // useTranslations('nav') gives t('dashboard') -> "Dashboard"


<!-- Template gallery needs locale-aware API call -->
```typescript
// Plan 01 adds ?locale= param to templates API
// Template gallery must pass current locale when fetching:
// GET /api/portal/templates?locale=es
Task 1: Extract strings from all components (nav, sidebar, forms, wizards, chat) packages/portal/components/nav.tsx packages/portal/components/agent-designer.tsx packages/portal/components/billing-status.tsx packages/portal/components/budget-alert-badge.tsx packages/portal/components/chat-message.tsx packages/portal/components/chat-sidebar.tsx packages/portal/components/chat-window.tsx packages/portal/components/employee-wizard.tsx packages/portal/components/impersonation-banner.tsx packages/portal/components/message-volume-chart.tsx packages/portal/components/onboarding-stepper.tsx packages/portal/components/provider-cost-chart.tsx packages/portal/components/subscription-card.tsx packages/portal/components/template-gallery.tsx packages/portal/components/tenant-form.tsx packages/portal/components/tenant-switcher.tsx packages/portal/components/wizard-steps/step-role.tsx packages/portal/components/wizard-steps/step-persona.tsx packages/portal/components/wizard-steps/step-tools.tsx packages/portal/components/wizard-steps/step-channels.tsx packages/portal/components/wizard-steps/step-escalation.tsx packages/portal/components/wizard-steps/step-review.tsx For EVERY component listed, apply this transformation:
1. Add `import { useTranslations } from 'next-intl';` (for 'use client' components)
2. At the top of the component function, add `const t = useTranslations('namespace');` where namespace matches the message file key group (e.g., 'nav' for nav.tsx, 'wizard' for wizard steps, 'chat' for chat components)
3. Replace every hardcoded English string with `t('keyName')` — use the exact keys from the en.json message file created in Plan 02
4. For strings with interpolation (e.g., "Welcome, {name}"), use `t('welcome', { name })` and ensure the message file uses ICU format: "Welcome, {name}"
5. For nav.tsx specifically: replace the hardcoded label strings in the navItems array with t() calls. Since navItems is defined outside the component, move the labels inside the component function or use a computed items pattern.

Specific component notes:
- nav.tsx: navItems labels ("Dashboard", "Employees", etc.) -> t('dashboard'), t('employees'), etc. "Sign out" -> t('signOut')
- template-gallery.tsx: Pass locale to templates API call: fetch(`/api/portal/templates?locale=${currentLocale}`). Get current locale from cookie or useLocale() from next-intl.
- employee-wizard.tsx: All step labels, button text, form labels
- onboarding-stepper.tsx: Step titles and descriptions
- agent-designer.tsx: Field labels, button text, placeholders
- chat-window.tsx: "Type a message", "Send", placeholder text
- chat-sidebar.tsx: "New Conversation", "No conversations"
- billing-status.tsx: Status labels, button text
- subscription-card.tsx: Plan names, subscribe/manage buttons
- tenant-form.tsx: Form labels, submit buttons
- tenant-switcher.tsx: "Select tenant", "All tenants"
- impersonation-banner.tsx: Banner text, stop button
- budget-alert-badge.tsx: "No limit set", budget alert text

Do NOT translate:
- Component prop names or internal variable names
- CSS class strings
- API endpoint URLs
- Console.log messages
- aria-label values that are already descriptive (but DO translate user-visible aria-labels)
cd /home/adelorenzo/repos/konstruct/packages/portal && npx next build 2>&1 | tail -20 - All 22 component files use useTranslations() for every user-visible string - No hardcoded English strings remain in component files (except technical strings like URLs, class names) - Template gallery passes locale to API - Portal builds successfully Task 2: Extract strings from all page files (dashboard, agents, chat, billing, usage, etc.) packages/portal/app/(dashboard)/dashboard/page.tsx packages/portal/app/(dashboard)/agents/page.tsx packages/portal/app/(dashboard)/agents/[id]/page.tsx packages/portal/app/(dashboard)/agents/new/page.tsx packages/portal/app/(dashboard)/agents/new/templates/page.tsx packages/portal/app/(dashboard)/agents/new/wizard/page.tsx packages/portal/app/(dashboard)/agents/new/advanced/page.tsx packages/portal/app/(dashboard)/chat/page.tsx packages/portal/app/(dashboard)/billing/page.tsx packages/portal/app/(dashboard)/usage/page.tsx packages/portal/app/(dashboard)/usage/[tenantId]/page.tsx packages/portal/app/(dashboard)/settings/api-keys/page.tsx packages/portal/app/(dashboard)/users/page.tsx packages/portal/app/(dashboard)/admin/users/page.tsx packages/portal/app/(dashboard)/tenants/page.tsx packages/portal/app/(dashboard)/tenants/new/page.tsx packages/portal/app/(dashboard)/tenants/[id]/page.tsx packages/portal/app/(dashboard)/onboarding/page.tsx packages/portal/app/(dashboard)/onboarding/steps/connect-channel.tsx packages/portal/app/(dashboard)/onboarding/steps/configure-agent.tsx packages/portal/app/(dashboard)/onboarding/steps/test-message.tsx packages/portal/app/invite/[token]/page.tsx For EVERY page file listed, apply the same transformation pattern as Task 1:
1. Add `import { useTranslations } from 'next-intl';`
2. Add `const t = useTranslations('namespace');` using the appropriate namespace
3. Replace all hardcoded English strings with `t('key')` calls

Page-specific notes:
- dashboard/page.tsx: "Dashboard", "Welcome back", stats labels -> t('dashboard.*')
- agents/page.tsx: "AI Employees", "New Employee", empty state text -> t('agents.*')
- agents/[id]/page.tsx: Agent detail labels, edit/delete buttons -> t('agentDesigner.*')
- agents/new/page.tsx: Three creation options text -> t('agentNew.*')
- agents/new/templates/page.tsx: Template gallery page title -> t('templates.*')
- agents/new/wizard/page.tsx: Wizard page wrapper -> t('wizard.*')
- agents/new/advanced/page.tsx: Advanced mode labels -> t('agentDesigner.*')
- chat/page.tsx: Chat page labels -> t('chat.*')
- billing/page.tsx: Billing page labels, plan info -> t('billing.*')
- usage/page.tsx & usage/[tenantId]/page.tsx: Usage labels, chart titles -> t('usage.*')
- settings/api-keys/page.tsx: API key management labels -> t('apiKeys.*')
- users/page.tsx: User management, invite labels -> t('users.*')
- admin/users/page.tsx: Platform admin user list -> t('adminUsers.*')
- tenants pages: Tenant management labels -> t('tenants.*')
- onboarding pages + steps: All onboarding UI -> t('onboarding.*')
- invite/[token]/page.tsx: Invitation acceptance page -> t('invite.*') (add invite namespace to message files if not already present)

After all string extraction is complete, do a final review of messages/en.json, messages/es.json, and messages/pt.json to ensure every key used by t() exists in all three files. Add any missing keys discovered during extraction.

IMPORTANT: If any page is a Server Component (no 'use client'), useTranslations still works the same way in next-intl v4 — it reads from the server context set up by i18n/request.ts. No change needed.
cd /home/adelorenzo/repos/konstruct/packages/portal && npx next build 2>&1 | tail -20 - All 22 page files use useTranslations() for every user-visible string - No hardcoded English strings remain in any page file - All translation keys used in t() calls exist in en.json, es.json, and pt.json - Portal builds successfully with zero errors - Portal builds: `cd packages/portal && npx next build` - Grep for remaining hardcoded strings: search for obvious English strings that should be translated - All message file keys are consistent across en.json, es.json, pt.json

<success_criteria>

  • Every user-visible string in the portal uses useTranslations()
  • All three message files (en/es/pt) have matching key structures
  • Template gallery passes locale to API for translated template content
  • Portal builds without errors
  • Zero hardcoded English strings remain in user-facing UI </success_criteria>
After completion, create `.planning/phases/07-multilanguage/07-03-SUMMARY.md`