"use client"; import { createContext, useContext, useEffect, useState, ReactNode } from "react"; import { auth, type Org, type Role, type SessionUser } from "@/lib/api"; export type { Org, Role, SessionUser }; interface AuthContextType { user: SessionUser | null; org: Org | null; /** True for owner and admin — the roles the /api/settings and /api/org routes require. */ isAdmin: boolean; } const AuthContext = createContext({ user: null, org: null, isAdmin: false }); export function useAuth() { return useContext(AuthContext); } /** * Wraps the authenticated app shell only (see app/(app)/layout.tsx). /login and * /setup live outside the group, so no pathname guard is needed here. */ export function AuthProvider({ children }: { children: ReactNode }) { const [user, setUser] = useState(null); const [org, setOrg] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { let cancelled = false; (async () => { try { const status = await auth.bootstrapStatus(); if (status.needs_setup) { window.location.href = "/setup"; return; } const me = await auth.me(); if (cancelled) return; setUser(me.user); setOrg(me.org); setLoading(false); } catch (err) { if (cancelled) return; const status = (err as { status?: number }).status; if (status === 401) { window.location.href = "/login"; return; } setError((err as Error).message || "Unable to load your session."); setLoading(false); } })(); return () => { cancelled = true; }; }, []); if (loading) { return (
); } if (error || !user) { return (

Can't load your session

{error ?? "Unable to load your session."}

Sign in
); } const isAdmin = user.role === "owner" || user.role === "admin"; return ( {children} ); }