// Epic UI components — chip, panel, sparkline, problem/med/lab/encounter/appt/gap renderers // Small provenance chip: tells user "this data came from Epic" const EpicChip = ({ fresh = true, size = 'sm' }) => ( 1 hr'}> Epic ); // Status pill for the connection const EpicStatusPill = ({ tone, children }) => ( {children} ); // Small sparkline for lab trends const EpicSpark = ({ values, width = 56, height = 18, color }) => { if (!values || values.length < 2) return null; const min = Math.min(...values), max = Math.max(...values); const range = max - min || 1; const stepX = width / (values.length - 1); const pts = values.map((v, i) => `${i * stepX},${height - ((v - min) / range) * height}`).join(' '); return ( ); }; // Unified Epic panel — header + body slot const EpicPanel = ({ title, icon, sub, actions, children }) => (
{icon && }

{title}

{sub && · {sub}}
{actions}
{children}
); const EpicFlag = ({ f, children }) => {children}; // ─── Resident drawer Epic block ────────────────────────────────── const EpicDrawerSection = ({ epic, resident, onBreakGlass }) => { if (!epic) { return (

Epic record

No Epic record linked. Search by DOB + name to match this resident to their chart.
); } const [tab, setTab] = React.useState('overview'); const tabs = [ { v: 'overview', l: 'Overview', ic: 'activity' }, { v: 'problems', l: 'Problems', ic: 'note', n: epic.problems.filter(p => p.status === 'active').length }, { v: 'meds', l: 'Meds', ic: 'pen', n: epic.meds.length }, { v: 'labs', l: 'Labs & vitals', ic: 'activity', n: epic.labs.length }, { v: 'encounters', l: 'Encounters', ic: 'calendar', n: epic.encounters.length }, { v: 'appts', l: 'Appts', ic: 'calendar', n: epic.appointments.length }, { v: 'gaps', l: 'Care gaps', ic: 'bell', n: epic.careGaps.filter(g => g.status === 'overdue').length }, { v: 'imms', l: 'Immunizations', ic: 'check' }, { v: 'sdoh', l: 'SDoH', ic: 'heart' }, ]; return (

Epic record

MRN {epic.mrn} · matched {epic.matchConfidence}%
{/* Tab strip */}
{tabs.map(t => ( ))}
{tab === 'overview' && (
MRN
{epic.mrn}
Address on file
{epic.addressOnFile}
Primary care
{epic.pcp.name}
{epic.pcp.clinic} · {epic.pcp.phone}
Care team ({epic.careTeam.length})
{epic.careTeam.map(m =>
{m.name} · {m.role}
)}
{/* key flags */} {(epic.allergies.length > 0 || epic.careGaps.some(g => g.status === 'overdue')) && (
{epic.allergies.length > 0 && ⚠ {epic.allergies.length} allerg{epic.allergies.length === 1 ? 'y' : 'ies'}} {epic.careGaps.filter(g => g.status === 'overdue').map(g => Overdue: {g.label})}
)}
)} {tab === 'problems' && ( {epic.problems.map(p => ( ))}
ConditionICD-10OnsetStatus
{p.label} {p.code} {p.onset} {p.status === 'active' ? Active : p.status === 'remission' ? Remission : Resolved}
)} {tab === 'meds' && ( {epic.meds.map(m => ( ))}
MedicationDoseFrequencyPrescriberSince
{m.name}{m.dose}{m.freq} {m.prescriber} {m.since}
)} {tab === 'labs' && ( {epic.labs.map(l => ( ))}
MeasureValueFlagRef rangeDateTrend
{l.name} {l.value} {l.unit} {l.flag} {l.ref} {l.date} {l.trend && }
)} {tab === 'encounters' && ( {epic.encounters.map(e => ( ))}
DateKindProviderReason
{e.date} {e.kind} {e.provider}
{e.clinic}
{e.reason}
)} {tab === 'appts' && ( epic.appointments.length === 0 ?
No upcoming appointments on file.
: {epic.appointments.map(a => ( ))}
DateTimeKindProviderReason
{a.date}{a.time} {a.kind}{a.provider}
{a.clinic}
{a.reason}
)} {tab === 'gaps' && ( {epic.careGaps.map(g => ( ))}
Care gapStatusDueOwner
{g.label} {g.status} {g.dueDate}{g.owner}
)} {tab === 'imms' && ( {epic.immunizations.map(i => ( ))}
VaccineLast givenStatus
{i.name} {i.date || } {i.due ? (i.due.includes('Overdue') ? {i.due} : {i.due}) : Up to date}
)} {tab === 'sdoh' && ( epic.sdoh.length === 0 ?
No SDoH screenings on file.
: {epic.sdoh.map((s, i) => ( ))}
ScreenerResponseDate
{s.q} {s.a} {s.date}
)} {/* Allergies always inline below */} {tab === 'overview' && epic.allergies.length > 0 && (
⚠ Allergies
{epic.allergies.map(a => (
{a.substance} · {a.reaction} ({a.severity})
))}
)}
); }; // ─── Record-match modal (used during intake) ─────────────────── const EpicMatchModal = ({ onClose, onMatch, onCreate }) => { const [selected, setSelected] = React.useState(0); const [glass, setGlass] = React.useState(false); return (
e.stopPropagation()}>

Possible matches in Epic

Searching by DOB · last name · phone. Review before linking — accuracy matters.
Search values
Dolores Fitzgerald DOB 07/14/1948 (978) 555-0771 Petersham, MA
{EPIC_INTAKE_CANDIDATES.map((c, i) => (
setSelected(i)}>
{c.confidence}%match
{c.first} {c.last}
MRN {c.mrn} DOB {c.dob} {c.phone}
{c.address}
PCP: {c.pcp} · Last visit: {c.lastVisit} · Problems: {c.problems.join(', ')}
Matched on: {c.matchedOn.map(m => {m})}
{c.note &&
⚠ {c.note}
}
{selected === i && }
))}
); }; Object.assign(window, { EpicChip, EpicStatusPill, EpicSpark, EpicPanel, EpicFlag, EpicDrawerSection, EpicMatchModal });