From 57424e6770bcdd13a77cb281ae77a65413c39168 Mon Sep 17 00:00:00 2001 From: Lucas Berger Date: Sun, 14 Jun 2026 22:35:19 -0400 Subject: [PATCH] feat(18-04): add fetchAdminTimezone + setAdminTimezone to PWA API client - Export AdminTimezoneResponse interface (timezone: string, isExplicitlySet: boolean) - fetchAdminTimezone(): GET /api/admin/config/timezone with credentials/redirect pattern - setAdminTimezone(timezone): PUT /api/admin/config/timezone with JSON body - Both wrappers call handleAuthResponse (same auth handling as sibling admin calls) --- apps/pwa/src/api/client.ts | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/apps/pwa/src/api/client.ts b/apps/pwa/src/api/client.ts index 707a5e7..87c1fbe 100644 --- a/apps/pwa/src/api/client.ts +++ b/apps/pwa/src/api/client.ts @@ -468,6 +468,48 @@ export async function setSharedCalendar(calendarId: number): Promise { handleAuthResponse(res, `PUT /api/admin/calendars/${calendarId}/shared`); } +/** + * Response shape for GET /api/admin/config/timezone. + * isExplicitlySet is false when the household timezone has not been saved yet + * (the server returns the process.env.TZ / Intl fallback in that case — D-06). + */ +export interface AdminTimezoneResponse { + timezone: string; + isExplicitlySet: boolean; +} + +/** + * Fetch the current household timezone setting. + * Admin-only: the server enforces requireAdmin (403 for non-admins). + */ +export async function fetchAdminTimezone(): Promise { + const res = await fetch('/api/admin/config/timezone', { + credentials: 'include', + redirect: 'manual', + }); + + handleAuthResponse(res, 'GET /api/admin/config/timezone'); + + return res.json() as Promise; +} + +/** + * Set the household timezone. + * Admin-only: the server enforces requireAdmin and IANA validation (Plan 02). + * @param timezone A valid IANA timezone identifier (e.g. 'America/Chicago'). + */ +export async function setAdminTimezone(timezone: string): Promise { + const res = await fetch('/api/admin/config/timezone', { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + credentials: 'include', + redirect: 'manual', + body: JSON.stringify({ timezone }), + }); + + handleAuthResponse(res, 'PUT /api/admin/config/timezone'); +} + /** * Self-service: save (add) the current member's own credential. * Member-scoped: NO userId in payload — server resolves from session (Pitfall 6 / T-10-12).