← All tests

Date arrows + password eye + a vue-i18n crash STAGING

Two small asks from Narong (2026-07-24) — plus a latent page-crashing bug found while verifying them. No migration, no backend change. Four repos.

  1. Order Management date arrows stepped 2 days"basically the date just moves by 2 days at a time." Fixed; the forward arrow was silently broken too.
  2. Show/hide password "eye" toggle"can we also include the Eye icon for our logins?" Added to the Commerce tenant login and the Cpanel admin login.
  3. 🔴 Found: the Commerce login page crashed to a blank screen under vue-i18n. Pre-existing, unrelated to either ask.

1. The date arrows — a timezone bug, invisible in UTC

shiftDate() parsed "2026-07-24T00:00:00" as local time, then formatted the result with .toISOString() — which is UTC. The +7 offset leaked into the output. It looks perfectly correct to anyone testing in UTC, which is how it shipped.

Back arrowForward arrow
Before (Cambodia, UTC+7)07-24 → 07-22 (2 days)07-24 → 07-24 (stuck)
After07-24 → 07-2307-24 → 07-25

Fixed with shiftBusinessDate() in lib/utils.ts — the arithmetic now happens entirely in UTC on both ends, so it is offset-independent. It replaced two duplicated copies of the old helper. The test reproduces the original 2-day jump in a UTC+ zone before asserting the fix, so it can't quietly pass in UTC the way the original slipped through.

Order Management date navigation on staging
Order Management on get-coffee.staging after clicking back — 2026-07-24 → 2026-07-23, exactly one day.

2. The eye toggle

Added to both password logins: type="button" so it can never submit the form, an aria-label/aria-pressed pair that flips with state, and a visible keyboard focus ring. New strings went into each app's en.json and the shared localization/locales/ source so the Khmer pass picks them up; km stays empty and falls back to English, per the existing convention.

commerce masked
Commerce login — masked (default).
commerce revealed
Commerce login — revealed.
admin masked
Cpanel admin — masked.
admin revealed
Cpanel admin — revealed.

3. 🔴 The Commerce login page was crashing to a blank screen

Building the eye toggle meant actually loading the Commerce login page — and it rendered completely blank.

vue-i18n treats a bare @ as linked-message syntax. The string auth.login.email_placeholder = "you@company.com" therefore threw SyntaxError: Invalid linked format and took down the entire page mount — not just the placeholder. This is the same class of bug already fixed once in the Cpanel bundle, but Commerce never got the fix, and here it sat on the main merchant login.

Production was never affected — the i18n wiring commit had not been promoted to main on either Commerce or the Outdoor CRM. The real risk was that the next promote of that i18n work would have carried a blank login screen to every merchant.

Swept every vue-i18n locale file and escaped all of it as {'@'}:

FileKeysWould have broken
nix-commerce/src/i18n/en.json2the login page + invoices
nix-outdoor-sales-frontend/src/i18n/en.json2Company Setup wizard, Edit Zone
localization/locales/{nix-commerce, outdoor-sales, cpanel-admin}/en.json6would re-introduce it on the next sync

nix-cafe was deliberately left alone — it runs next-intl (ICU), where @ is an ordinary character and this escape would render a literal {'@'} to users.

commerce login rendering on staging
The Commerce login on demo.staging — rendering again, with the @ showing correctly in the email placeholder (the escape does not leak into the UI).

Checks

SuiteResult
Local — date helper across two timezones + boundaries, eye toggle on both logins16/16
Staging — login renders, @ escapes, eye toggle, date arrows ±1 day, no 5xx9/9
Staging smoke (SSO, cross-tenant guard, Starter login, no-session redirect)5/5
tsc --noEmit (nix-cafe) + vite build (commerce, admin, outdoor)clean

Shipped

RepostagingChange
nix-cafe72f1f4e (Worker 99f8b585)date-arrow fix
nix-commerceb230336eye toggle + @ escape
nix-outdoor-sales-adminb70d0f1 (dev; no staging branch)eye toggle
nix-outdoor-sales-frontend5d10d3e@ escape

No migration. Parked for the scheduled prod promote. Note: the Commerce and Outdoor staging merges also carried their i18n wiring commits to staging for the first time — worth a look beyond these fixes.