"use client"; import { create } from "zustand"; import { api, ApiClientError } from "@/lib/api"; import type { AdminIdentity, MaintenanceSetting, SettingsResponse, SystemResponse } from "./types"; export type GateStatus = "loading" | "authed" | "unauthed" | "forbidden" | "error"; interface AdminState { status: GateStatus; admin: AdminIdentity | null; error: string | null; maintenance: MaintenanceSetting | null; node: string | null; version: string | null; /** GET /api/admin/me → decides which screen the gate renders. */ check: () => Promise; signedIn: (admin: AdminIdentity) => void; /** Called by the query hook on any 401. */ signedOut: () => void; signOut: () => Promise; /** Top-bar status: maintenance pill + node/version. */ loadStatus: () => Promise; setMaintenance: (m: MaintenanceSetting) => void; } export const useAdmin = create((set, get) => ({ status: "loading", admin: null, error: null, maintenance: null, node: null, version: null, check: async () => { try { const r = await api<{ admin: AdminIdentity }>("/api/admin/me"); set({ status: "authed", admin: r.admin, error: null }); void get().loadStatus(); } catch (e) { if (e instanceof ApiClientError) { if (e.status === 401) set({ status: "unauthed", admin: null, error: null }); else if (e.status === 403) set({ status: "forbidden", admin: null, error: e.message }); else set({ status: "error", admin: null, error: e.message }); } else { set({ status: "error", admin: null, error: "Unexpected error." }); } } }, signedIn: (admin) => { set({ status: "authed", admin, error: null }); void get().loadStatus(); }, signedOut: () => set({ status: "unauthed", admin: null, maintenance: null }), signOut: async () => { await api("/api/admin/auth/logout", { method: "POST" }).catch(() => {}); get().signedOut(); }, loadStatus: async () => { const [settings, system] = await Promise.allSettled([api("/api/admin/settings"), api("/api/admin/system")]); const patch: Partial = {}; if (settings.status === "fulfilled") { const m = settings.value.settings["maintenance"] as MaintenanceSetting | undefined; patch.maintenance = m && typeof m.enabled === "boolean" ? m : { enabled: false, message: "" }; } if (system.status === "fulfilled") { const svc = system.value.services.find((s) => s.name === "spinza-api") ?? system.value.services[0]; if (svc) { patch.node = svc.node; patch.version = svc.version; } } set(patch); }, setMaintenance: (m) => set({ maintenance: m }), }));