// portal-components.jsx — Shared UI primitives
// Exports to window: TierBadge, LabBadge, ProgressBar, SectionLabel, Modal, EmptyState, VitalChart
const { useState, useEffect, useRef } = React;
function TierBadge({ tier, size = 'sm' }) {
const C = window.C;
const t = C.tiers[tier] || C.tiers.BRONCE;
const isLg = size === 'lg';
return (
{tier}
);
}
function LabBadge({ labId }) {
const lab = (window.LABS || []).find(l => l.id === labId);
if (!lab) return null;
return (
{lab.name}
);
}
function ProgressBar({ value, max, color, height = 6 }) {
const pct = Math.min(Math.max((value / Math.max(max, 1)) * 100, 2), 100);
return (
);
}
function SectionLabel({ children, style }) {
return (
{children}
);
}
function EmptyState({ icon, title, sub }) {
const C = window.C;
return (
{icon}
{title}
{sub &&
{sub}
}
);
}
function Modal({ visible, onClose, title, children, height = '90%' }) {
const C = window.C;
useEffect(() => {
document.body.style.overflow = visible ? 'hidden' : '';
return () => { document.body.style.overflow = ''; };
}, [visible]);
if (!visible) return null;
return (
e.stopPropagation()}>
{title &&
{title}
}
{children}
);
}
// ── VitalChart — SVG sparkline ────────────────────────────────────────────────
function VitalChart({ data, color, unit, targetMin, targetMax, height = 80 }) {
if (!data || data.length < 2) return Sin suficientes datos
;
const W = 280, H = height;
const vals = data.map(d => d.value || d.sys || 0);
const minV = Math.min(...vals) * 0.93;
const maxV = Math.max(...vals) * 1.07;
const x = (i) => (i / (data.length - 1)) * (W - 20) + 10;
const y = (v) => H - 8 - ((v - minV) / (maxV - minV)) * (H - 16);
const points = vals.map((v, i) => `${x(i)},${y(v)}`).join(' ');
const area = `M ${x(0)},${H} ` + vals.map((v, i) => `L ${x(i)},${y(v)}`).join(' ') + ` L ${x(vals.length-1)},${H} Z`;
const last = vals[vals.length - 1];
const inTarget = targetMin && targetMax ? (last >= targetMin && last <= targetMax) : true;
return (
);
}
Object.assign(window, { TierBadge, LabBadge, ProgressBar, SectionLabel, EmptyState, Modal, VitalChart });