/* ============================================================= CoreIQ Office — Dashboard (LIVE · this pharmacy) Every figure here is a real aggregate pulled from Aurora via the Office API (/overview), scoped to the signed-in organisation (and the selected store). Nothing is fabricated: where a vertical has no data yet — e.g. no sales history, dispensing not migrated — the figure is honestly zero and labelled, rather than filled with a placeholder. ============================================================= */ const { useState: dashUseState, useEffect: dashUseEffect } = React; const dashMoney = (cents) => "$" + (Number(cents || 0) / 100).toLocaleString("en-AU", { minimumFractionDigits: 2, maximumFractionDigits: 2 }); const dashNum = (n) => Number(n || 0).toLocaleString("en-AU"); // date math on YYYY-MM-DD (UTC) const dMinusMonths = (d, n) => { const t = new Date(d + "T00:00:00Z"); t.setUTCMonth(t.getUTCMonth() - n); return t.toISOString().slice(0, 10); }; function Dashboard() { const { scope, stores, setScreen, setScope } = window.useOffice(); const [ov, setOv] = dashUseState(null); const [loading, setLoading] = dashUseState(true); const [err, setErr] = dashUseState(null); const [range, setRange] = dashUseState(null); // fetched takings for the window const [from, setFrom] = dashUseState(""); const [to, setTo] = dashUseState(""); const siteId = scope === "all" ? undefined : scope; dashUseEffect(() => { let alive = true; setLoading(true); setErr(null); window.OfficeAPI.getOverview(siteId) .then((o) => { if (alive) { setOv(o); setLoading(false); } }) .catch((e) => { if (alive) { setErr(String((e && e.message) || e)); setLoading(false); } }); return () => { alive = false; }; }, [scope]); // Sales for the chosen window — history + new sales as ONE timeline. First load // uses the API default (trailing 12 months of data) and seeds the date inputs. const loadRange = (f, t) => { const q = { ...(f ? { from: f } : {}), ...(t ? { to: t } : {}), ...(siteId ? { siteId } : {}) }; window.OfficeAPI.getSalesRange(Object.keys(q).length ? q : undefined) .then((r) => { setRange(r); setFrom(r.range.from || ""); setTo(r.range.to || ""); }) .catch(() => setRange(null)); }; dashUseEffect(() => { loadRange(); }, [scope]); const cur = stores.find((s) => s.id === scope); const scopeName = scope === "all" ? `All stores · ${stores.length}` : (cur?.name || "—"); const v = (fn) => (loading || !ov ? "…" : fn(ov)); const bounds = range?.bounds; const preset = (months) => { if (!bounds) return; const f = months == null ? bounds.from : dMinusMonths(bounds.to, months); setFrom(f); setTo(bounds.to); loadRange(f, bounds.to); }; const rv = (fn) => (range ? fn(range) : "…"); return (
{scopeName} · live from Aurora

Dashboard

{err && (
Couldn't load live data from the API: {err}
)} {/* Takings — pick a period; history + new sales are one continuous timeline */}

Takings

{from} → {to} · {rv((r) => dashNum(r.sales))} sales
setFrom(e.target.value)} style={{height:32, width:140}}/> setTo(e.target.value)} style={{height:32, width:140}}/>
dashMoney(r.takingsCents))} delta={{ dir: "up", text: rv((r) => dashNum(r.sales) + " sales") }}/> dashMoney(r.avgBasketCents))} delta={{ text: "per sale" }}/> dashMoney(o.stockValueCents))} delta={{ text: v((o) => dashNum(o.stockedSkus) + " SKUs in stock") }}/> dashNum(o.customers))} delta={{ text: "account + patient records" }}/>
{range && range.byMonth.length > 0 && (
36 ? 1 : 3, height:96}}> {(() => { const mx = Math.max(...range.byMonth.map((m) => m.takingsCents), 1); const showLbl = range.byMonth.length <= 14; return range.byMonth.map((m) => (
{showLbl && {m.month.slice(2)}}
)); })()}
{range.byMonth.length > 14 &&
{range.byMonth[0].month} → {range.byMonth[range.byMonth.length - 1].month}
}
)}
{/* Catalogue / customer counts */}
dashNum(o.products))} delta={{ text: v((o) => dashNum(o.activeProducts) + " active / sellable") }} spark={null}/> dashNum(o.customers))} delta={{ text: "patient + account records" }} spark={null}/> dashNum(o.stockedSkus))} delta={{ text: "lines with on-hand > 0" }} spark={null}/> dashNum(o.stores))} delta={{ text: stores.length === 1 ? "single site" : "in this organisation" }} spark={null}/>
{/* Stores — real, from /sites */}

Stores

Live from Aurora · click to scope the dashboard
{stores.length === 0 &&
No stores for this organisation.
} {stores.map((s) => (
setScope(s.id)}>
{s.code || "··"}
{s.name}
{s.id}
{scope === s.id && }
))}
{/* Data sources — what's loaded, at the data level */}

What's loaded

{[ { ok: true, label: "Product catalogue", meta: v((o) => dashNum(o.products) + " products, live in Aurora") }, { ok: true, label: "Customers & accounts", meta: v((o) => dashNum(o.customers) + " patient / account records") }, { ok: true, label: "Stock on hand", meta: v((o) => dashNum(o.stockedSkus) + " stocked SKUs · " + dashMoney(o.stockValueCents) + " at cost") }, { ok: true, label: "Sales history", meta: bounds ? "continuous trading history from " + bounds.from : "trading history on file" }, { ok: true, label: "Purchasing & accounts", meta: "supplier invoices + account statements on file" }, { ok: false, label: "New POS sales", meta: "appear here as the POS rings them" }, { ok: false, label: "Scripts / dispensing", meta: "handled by the dispensing system" }, ].map((r, i) => (
{r.label}
{r.meta}
{r.ok ? "LIVE" : "NONE"}
))}
); } function KpiCard({ label, value, delta, spark }) { return (
{label}
{value}
{delta &&
{delta.text}
} {spark && (
{spark.map((v, i) => ( ))}
)}
); } window.OFFICE_SCREENS = Object.assign(window.OFFICE_SCREENS || {}, { dashboard: Dashboard }); window.KpiCard = KpiCard;