/* Banyan Pharmacy — UI primitives (Terrace Stone & Ink) */
const { useState, useEffect, useRef, useMemo, createContext, useContext } = React;
const D = window.DATA;
function cx(...a) { return a.filter(Boolean).join(" "); }
/* ---------- Inline icons (Lucide-style, 1.5px, never filled) ------------- */
const Icon = ({ size = 16, stroke = 1.5, children, style }) => (
);
const Icons = {
chevDown: (p) => ,
chevRight: (p) => ,
chevLeft: (p) => ,
close: (p) => ,
check: (p) => ,
arrowLeft: (p) => ,
plus: (p) => ,
mapPin: (p) => ,
cross: (p) => ,
store: (p) => ,
truck: (p) => ,
pkg: (p) => ,
alert: (p) => ,
trendUp: (p) => ,
trendDown: (p) => ,
clock: (p) => ,
flask: (p) => ,
user: (p) => ,
settings: (p) => ,
logout: (p) => ,
play: (p) => ,
message: (p) => ,
external: (p) => ,
expedite: (p) => ,
swap: (p) => ,
};
/* Terrace four-peak glyph — the only ornamental mark, currentColor-aware */
function Glyph({ size = 16, stroke = 1.6 }) {
return (
);
}
function TerraceLogo({ height = 30 }) {
const w = (height * 267) / 62;
return (
);
}
/* ---------- Avatar ---------- */
function Avatar({ initials, size = "md", clay, org }) {
return {initials || "?"};
}
/* ---------- Format badge ---------- */
function FormatBadge({ format, showLabel = true }) {
const f = D.FORMAT[format];
const gl = format === "hospital" ? : format === "flagship" ? : ;
return {gl}{showLabel && f.short};
}
/* ---------- Health pill ---------- */
function HealthPill({ status }) {
const h = D.HEALTH[status];
const tone = { healthy: "var(--green)", watch: "var(--amber)", atrisk: "var(--red)", critical: "var(--clay)" }[status];
const bg = { healthy: "var(--green-wash)", watch: "var(--amber-wash)", atrisk: "var(--red-wash)", critical: "var(--clay-wash)" }[status];
const fg = { healthy: "var(--green)", watch: "var(--amber)", atrisk: "var(--red)", critical: "var(--clay-deep)" }[status];
return {h.label};
}
/* ---------- Provenance "from Terrace" ---------- */
function Prov({ children = "from Terrace", muted }) {
return {children};
}
/* ---------- money (INR, Indian grouping) ---------- */
function inr(n) { return "₹" + Number(n).toLocaleString("en-IN", { maximumFractionDigits: 0 }); }
/* ---------- SKU label ---------- */
function skuName(key) { return D.SKU[key] ? D.SKU[key].name : key; }
/* ---------- date helpers ---------- */
const MO = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
const WD = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
const MOFULL = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
function parseDate(s) { return new Date(s + "T00:00:00"); }
function shortDate(s) { const d = parseDate(s); return `${MO[d.getMonth()]} ${d.getDate()}`; }
function longDate(s) { const d = parseDate(s); return `${WD[d.getDay()]}, ${MOFULL[d.getMonth()]} ${d.getDate()}`; }
/* ---------- Drawer ---------- */
function Drawer({ open, onClose, title, children, footer, width = 480 }) {
useEffect(() => {
function esc(e) { if (e.key === "Escape") onClose(); }
if (open) window.addEventListener("keydown", esc);
return () => window.removeEventListener("keydown", esc);
}, [open, onClose]);
return (
);
}
function useClickOutside(ref, onOut) {
useEffect(() => {
function h(e) { if (ref.current && !ref.current.contains(e.target)) onOut(); }
document.addEventListener("mousedown", h);
return () => document.removeEventListener("mousedown", h);
}, [onOut]);
}
function SectionHead({ title, count, action }) {
return (
{title}
{count != null && {count}}
{action}
);
}
Object.assign(window, {
cx, Icon, Icons, Glyph, TerraceLogo, Avatar, FormatBadge, HealthPill, Prov,
inr, skuName, parseDate, shortDate, longDate,
Drawer, useClickOutside, SectionHead,
});