// The demo auth gate. This is intentionally a COOKIE-ONLY stand-in so the // template boots with zero backend — `login` writes the cookie, the // dashboard layout loader reads it. Swap `isSignedIn` for a real check // (verify a signed session, call your api) when you wire auth for real. export const SESSION_COOKIE = 'demo_session' // Browser-safe cookie parse — NO `node:*` import, so it's safe in the page // module graph. It runs in BOTH places the gate needs it: // - SSR: the loader's `headers['cookie']` (raw Cookie request header) // - client nav: `document.cookie` (the loader's `headers` is undefined // on the client, so the gate falls back to this) export const readCookie = ( header: string | null | undefined, name: string, ): string | undefined => { if (!header) return undefined const match = new RegExp(`(?:^|;\\s*)${name}=([^;]*)`).exec(header) return match ? decodeURIComponent(match[1]!) : undefined } // `headers` is populated server-side (SSR); on the client it's undefined, so // fall back to document.cookie. Either way: is there a session cookie? export const isSignedIn = (headers: Record | undefined): boolean => { const cookieHeader = headers?.['cookie'] ?? (typeof document === 'undefined' ? '' : document.cookie) return readCookie(cookieHeader, SESSION_COOKIE) !== undefined }