feat(water-log): add 'holes' unit + EN/ES language toggle for mobile
Deploy to route.crispygoat.com / deploy (push) Successful in 4m2s
Deploy to route.crispygoat.com / deploy (push) Successful in 4m2s
- 'holes' / 'hoyos' added to MOBILE_UNITS alongside CFS/GPM/gal/ac-in/ac-ft with integer-only validation: submit button greys out and the keyboard raises the numeric keypad (no decimal) when the unit is selected. - Language toggle in the headgate list header (next to logout) flips every screen between English and Spanish. Choice is persisted to the existing 'wl_lang' cookie for 1y, so the user's last selection sticks across logout/relogin. - i18n strings lifted into shared src/lib/water-log/i18n.ts (single source of truth, en/es parity enforced by tests). All mobile screens (Pin, HeadgateList, LogForm, Success) plus the loadHeadgates error in the orchestrator consume the dictionary. Brand strip, aria-labels, segmented control labels, success recap, and submit-button labels all go through getT()/formatUnit()/displayUnit(). - 26 new unit tests (tests/unit/water-log-i18n.test.ts) cover: en/es dict parity, holes catalog + hoyos translation, all the detectInitialLang() branches (SSR/cookie/navigator), setLangCookie read/write, label interpolation helpers, and the unit catalog. Refs /tmp/refactor-water-log.md (Commit B plan)
This commit is contained in:
@@ -45,6 +45,14 @@ export type Labels = {
|
||||
save: string;
|
||||
saving: string;
|
||||
back: string;
|
||||
signOut: string;
|
||||
a11yBackToHeadgates: string;
|
||||
a11yChangeHeadgate: string;
|
||||
a11ySignOut: string;
|
||||
};
|
||||
/** The brand strip shown on the PIN and Success screens. */
|
||||
brand: {
|
||||
waterLog: string;
|
||||
};
|
||||
/** `/water` PIN entry screen. */
|
||||
pin: {
|
||||
@@ -54,6 +62,8 @@ export type Labels = {
|
||||
unlock: string;
|
||||
forgot: string;
|
||||
genericError: string;
|
||||
a11yPin: string;
|
||||
a11yPinEntry: string;
|
||||
};
|
||||
/** `/water` headgate list screen. */
|
||||
headgates: {
|
||||
@@ -65,14 +75,19 @@ export type Labels = {
|
||||
pullToRefresh: string;
|
||||
thresholdHigh: string;
|
||||
thresholdLow: string;
|
||||
refresh: string;
|
||||
refreshing: string;
|
||||
loadError: string;
|
||||
};
|
||||
/** `/water` measurement entry screen. */
|
||||
log: {
|
||||
title: string;
|
||||
measurement: string;
|
||||
unit: string;
|
||||
timestamp: string;
|
||||
loggedNow: string;
|
||||
notes: string;
|
||||
notesOptional: string;
|
||||
notesPlaceholder: string;
|
||||
notesVisibility: string;
|
||||
measurementError: string;
|
||||
@@ -124,6 +139,13 @@ export const LABELS: Record<Lang, Labels> = {
|
||||
save: "Save",
|
||||
saving: "Saving…",
|
||||
back: "Back",
|
||||
signOut: "Sign out",
|
||||
a11yBackToHeadgates: "Back to headgates",
|
||||
a11yChangeHeadgate: "Change headgate",
|
||||
a11ySignOut: "Sign out",
|
||||
},
|
||||
brand: {
|
||||
waterLog: "TUXEDO WATER LOG",
|
||||
},
|
||||
pin: {
|
||||
title: "Enter your PIN",
|
||||
@@ -132,6 +154,8 @@ export const LABELS: Record<Lang, Labels> = {
|
||||
unlock: "Unlock",
|
||||
forgot: "Forgot your PIN? Ask the ditch supervisor.",
|
||||
genericError: "Something went wrong. Try again.",
|
||||
a11yPin: "PIN",
|
||||
a11yPinEntry: "PIN entry — tap to focus",
|
||||
},
|
||||
headgates: {
|
||||
title: "Headgates",
|
||||
@@ -143,13 +167,18 @@ export const LABELS: Record<Lang, Labels> = {
|
||||
pullToRefresh: "Pull down to refresh the list",
|
||||
thresholdHigh: "Hi",
|
||||
thresholdLow: "Lo",
|
||||
refresh: "Refresh",
|
||||
refreshing: "Checking…",
|
||||
loadError: "Couldn't load headgates. Pull down to try again.",
|
||||
},
|
||||
log: {
|
||||
title: "Log Reading",
|
||||
measurement: "Measurement",
|
||||
unit: "Unit",
|
||||
timestamp: "Timestamp",
|
||||
loggedNow: "Logged now",
|
||||
notes: "Notes",
|
||||
notesOptional: "optional",
|
||||
notesPlaceholder:
|
||||
"Anything the supervisor should know about this reading?",
|
||||
notesVisibility: "Visible to admins only",
|
||||
@@ -197,6 +226,13 @@ export const LABELS: Record<Lang, Labels> = {
|
||||
save: "Guardar",
|
||||
saving: "Guardando…",
|
||||
back: "Atrás",
|
||||
signOut: "Salir",
|
||||
a11yBackToHeadgates: "Volver a compuertas",
|
||||
a11yChangeHeadgate: "Cambiar compuerta",
|
||||
a11ySignOut: "Cerrar sesión",
|
||||
},
|
||||
brand: {
|
||||
waterLog: "REGISTRO DE AGUA TUXEDO",
|
||||
},
|
||||
pin: {
|
||||
title: "Ingresa tu PIN",
|
||||
@@ -205,6 +241,8 @@ export const LABELS: Record<Lang, Labels> = {
|
||||
unlock: "Desbloquear",
|
||||
forgot: "¿Olvidaste tu PIN? Pregúntale al supervisor.",
|
||||
genericError: "Algo salió mal. Inténtalo de nuevo.",
|
||||
a11yPin: "PIN",
|
||||
a11yPinEntry: "Entrada de PIN — toca para enfocar",
|
||||
},
|
||||
headgates: {
|
||||
title: "Compuertas",
|
||||
@@ -216,13 +254,18 @@ export const LABELS: Record<Lang, Labels> = {
|
||||
pullToRefresh: "Jala hacia abajo para actualizar la lista",
|
||||
thresholdHigh: "Alto",
|
||||
thresholdLow: "Bajo",
|
||||
refresh: "Actualizar",
|
||||
refreshing: "Verificando…",
|
||||
loadError: "No se pudieron cargar las compuertas. Jala para intentar de nuevo.",
|
||||
},
|
||||
log: {
|
||||
title: "Registrar lectura",
|
||||
measurement: "Medición",
|
||||
unit: "Unidad",
|
||||
timestamp: "Hora",
|
||||
loggedNow: "Registrando ahora",
|
||||
notes: "Notas",
|
||||
notesOptional: "opcional",
|
||||
notesPlaceholder:
|
||||
"¿Algo que el supervisor deba saber sobre esta lectura?",
|
||||
notesVisibility: "Visible solo para administradores",
|
||||
|
||||
Reference in New Issue
Block a user