"use client"; /* Kit check (a round asking everyone to confirm what they hold), its shortfalls, and the size * waitlist. Starting and closing a round is admin only on the server, so it is hidden here too. */ import { useState } from "react"; import Link from "next/link"; import { useSnap } from "@/lib/client"; import { Empty, Field } from "@/components/ui"; import { MonoNum, Panel, Tag } from "@/components/portal"; import { fmtDate, formatInZone } from "@/lib/compute"; import { WAITLIST_HOLD_HOURS, holdEndsAt, holdExpired } from "@/lib/staffreq"; import type { CycleRow, ShortfallRow, WaitingRow } from "./RequestList"; type Op = "kitcheck.open" | "kitcheck.close" | "waitlist.offer"; export default function KitCheck({ cycle, shortfalls, waiting, act }: { cycle: CycleRow | null; shortfalls: ShortfallRow[]; waiting: WaitingRow[]; act: (op: Op, payload: Record) => Promise; }) { const { s, isAdmin } = useSnap(); const [dueBy, setDueBy] = useState(""); return (
{cycle ? (
Due by {fmtDate(cycle.dueBy)} · {cycle.answers} answer{cycle.answers === 1 ? "" : "s"} in · opened by {cycle.openedBy || "—"} {isAdmin && }
) : isAdmin ? (
{(c) => setDueBy(e.target.value)} />}
) : ( No kit check running. )}
{!cycle ? (
No kit check is running.
) : shortfalls.length === 0 ? (
{cycle.answers === 0 ? "Nobody has answered yet." : "Every answer so far matched the record."}
) : (
{shortfalls.map((f) => ( ))}
WhoGarmentSize On recordConfirmedShort AnsweredRecord
{f.staffName} {f.staffNum}{f.ward && · {f.ward}} {f.item} {f.size} {f.onRecord} {f.confirmed} {formatInZone(f.at, s.tz)} Open record
)}
{waiting.length === 0 ? (
Nobody is waiting on a size.
) : waiting.map((w) => { const ends = holdEndsAt(w.offeredAt); return (
{w.item}{w.size} · {w.staffName}{w.ward ? ` (${w.ward})` : ""} · since {formatInZone(w.since, s.tz)} {!w.offeredAt ? : holdExpired(w.offeredAt) ? Hold lapsed — offer to the next person : Held until {ends ? formatInZone(ends, s.tz, { day: "numeric", month: "short", hour: "numeric", minute: "2-digit" }) : "—"}}
); })}
); }