All files / src/features/onboarding dismissal.ts

84.61% Statements 11/13
75% Branches 3/4
100% Functions 4/4
90.9% Lines 10/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39          5x     5x         7x   9x         5x 4x 4x               3x 3x 3x            
// The walkthrough's "seen it" flag lives in a cookie (no DB, no server state).
// A cookie (not localStorage) so the collections *server component* can read it
// and redirect to /welcome BEFORE rendering — no SSR-paint flash. Centralized
// here so nothing else touches raw document.cookie; reads are SSR-safe (no
// document on the server) and tolerate cookie access throwing.
export const DISMISS_KEY = "adored-welcome-dismissed";
 
// One year — the "you've seen the intro" signal should outlast a browser session.
const MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
 
// Pure predicate over a raw Cookie header / document.cookie string, so both the
// client (document.cookie) and the server (next/headers) paths share one parse.
export function isDismissedInCookieString(cookieString: string): boolean {
  return cookieString
    .split(";")
    .some((pair) => pair.trim().startsWith(`${DISMISS_KEY}=1`));
}
 
// Client read. SSR-safe: no document on the server -> not dismissed.
export function isWelcomeDismissed(): boolean {
  if (typeof document === "undefined") return false;
  try {
    return isDismissedInCookieString(document.cookie);
  } catch {
    return false;
  }
}
 
// Client write. SSR-safe and non-fatal if cookies are unavailable.
export function dismissWelcome(): void {
  Iif (typeof document === "undefined") return;
  try {
    document.cookie = `${DISMISS_KEY}=1; path=/; max-age=${MAX_AGE_SECONDS}; SameSite=Lax`;
  } catch {
    // Cookies unavailable — the auto-trigger simply stays armed. Non-fatal;
    // re-open and manual visits still work.
  }
}