/* ============================================================= CoreIQ Office — National catalogue (Ironbark reference) Live search over the shared Ironbark reference catalogue served by the Office API (/reference/*). This screen reads REAL data — no sample data. It is the source-of-truth product browser a pharmacy uses before adding a line to its own catalogue. ============================================================= */ const { useState: catUseState, useEffect: catUseEffect, useRef: catUseRef } = React; function NationalCatalogue() { const [q, setQ] = catUseState(""); const [rows, setRows] = catUseState([]); const [stats, setStats] = catUseState(null); const [loading, setLoading] = catUseState(true); const [err, setErr] = catUseState(null); const reqSeq = catUseRef(0); const [sort, setSort] = catUseState({ col: "description", dir: "asc" }); // How much reference data is loaded — proves the catalogue is fully populated. catUseEffect(() => { window.OfficeAPI.referenceStats() .then(setStats) .catch((e) => setErr(String(e.message || e))); }, []); // Debounced live search (empty query = alphabetical browse). catUseEffect(() => { const seq = ++reqSeq.current; setLoading(true); const t = setTimeout(() => { window.OfficeAPI.referenceSearch(q.trim(), 60, 0, sort.col, sort.dir) .then((ps) => { if (seq !== reqSeq.current) return; // a newer query won setRows(ps); setErr(null); setLoading(false); }) .catch((e) => { if (seq !== reqSeq.current) return; setErr(String(e.message || e)); setLoading(false); }); }, 220); return () => clearTimeout(t); }, [q, sort.col, sort.dir]); const price = (cents) => cents == null ? "—" : window.officeMoney(cents / 100); const COLS = [ { k: "description", label: "Product", num: false }, { k: "barcode", label: "Barcode", num: false }, { k: "schedule", label: "Sched", num: false }, { k: "generic", label: "Generic / active", num: false }, { k: "pack", label: "Pack", num: false }, { k: "price", label: "Trade ex-GST", num: true }, { k: "provider", label: "Source", num: false }, ]; const toggleSort = (k) => setSort((s) => (s.col === k ? { col: k, dir: s.dir === "asc" ? "desc" : "asc" } : { col: k, dir: k === "price" ? "desc" : "asc" })); const arrow = (k) => (sort.col === k ? (sort.dir === "asc" ? " ↑" : " ↓") : ""); return (