From 6f1aa37a266da25a4255661b70354d5dc8532d35 Mon Sep 17 00:00:00 2001 From: Nora Date: Mon, 6 Jul 2026 10:05:55 -0600 Subject: [PATCH] fix(time-tracking): inherit lang from water-log and stop PIN flash Two UX bugs in the worker Time Tracking mobile flow: 1) Spanish parity between Water Log and Time Tracking. The Water Log mobile app (/water) uses the wl_lang cookie for its language; the Time Tracking field client used its own time_tracking_lang cookie. A worker who set Spanish on /water then tapped the Time tab saw English. getLangCookie() now falls back to wl_lang when time_tracking_lang is unset, so the Time tab inherits the worker's Water Log preference. Standalone /tuxedo/time-clock is unaffected (no wl_lang cookie there). 2) PIN screen flash on tab change. initialState started at screen 'pin', so the init effect that resolves the session cookie + open clock-in caused a one-tick flash of the PIN screen even when the worker was already authenticated. initialState now starts at 'loading' (a spinner) and the init effect dispatches the correct screen (hub / working / pin) once the session check resolves. Public contract unchanged: exported types, function signatures, and the cookie name on writes are all preserved. The change is additive on read (extra cookie fallback) and a one-key swap on initial state. Verified locally: tsc clean, lint unchanged (354 problems = baseline), vitest 226 pass / 29 fail (same pre-existing auth failures, none related to this change). --- .../time-tracking/TimeTrackingFieldClient.tsx | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/components/time-tracking/TimeTrackingFieldClient.tsx b/src/components/time-tracking/TimeTrackingFieldClient.tsx index 4cae2cc..8cab82f 100644 --- a/src/components/time-tracking/TimeTrackingFieldClient.tsx +++ b/src/components/time-tracking/TimeTrackingFieldClient.tsx @@ -392,8 +392,15 @@ const TRANS_ES: Translations = { function getLangCookie(): string { if (typeof document === "undefined") return "en"; - const match = document.cookie.match(/time_tracking_lang=(\w+)/); - return match ? match[1] : "en"; + // `time_tracking_lang` is the explicit override. Fall back to + // `wl_lang` so workers who switched to Spanish on the Water Log + // mobile app inherit the same language when they tap the Time tab + // — without this, the Time tab resets to English every time. + const tt = document.cookie.match(/time_tracking_lang=(\w+)/); + if (tt) return tt[1]; + const wl = document.cookie.match(/wl_lang=(\w+)/); + if (wl) return wl[1]; + return "en"; } function setLangCookie(lang: string) { @@ -410,8 +417,8 @@ function langToBcp(): "en-US" | "es-ES" { // Cheap global so `formatTime` doesn't have to thread `lang` around. // Resolved at call time from the lang cookie that's always set. if (typeof document === "undefined") return "en-US"; - const m = document.cookie.match(/time_tracking_lang=(\w+)/); - return m?.[1] === "es" ? "es-ES" : "en-US"; + const m = getLangCookie(); + return m === "es" ? "es-ES" : "en-US"; } function formatHours(minutes: number): string { @@ -538,7 +545,12 @@ function emptyManualDraft(): State["manualEntryDraft"] { const initialState: State = { lang: (getLangCookie() as "en" | "es") ?? "en", - screen: "pin", + // Start in `"loading"` so the init effect can resolve the session + // cookie + open clock-in before the UI renders. Previously this + // was `"pin"`, which caused a ~one-tick flash of the PIN screen on + // every tab switch — workers with a valid session saw the PIN UI + // for a moment before it was swapped out for Hub/Working. + screen: "loading", tasks: [], openEntry: null, payPeriod: null,