"use client"; import { useQuery } from "@tanstack/react-query"; import { useRouter } from "next/navigation"; import { useEffect } from "react"; import { API_BASE, ApiError, NotConnected, api, type Session } from "./api"; import { NotConnectedPanel } from "@/components/NotConnected"; export function useSession() { const { data, error, isLoading } = useQuery({ queryKey: ["me"], queryFn: api.me, staleTime: 60_000, }); return { session: data, error, isLoading }; } /* * The route-group guard. This is UX, not security: admin enforces the same * boundary with RequireStaff/RequireCustomer and returns 404 rather than 403 * for another account's data. A customer hitting a staff route is redirected * rather than shown a refusal, because there is nothing to tell them about. */ export function RequireKind({ kind, children, }: { kind: Session["kind"]; children: React.ReactNode; }) { const router = useRouter(); const { session, error, isLoading } = useSession(); useEffect(() => { if (error instanceof ApiError && error.status === 401) { router.replace("/login"); return; } if (session && session.kind !== kind) { router.replace(session.kind === "staff" ? "/staff" : "/"); } }, [error, session, kind, router]); if (error instanceof NotConnected) return ; if (isLoading || !session || session.kind !== kind) return null; return <>{children}; }