/* 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 }) => ( {children} ); 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 ( TERRACE ); } /* ---------- 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, });