Files
threadcount-community/app/m/(app)/issue/page.tsx
T
ThreadCount 822c0b7c0b ThreadCount Community edition
Uniform stock management for healthcare linen rooms: the coordinator app, the phone counter and the staff app, for your own server. Built from 8685140 on 2026-09-13. Licensed under the Functional Source License (FSL-1.1-ALv2).
2026-09-13 11:09:20 +10:00

46 lines
2.1 KiB
TypeScript

"use client";
/* Issue starts with the person: their sizes, allowance and approvals all hang off the record,
so choosing them first is what lets the app check an issue before the garments leave the shelf. */
import { useMemo, useState } from "react";
import { useSnap } from "@/lib/client";
import { ccOf, staffName } from "@/lib/compute";
import { INK, MBody, MEmpty, MRow, MRule, MSection, MTop, inputStyle } from "@/components/m";
export default function MIssuePick() {
const { s } = useSnap();
const [q, setQ] = useState("");
const list = useMemo(() => {
const needle = q.trim().toLowerCase();
const active = s.staff.filter((x) => !x.inactive);
if (!needle) {
// No query: whoever was served most recently, so the usual faces are one tap away.
const seen: Record<string, string> = {};
for (const i of s.issues) seen[i.staffId] = i.date > (seen[i.staffId] || "") ? i.date : seen[i.staffId];
return [...active].sort((a, b) => (seen[b.id] || "").localeCompare(seen[a.id] || "")).slice(0, 12);
}
return active.filter((x) => `${x.first} ${x.last} ${x.num} ${x.dept}`.toLowerCase().includes(needle)).slice(0, 40);
}, [s, q]);
return (
<>
<MTop title="Issue" back right={`${s.staff.filter((x) => !x.inactive).length} on the register`} />
<MRule />
<MBody>
<div style={{ padding: 16, borderBottom: "2px solid " + INK }}>
<input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Name or staff number" autoFocus
aria-label="Search the staff register" style={inputStyle} />
</div>
<MSection label={q.trim() ? "Matches" : "Recently served"} />
{list.length === 0
? <MEmpty title="Nobody matches that" sub="Try a surname or a staff number. New starters are added on the desktop." />
: list.map((st) => (
<MRow key={st.id} href={`/m/issue/${st.id}`} mark="accent"
title={staffName(st)}
sub={[st.num, st.dept || st.group, ccOf(s, st) && `CC ${ccOf(s, st)}`].filter(Boolean).join(" · ")} />
))}
</MBody>
</>
);
}