feat(web): i18n operator UX — settings, pilot copy, Intl, a11y, API errors (#909) #923
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!923
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "dev/909"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
/settings/languagelocale picker:Intl.DisplayNamesnative labels, immediate redirect on selection,localStorage+ server/mesync best-effortlogin,onboarding,settings-appearance,settings-languagefully migrated to Paraglide messages (m.*); ICU plural proof viaIntl.PluralRulesin the language count subtitlefmtTimeusesgetLocale()so pilot-screen timestamps honour the active locale$localelayout syncsdocument.documentElement.lang/.diron every navigation; RTL detection viagetTextDirection(); 5 a11y contract testslocalizedApiError()maps HTTP 401/403/404/5xx to Paraglide keys; network errors useerror_network; unknown errors carry raw server detail aserr.causeTest plan
$locale.test.tsx)settings.language.test.tsx)🤖 Generated with Claude Code
US-B1–B5 all implemented correctly.
localizedApiError,fmtTimelocale wiring,lang/dirsync, language picker withIntl.DisplayNames+ ICU plural, 12 new tests — all green CI.Nit (not blocking):
language-description<p>sits outside the<section>card — cosmetically fine but semantically it reads as a page footer rather than section copy.PR has conflicts — please rebase on main before merging.
bca0bbb650707f287746