"use client"; import Link from "next/link"; import { useParams, useSearchParams } from "next/navigation"; import { useCallback, useState } from "react"; import { useSnap } from "@/lib/client"; import { PageHead, Empty, ErrorLine } from "@/components/ui"; import { Icon, Tabs } from "@/components/portal"; import { StaffDialog } from "@/components/dialogs"; import { requestCounts, useRequests } from "@/components/requests/RequestList"; import type { StaffRec } from "@/lib/compute"; import { PeopleStyles, fullName } from "./shared"; import Summary from "./Summary"; import UniformTab from "./UniformTab"; import RequestsTab from "./RequestsTab"; import HistoryTab from "./HistoryTab"; import DetailsTab from "./DetailsTab"; const TAB_IDS = ["uniform", "requests", "history", "details"] as const; type TabId = (typeof TAB_IDS)[number]; const asTab = (v: string | null): TabId => ((TAB_IDS as readonly string[]).includes(v || "") ? (v as TabId) : "uniform"); /** Head actions shared by the register and the record (ADMIN only). */ function HeadActions({ onAdd }: { onAdd: () => void }) { const { isAdmin } = useSnap(); if (!isAdmin) return null; return ( <> Import the register ); } function Crumb({ name }: { name: string }) { return ( ); } export default function StaffRecord() { const { id } = useParams<{ id: string }>(); const { s } = useSnap(); const [add, setAdd] = useState(false); const st = s.staff.find((x) => x.id === id); if (!st) { return (
setAdd(true)} /> Nobody on the register has this record. Back to People {add && setAdd(false)} />}
); } /* Keyed on the person, so walking from one record to another (through "Whose requests they approve") starts every draft, dialog and one-time code afresh instead of carrying it over. */ return ; } function RecordBody({ st }: { st: StaffRec }) { const { isAdmin, mutate } = useSnap(); const sp = useSearchParams(); const tab = asTab(sp.get("tab")); const edit = isAdmin && tab === "details" && sp.get("edit") === "1"; const [add, setAdd] = useState(false); const [err, setErr] = useState(""); const act = useCallback(async (op: string, payload: unknown) => { setErr(""); const r = await mutate(op, payload); if (!r.ok) setErr(r.error); return r.ok; }, [mutate]); /* One fetch of this person's requests feeds the tab count, the Requests tab and the order-form history. */ const req = useRequests({ staffId: st.id }); const counts = req.data ? requestCounts(req.data, { staffId: st.id }) : null; const base = `/app/staff/${st.id}`; const hrefFor = (t: string) => (t === "uniform" ? base : `${base}?tab=${t}`); const tabs = [ { id: "uniform", label: "Uniform" }, { id: "requests", label: "Requests", count: counts ? counts.open : undefined }, { id: "history", label: "History" }, { id: "details", label: "Details & access" }, ]; const label = tabs.find((t) => t.id === tab)!.label; return (
setAdd(true)} />
{tab === "uniform" && } {tab === "requests" && } {tab === "history" && } {tab === "details" && }
{add && setAdd(false)} />}
); }