"use client"; import { usePathname, useRouter } from "next/navigation"; import { useEffect, useState, type ReactNode } from "react"; import { requestJson } from "../lib/api-client"; import { authFetch } from "../lib/auth"; // Backup access stays available so a fresh installation can be restored before // connecting any apps. This is navigation only; the API enforces admin access. export default function SetupGate({ children }: { children: ReactNode }) { const pathname = usePathname(); const router = useRouter(); const bypass = pathname === "/setup" || pathname === "/admin/backups"; const [checked, setChecked] = useState(false); useEffect(() => { if (bypass) return; const controller = new AbortController(); void requestJson<{ setup_required: boolean }>( "/setup/status", { signal: controller.signal, cache: "no-store" }, authFetch, ) .then((status) => { if (controller.signal.aborted) return; if (status.setup_required) router.replace("/setup"); else setChecked(true); }) .catch(() => { // Never hide an existing installation during an API outage or rollout. if (!controller.signal.aborted) setChecked(true); }); return () => controller.abort(); }, [bypass, router]); if (bypass || checked) return children; return (
Checking installation...
); }