"use client";
import { useState } from "react";
import { LiveRegion } from "@/components/ui";
import { Panel } from "@/components/portal";
import { useSnap } from "@/lib/client";
import { fmtDate, money } from "@/lib/compute";
import { HeadActions, PanelEmpty, TableWrap, TOTAL, plural } from "./bits";
import type { ReportData } from "./useReportData";
function SubHead({ children }: { children: React.ReactNode }) {
return
{children}
;
}
/* The yearly figure is a reporting number, not a limit, so it lives here and nowhere else. */
function YearlyFigure() {
const { s, isAdmin, busy, mutate } = useSnap();
const [editing, setEditing] = useState(false);
const [val, setVal] = useState("");
const [msg, setMsg] = useState<{ text: string; err: boolean } | null>(null);
const current = s.settings.defaultEntitlement;
async function save() {
const n = Number(val);
if (!Number.isInteger(n) || n < 0) { setMsg({ text: "Enter a whole number, 0 or more.", err: true }); return; }
const r = await mutate("settings.update", { defaultEntitlement: n });
if (!r.ok) { setMsg({ text: r.error, err: true }); return; }
setEditing(false);
setMsg({ text: "Saved.", err: false });
}
return (
{!editing ? (
<>
Yearly figure for reports · {current} garments per person
{isAdmin && }
>
) : (
)}
);
}
export default function PeopleTab({ d }: { d: ReportData }) {
const { R, mLbl, csv, print } = d;
return (
0}
aside={threshold {R.excThreshold} items/month>} onCsv={csv.exceptions} onPrint={print.exceptions} />}>
{R.excRows.length === 0 ? No exceptions in {mLbl}. : (
| Staff | Group | Cost centre | Items (month) | Items (FY) | Flag |
{R.excRows.map((r, i) => | {r.who} | {r.group} | {r.cc || "—"} | {r.mQty} | {r.fyQty} | {r.flags.map((f, j) => {f})} |
)}
)}
0}
aside={ 0 ? `${plural(R.apprTot, "set")} outstanding` : undefined} onCsv={csv.approvals} onPrint={print.approvals} />}>
{R.apprRows.length === 0 ? No uncollected approvals. : (
| Staff | Ward | Approved by | Date | Sets approved | Collected | Remaining |
{R.apprRows.map((r, i) => | {r.who} | {r.dept} | {r.by} | {fmtDate(r.date)} | {r.sets} | {r.used} | {r.rem} |
)}
| TOTAL OUTSTANDING | | | | | | {R.apprTot} |
)}
saved {money(R.plSaved)}>} onCsv={csv.preloved} onPrint={print.preloved} />}>
Issued free · {R.plQty}
{R.plIssueRows.length === 0 ? Nothing issued from the pool in {mLbl}. : (
| Date | Staff | Item | Size | Qty | Value saved |
{R.plIssueRows.map((r, i) => | {fmtDate(r.date)} | {r.who} | {r.item} | {r.size} | {r.qty} | {money(r.saved)} |
)}
)}
Hand-ins · {R.ragMonth} to rag
{R.hiRows.length === 0 ? No hand-ins in {mLbl}. : (
| Date | Staff | Received by | Good | Rag | Allowance |
{R.hiRows.map((r, i) => | {fmtDate(r.date)} | {r.who} | {r.by} | {r.good} | {r.rag} | {r.credit} |
)}
)}
Pool today · {R.plPoolTotal} at $0
{R.plPoolRows.length === 0 ? The pool is empty. : (
| Item | Sizes on hand | Total |
{R.plPoolRows.map((r, i) => | {r.item} | {r.sizes} | {r.total} |
)}
)}
);
}