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).
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
"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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user