Skip to content

feat(i18n): localized dates, numbers, and XLM formatting (Closes #71) - #81

Open
mzterwalexzyy wants to merge 1 commit into
Kalebtron1:mainfrom
mzterwalexzyy:feat/localized-dates-numbers-xlm
Open

feat(i18n): localized dates, numbers, and XLM formatting (Closes #71)#81
mzterwalexzyy wants to merge 1 commit into
Kalebtron1:mainfrom
mzterwalexzyy:feat/localized-dates-numbers-xlm

Conversation

@mzterwalexzyy

Copy link
Copy Markdown

Summary

Localizes dates, numbers, and XLM/USDC balances so they follow the conventions of the language the user has selected, instead of always rendering in a hardcoded es-MX locale with Number.toFixed(...).

Closes #71

The problem

Several views formatted values locale-independently:

  • Dates were hardcoded to toLocaleDateString("es-MX", ...), so they never changed when the user switched to English.
  • Amounts used Number.toFixed(...), which always uses a . decimal separator and no grouping, regardless of locale.

The result: switching language localized the copy but left dates and numbers looking native-only.

Approach

Added one small, dependency-free formatting module, src/lib/format.ts, built on the platform Intl APIs:

  • formatAmount(value, language, opts?) — locale-aware number formatting. Formats at render time only and never mutates the value, so amounts stay exact and accurate. A non-finite input (e.g. a not-yet-loaded balance) is returned unchanged rather than showing NaN.
  • formatDate(value, language, opts?) — locale-aware date/time formatting. Accepts a Date, ISO string, or epoch; an unparseable value is returned unchanged rather than showing Invalid Date.
  • useFormatters() — a hook that binds both to the active language, so a language switch reformats every value on screen. Components call formatAmount(value, opts?) / formatDate(value, opts?) without threading the locale through.

The app's language codes (es, en) are valid BCP-47 subtags, so they map straight to Intl. This is deliberately not es-MX: pinning a single region was the original bug. With the generic codes, both dates and numbers switch — Spanish shows 1.234,56 and 15 ene, English shows 1,234.56 and Jan 15. A resolveLocale guard falls back to the default language if an unexpected code appears, and the region can be pinned later in one place if the maintainers prefer.

The internal data model is untouched; only render-time presentation changed.

Impacted views

  • src/components/CreditSection.tsx — XLM credit limit, debt, and interest amounts.
  • src/components/ActivityList.tsx — activity row date and amount.
  • src/pages/Perfil.tsx — on-chain USDC balance, available credit (XLM), and reputation score.
  • src/pages/Historial.tsx — month-group header, transaction row date and amount, and the two USDC volume totals.

Before / after

Before (any language) After — Spanish After — English
Activity date 15 ene, 14:30 (always es-MX) 15 ene, 14:30 Jan 15, 2:30 PM
History month header enero 2026 (always es-MX) enero 2026 January 2026
Amount 1234.50 XLM (always .) 1.234,50 XLM 1,234.50 XLM
USDC volume 1234 USDC 1.234 USDC 1,234 USDC

Testing

  • Added src/lib/format.test.ts (vitest): locale switching, fraction-digit precision, non-finite passthrough, and date parsing from Date/string/epoch. 9 tests pass.
  • npx tsc --noEmit: clean.
  • npm run build: succeeds.
  • Manually compared the same screens across es and en via the in-app language toggle.

Dates were formatted with a hardcoded es-MX locale and amounts with
Number.toFixed(), so they never reflected the language the user picked.

Add a small, dependency-free formatting module (src/lib/format.ts) built
on the Intl APIs: formatAmount and formatDate format at render time only
(values stay exact), and a useFormatters() hook binds them to the active
language so a language switch reformats every value on screen. The app's
language codes map straight to Intl, so both dates and numbers now switch
(es "1.234,56" / "15 ene" vs en "1,234.56" / "Jan 15"); non-finite numbers
and unparseable dates pass through unchanged instead of showing NaN.

Impacted views: CreditSection, ActivityList, Perfil, Historial.
Adds src/lib/format.test.ts (vitest) covering locale switching, precision,
non-finite passthrough, and date parsing.

Closes Kalebtron1#71
@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

@mzterwalexzyy is attempting to deploy a commit to the alankcr1-6443's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jul 28, 2026

Copy link
Copy Markdown

@mzterwalexzyy Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

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.

Localized dates, numbers, and XLM formatting

1 participant