i18n: render List/Plan per project.kind in copy (ICU select, EN+FR)

Seen in 1 project by 1 person

About

Follow-up to the project.kind foundation (merged to develop). Make user-facing copy say the right noun — List/Plan (FR liste/plan) — per project.kind, instead of the generic "project"/"projet". Derived words too: sous-projet → sous-liste / sous-plan.

Rule

project.kind ∈ {list, decision, plan} is the source of truth (stored column; kindToTabLabel). Per Yan: a thing is a List or a Plan; "project"/"projet" is RESERVED for the (undefined) both-case and should not appear in normal copy.

Approach (LOCKED): ICU select on kind, per string

For each user-facing string that references a project AND has a project/kind in scope, parameterize it and use an ICU select: {kind, select, plan {…le plan…} other {…la liste…}} (EN: plan {…the plan…} other {…the list…}).

  • other = list (default); a decision kind falls into other unless the string is decision-specific (then add a decision {} branch).
  • Write each FR branch grammatically — this is WHY we use select: handle gender/contractions (le plan / la liste, du plan / de la liste, au plan / à la liste).
  • Pass kind: project.kind (the project in scope, or the chain root's kind) at each call site.

Scope

  • Re-parameterize the ~80 'project'/'projet'/'sous-projet' strings the earlier i18n sweep extracted to t() keys. Components incl: ProjectListView, options/, duplicate/, projectInfo/, public/, projectPage, import, comments/collab, etc. NewProjectModal is already kind-aware — skip it.
  • Localize the kind labels in apps/web/lib/public-section/kind-label.ts (kindLabel returns hardcoded 'List'/'Plan'/'Decision') → render via next-intl so FR shows Liste/Plan/Décision; update its call sites (headers/chips).
  • "sub-project" → sub-list/sub-plan via the same select (incl. the ICU-plural strings — nest select inside plural or vice-versa as needed).

Edge — mixed-kind collections (FLAG, do not guess)

Strings over a COLLECTION of possibly-mixed-kind projects with no single kind in scope ("No projects yet", "Search your projects…", "your projects", umbrella sub-project counts) have no single noun. Use a sensible neutral wording AND enumerate every such string in the hand-off comment for Yan to choose final wording (e.g. "vos listes et plans"). Do not block.

Verify (ONCE, at end — do not chunk)

  • pnpm i18n:check parity (no TODO); web tsc; full web vitest run (wrap/adjust copy-asserting tests in NextIntlClientProvider); shared tests. For FR: export ANTHROPIC_API_KEY=$(grep -E '^ANTHROPIC_API_KEY=' apps/web/.env.local | cut -d= -f2-) then pnpm i18n:translate (or hand-write — i18n:check is the gate).
  • No excluded paths expected. Do NOT auto-merge — large user-facing copy diff needs a human eyeball (esp. FR). Open ONE PR, hand-off comment (incl. the mixed-kind list), set state=review, keep worktree.

Links

No links shared yet.

Listed in

Bookmarked in

Not in any public bookmark categories yet.