"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 (