"use client"; /* One field over people and stock together — at the counter you don't know in advance which one you're after. People take an accent marker, stock lines an ink one. */ import { useMemo, useState } from "react"; import { useDerived, useSnap } from "@/lib/client"; import { bcBound, ccOf, label, locMap, locTrail, onhand, touched, reorderAt, staffName, variantName } from "@/lib/compute"; import MScan from "@/components/MScan"; import { INK, IconScan, MBody, MEmpty, MNav, MRow, MRule, MSection, MTop, inputStyle } from "@/components/m"; export default function MSearch() { const { s } = useSnap(); const { L, byId, variants } = useDerived(); const [q, setQ] = useState(""); const [scan, setScan] = useState(false); const locs = useMemo(() => locMap(s), [s]); const { people, lines } = useMemo(() => { const needle = q.trim().toLowerCase(); const stockRows = variants.filter((v) => touched(s, L, v.key)).map((v) => ({ // Only the bound supplier code: it is what someone reads off a label and types in here. ...v, oh: onhand(s, L, v.key), par: reorderAt(s, v.key), code: bcBound(s, v.item, v.si), where: locTrail(locs, s.placed[v.key], 0), name: `${variantName(byId[v.itemId], v.size)}`, })); if (!needle) { const seen: Record = {}; for (const i of s.issues) seen[i.staffId] = i.date > (seen[i.staffId] || "") ? i.date : seen[i.staffId]; return { people: s.staff.filter((x) => !x.inactive).sort((a, b) => (seen[b.id] || "").localeCompare(seen[a.id] || "")).slice(0, 5), lines: stockRows.filter((r) => r.oh <= r.par).slice(0, 5), }; } return { people: s.staff.filter((x) => !x.inactive && `${x.first} ${x.last} ${x.num} ${x.dept}`.toLowerCase().includes(needle)).slice(0, 12), lines: stockRows.filter((r) => `${r.name} ${r.code} ${r.where}`.toLowerCase().includes(needle)).slice(0, 20), }; }, [s, L, variants, byId, q, locs]); const empty = q.trim() && people.length === 0 && lines.length === 0; return ( <>
setQ(e.target.value)} placeholder="Name, staff number, garment or code" autoFocus aria-label="Search people and stock" style={{ ...inputStyle, flex: 1 }} />
{empty ? ( ) : ( <> {people.length > 0 && ( <> {people.map((st) => ( ))} )} {lines.length > 0 && ( <> {lines.map((r) => ( {r.oh}/{r.par}} /> ))} )} )}
{scan && { const k = s.barcodes[raw.trim()]; const v = k ? variants.find((x) => x.key === k) : undefined; setQ(v ? `${variantName(byId[v.itemId], v.size)}` : raw.trim()); setScan(false); }} onClose={() => setScan(false)} />} ); }