Signal/signal-ui/src/components/Sidebar.jsx
Kisa a424ac9d13 feat: add reason strings per patient, fix export headers, add signal-ui source
- Add _build_reason() to backend — per-patient reason strings with specific
  day counts (e.g. "Supply lapsed 70 days ago. Prescriber contact required.")
- Add reason field to RecordOut model and backend /api/export CSV
- Fix export column headers: Coverage End Date → Resupply End Date,
  Days Until Coverage End → Days Until Resupply End
- Pass reason through apiRecordToLocal in frontend api.js
- Display reason as muted sub-line under status badge in WorklistTable
- Add reason column to client-side CSVExport
- Add signal-ui React source to repo (was untracked)
- CLAUDE.md: add Billing and CMS integrations to Phase 2 deferred table
- research: restore Section 14 stat verification (May 23 recovery)

Deployed to Railway production — health check confirmed live.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 09:45:02 -04:00

132 lines
No EOL
4.6 KiB
JavaScript

export default function Sidebar({
oocCount,
visitDueCount,
refillCount,
activeFilter,
onFilterChange,
onImportClick,
}) {
const navItems = [
{
label: "All Patients",
key: "all",
icon: "≡",
badge: null,
},
{
label: "Resupply Ready",
key: "REFILL_WINDOW",
icon: "⚠",
badge: refillCount,
badgeWarn: true,
},
{
label: "Renewal Due",
key: "VISIT_DUE",
icon: "⚡",
badge: visitDueCount,
},
{
label: "Supply Lapsed",
key: "OUT_OF_COVERAGE",
icon: "✕",
badge: oocCount,
},
];
return (
<aside className="w-[240px] bg-teal-900 border-r border-teal-700 flex flex-col shrink-0 fixed top-0 left-0 bottom-0 z-20">
{/* Header */}
<div className="px-5 pt-[22px] pb-[18px] border-b border-[rgba(15,94,94,0.5)]">
<div className="flex items-center gap-[10px] mb-1">
<div className="w-[33px] h-[33px] bg-gradient-to-br from-[#1A8A8A] to-[#147A7A] rounded-lg flex items-center justify-center font-heading font-bold text-[16px] text-warm-white shrink-0 shadow-[0_2px_8px_rgba(20,122,122,0.35)]">
S
</div>
<span className="font-heading font-bold text-[17px] text-warm-white tracking-[-0.01em]">
Signal
</span>
</div>
<div className="text-[11px] text-teal-300 ml-[43px] tracking-[0.01em]">
by STTIL Solutions
</div>
</div>
{/* Nav */}
<nav className="py-[10px] flex-1 overflow-y-auto">
<div className="text-[10px] font-medium tracking-[0.09em] uppercase text-[#426060] px-5 pt-[10px] pb-1">
Worklist
</div>
{navItems.map((item) => (
<a
key={item.key}
href="#"
onClick={(e) => {
e.preventDefault();
onFilterChange(item.key);
}}
className={`flex items-center gap-[10px] px-5 py-[9px] text-[13.5px] no-underline transition-all cursor-pointer border-l-[3px] ${
activeFilter === item.key
? "text-warm-white font-medium border-l-[var(--accent)] bg-[rgba(10,68,68,0.55)]"
: "text-[#7A9E9E] border-l-transparent hover:text-teal-400 hover:bg-[rgba(46,163,163,0.07)]"
}`}
>
<span className="w-[18px] text-center text-[14px] shrink-0">
{item.icon}
</span>
{item.label}
{item.badge != null && item.badge > 0 && (
<span
className={`ml-auto text-[10px] font-semibold px-[7px] py-[1px] rounded-[20px] font-mono ${
item.badgeWarn
? "bg-[rgba(217,123,53,0.22)] text-[#E49655]"
: "bg-[rgba(200,48,48,0.22)] text-[#FF8080]"
}`}
>
{item.badge}
</span>
)}
</a>
))}
<div className="text-[10px] font-medium tracking-[0.09em] uppercase text-[#426060] px-5 pt-4 pb-1">
System
</div>
<a
href="#"
onClick={(e) => {
e.preventDefault();
onImportClick();
}}
className="flex items-center gap-[10px] px-5 py-[9px] text-[13.5px] text-[#7A9E9E] no-underline transition-all cursor-pointer border-l-[3px] border-l-transparent hover:text-teal-400 hover:bg-[rgba(46,163,163,0.07)]"
>
<span className="w-[18px] text-center text-[14px] shrink-0"></span>
Import CSV
</a>
<a
href="#"
onClick={(e) => e.preventDefault()}
className="flex items-center gap-[10px] px-5 py-[9px] text-[13.5px] text-[#7A9E9E] no-underline transition-all cursor-pointer border-l-[3px] border-l-transparent hover:text-teal-400 hover:bg-[rgba(46,163,163,0.07)]"
>
<span className="w-[18px] text-center text-[14px] shrink-0"></span>
Settings
</a>
</nav>
{/* Footer */}
<div className="px-5 py-[14px] border-t border-[rgba(15,94,94,0.5)]">
<div className="flex items-center gap-[10px]">
<div className="w-[30px] h-[30px] bg-[rgba(46,163,163,0.18)] border border-[rgba(46,163,163,0.3)] rounded-full flex items-center justify-center text-[11px] text-teal-400 font-semibold shrink-0">
DS
</div>
<div>
<div className="text-xs font-medium text-warm-white">
Demo Supplier
</div>
<div className="text-[10px] text-teal-300 mt-[1px]">
Billing Staff
</div>
</div>
</div>
</div>
</aside>
);
}