From c2e0ab1b1fa3aea572ec46e8d4fb24cf7083adf7 Mon Sep 17 00:00:00 2001 From: Lucas Berger Date: Sat, 6 Jun 2026 21:38:38 -0400 Subject: [PATCH] feat(260606-tv8-01): wire login redirect into CalendarShell meQuery handling - Import maybeRedirectToLogin + clearLoginRedirect from loginRedirect.ts - useEffect on meQuery.isError calls maybeRedirectToLogin() (one-shot, loop-guarded) - useEffect on meQuery.isSuccess calls clearLoginRedirect() for future re-auth - Existing 'Sign-in required' branch retained as fall-through for already-attempted case --- apps/pwa/src/components/CalendarShell.tsx | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/apps/pwa/src/components/CalendarShell.tsx b/apps/pwa/src/components/CalendarShell.tsx index 009f324..3f4ef37 100644 --- a/apps/pwa/src/components/CalendarShell.tsx +++ b/apps/pwa/src/components/CalendarShell.tsx @@ -43,6 +43,7 @@ import { Plus } from 'lucide-react' import { fetchMe, fetchEvents } from '../api/client.js' import { hydrateEvents } from '../lib/hydrateEvents.js' +import { maybeRedirectToLogin, clearLoginRedirect } from '../lib/loginRedirect.js' import { buildCalendarConfig, SX_FIRST_DAY_OF_WEEK } from '../lib/calendarConfig.js' import { useCalendarStore } from '../store/calendarStore.js' import { EventDetailPopover } from './EventDetailPopover.js' @@ -174,6 +175,26 @@ export function CalendarShell() { eventsService.set(sxEvents as Parameters[0]) }, [eventsQuery.data, eventsService]) + // Auth redirect — one-shot full-page nav to /api/login when /api/me fails. + // If this is the first failure, maybeRedirectToLogin() sets a sessionStorage + // flag and navigates the browser to /api/login (top-level nav, no CORS block). + // The page will unmount as the browser navigates. If the flag is already set + // (already bounced through login once and still failing), returns false and the + // existing "Sign-in required" branch below renders. + useEffect(() => { + if (meQuery.isError) { + maybeRedirectToLogin() + } + }, [meQuery.isError]) + + // Clear the one-shot flag on a successful /api/me load so a later session + // expiry can trigger another redirect instead of showing "Sign-in required". + useEffect(() => { + if (meQuery.isSuccess) { + clearLoginRedirect() + } + }, [meQuery.isSuccess]) + // ── Render helpers ──────────────────────────────────────────────────────── // Determine which content to show in the calendar area