"use client"; import { useMemo, useRef, useState } from "react"; import { Field } from "@/components/ui"; import { Tag } from "@/components/portal"; import type { StaffRec } from "@/lib/compute"; import { fullName, type Act } from "./shared"; /* The person's manager: approves their requests in the staff app and signs their paper form. One box, * found by search and saved on the pick. Anyone may be their own manager, marked Self-approved. */ export default function ManagerBox({ people, subject, isAdmin, act }: { people: StaffRec[]; subject: StaffRec; isAdmin: boolean; act: Act }) { const [q, setQ] = useState(""); const [changing, setChanging] = useState(false); const [busy, setBusy] = useState(false); const results = useRef<(HTMLButtonElement | null)[]>([]); const needle = q.trim().toLowerCase(); const mgr = subject.managerId ? people.find((x) => x.id === subject.managerId) : undefined; const matches = useMemo(() => { if (!needle) return []; return people.filter((x) => !x.inactive && (`${x.first} ${x.last}`.toLowerCase().includes(needle) || x.num.toLowerCase().includes(needle))).slice(0, 8); }, [people, needle]); function onListKey(e: React.KeyboardEvent) { const fwd = e.key === "ArrowDown", back = e.key === "ArrowUp"; if ((!fwd && !back) || matches.length === 0) return; e.preventDefault(); const at = results.current.findIndex((el) => el === document.activeElement); const next = at < 0 ? 0 : at + (fwd ? 1 : -1); results.current[Math.max(0, Math.min(matches.length - 1, next))]?.focus(); } async function save(managerId: string) { setBusy(true); const ok = await act("staff.patch", { id: subject.id, managerId }); setBusy(false); if (ok) { setQ(""); setChanging(false); } } if (mgr && !changing) { const self = mgr.id === subject.id; const name = fullName(mgr); return (
{name}{self ? " (themselves)" : ""} {mgr.num && {mgr.num}} {self && Self-approved} {mgr.inactive && Inactive} {isAdmin && ( )}
); } if (!isAdmin) return
None set.
; return (
{(c) => ( setQ(e.target.value)} onKeyDown={(e) => { if (e.key === "ArrowDown" && matches.length) { e.preventDefault(); results.current[0]?.focus(); } else if (e.key === "Escape" && changing) { e.preventDefault(); setQ(""); setChanging(false); } }} /> )} {changing && } {needle !== "" && (
{matches.map((x, i) => { const self = x.id === subject.id; return ( ); })} {matches.length === 0 &&
Nobody on the register matches that.
}
)}
); }