Skip to content

feat(analysis): localize bill tooltip copy and make number formatting locale-aware - #38

Merged
AlaskanTuna merged 1 commit into
mainfrom
feat/localize-formatter-tooltips
Aug 25, 2026
Merged

feat(analysis): localize bill tooltip copy and make number formatting locale-aware#38
AlaskanTuna merged 1 commit into
mainfrom
feat/localize-formatter-tooltips

Conversation

@AlaskanTuna

Copy link
Copy Markdown
Owner

Closes #12 — the formatter/tooltip half. The auth-email half landed in #37.

Two genuinely English-only surfaces in a trilingual app

1. BILL_TOOLTIPS / NEM_TOOLTIPS were hardcoded English in lib/formatters.ts — twelve explanatory strings about TNB tariff components and NEM credit flow, rendered through <InfoTooltip> next to labels that were translated. A Malay or Chinese user saw a localized label with an English explanation.

Moved into analysis.json under billBreakdown.tooltips and billBreakdown.nemTooltips, translated for ms and zh, and routed through t(). Only BillBreakdown.tsx consumed them, so the change is contained. Key structure verified identical across locales (305 keys each).

2. Both Intl.NumberFormats were pinned to 'en-MY' — so currency and number grouping ignored the user's language entirely, even though LOCALE_TO_INTL already existed for exactly this and maps zh to zh-Hans-MY.

setFormatterLocale() now rebuilds them, called from LocaleProvider on mount and on every change. A setter rather than a per-call argument because these formatters have ~100 call sites; threading a locale through all of them would be a far larger diff than the behaviour warrants.

Proof it actually varies:

en: RM 1,234,567.89  |  9,876.5 kWh
ms: RM 1,234,567.89  |  9,876.5 kWh
zh: MYR 1,234,567.89 |  9,876.5 kWh

Incidental extraction, and why it was necessary

Importing LOCALE_TO_INTL from i18n.ts broke AnalysisPage.test.tsx: i18n.ts calls i18n.init() at module scope, so any importer drags that in, and a test that mocks i18n was suddenly loading the real one.

Rather than duplicating the map and inviting drift, the locale constants (SUPPORTED_LOCALES, SupportedLocale, DEFAULT_LOCALE, LOCALE_STORAGE_KEY, LOCALE_TO_INTL, isSupportedLocale) moved to a side-effect-free lib/locales.ts. i18n.ts re-exports them, so every existing importer is unaffected.

Correction to an earlier claim

#37's description said "nothing persists User.locale yet, so production still sends English." That was wrong. useLocale.tsx:83 already calls authClient.updateUser({ locale: next }) and reads it back on mount, and config/auth.ts passes it to the email renderers. The localized-email chain has been live end to end since #37 merged.

Verified

pnpm --filter frontend exec tsc --noEmit 0 errors · 216 frontend tests pass · Prettier clean · no BILL_TOOLTIPS/NEM_TOOLTIPS references remain.

https://claude.ai/code/session_01URDpaxhXyPLWnUQtvowNyM

@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: af8c7d9c-d193-4a04-845a-86c608c12217


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@AlaskanTuna
AlaskanTuna merged commit 62dfdbc into main Aug 25, 2026
3 checks passed
@AlaskanTuna
AlaskanTuna deleted the feat/localize-formatter-tooltips branch August 25, 2026 10:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Localize auth emails and formatter tooltip copy to BM and Chinese

1 participant