// vita-history.jsx — Clinical history: patient-friendly dashboard + norm-compliant medical view
const DOCTYPE = 'CC';
function pacienteEdad(profile) { return profile.edad ? (String(profile.edad).replace(/\D/g, '') || profile.edad) : '—'; }
function folio(profile) {
const base = (profile.nombre || 'VITA').replace(/\s/g, '').toUpperCase();
let h = 0; for (let i = 0; i < base.length; i++) h = (h * 31 + base.charCodeAt(i)) % 1000000;
return 'HC-' + String(100000 + h).slice(0, 6);
}
function hoy() { return new Date().toLocaleDateString('es-CO', { day: '2-digit', month: '2-digit', year: 'numeric' }); }
function arrify(v) { return Array.isArray(v) ? v : (v ? [v] : []); }
// ── Build the patient timeline from session state ───────────────
function buildTimeline(profile, asis, docs, seguimiento, version) {
const ev = [];
ev.push({ icon: 'mic', color: 'accent', titulo: 'Primer triage con Vita', detalle: 'Tu historia de salud quedó registrada', cuando: 'Inicio' });
if (docs && docs.length) ev.push({ icon: 'doc', color: 'accent', titulo: docs.length + ' documento' + (docs.length > 1 ? 's' : '') + ' guardado' + (docs.length > 1 ? 's' : ''), detalle: docs.slice(0, 3).join(' · '), cuando: 'Inicio' });
ev.push({ icon: 'sparkle', color: 'green', titulo: 'Vita preparó tu análisis (ASIS)', detalle: asis ? asis.estadoTexto : 'Análisis de tu situación de salud', cuando: 'Inicio' });
(seguimiento || []).forEach(s => {
const done = ['agendado', 'activo', 'completado'].includes(s.estado);
ev.push({ icon: (window.SEG_ICON && window.SEG_ICON[s.tipo]) || 'calendar', color: done ? 'green' : 'amber', titulo: s.titulo, detalle: done ? 'Vita lo gestionó' : 'Vita está pendiente', cuando: 'En curso' });
});
if (version > 1) ev.push({ icon: 'refresh', color: 'accent', titulo: 'Historia actualizada (v' + version + ')', detalle: 'Sumaste información nueva', cuando: 'Reciente' });
return ev;
}
function HistoryScreen({ t, persona, profile, asis, docs, seguimiento, version, hcFormal, hcLoading, onGenerateFormal, onShare, onBack, onTalk, onOpenSeg, onShowSecurity, onToggleTheme, onOpenHome, onOpenProfile, onOpenServices }) {
const [mode, setMode] = React.useState('paciente'); // paciente | medica
const accent = persona.accent;
const colorMap = { accent: accent, green: t.green, amber: '#E6A93C' };
React.useEffect(() => {
if (mode === 'medica' && !hcFormal && !hcLoading) onGenerateFormal();
}, [mode]);
return (
{/* header */}
{Icon.chevron({ s: 18, c: t.textSoft, w: 2.5 })}
Historia clínica
Administrada por Vita · {folio(profile)}
{Icon.upload({ s: 18, c: accent })}
{/* mode toggle */}
{[['paciente', 'Para ti', 'heart'], ['medica', 'Para tu médico', 'doc']].map(([m, label, ic]) => (
setMode(m)} style={{
flex: 1, padding: '10px 0', borderRadius: 10, cursor: 'pointer', border: 'none',
display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 7,
background: mode === m ? `linear-gradient(135deg, ${accent}, ${persona.accentDeep})` : 'transparent',
color: mode === m ? t.onAccent : t.textSoft, fontFamily: 'Hanken Grotesk, sans-serif', fontSize: 14, fontWeight: 700,
boxShadow: mode === m ? `0 6px 16px ${hexA(accent, 0.3)}` : 'none', transition: 'all .2s',
}}>{Icon[ic]({ s: 16, c: mode === m ? t.onAccent : t.muted })}{label}
))}
{mode === 'paciente'
?
:
}
{}} onOpenProfile={onOpenProfile} onOpenServices={onOpenServices} onShowSecurity={onShowSecurity} onAddInfo={onTalk} />
);
}
// ── Patient-friendly view ───────────────────────────────────────
function PacienteView({ t, persona, profile, asis, docs, seguimiento, version, colorMap, onOpenSeg }) {
const accent = persona.accent;
const timeline = buildTimeline(profile, asis, docs, seguimiento, version);
const cards = [
{ icon: 'heart', label: 'Lo que cuidamos', items: arrify(profile.condiciones), empty: 'Sin condiciones registradas' },
{ icon: 'pill', label: 'Tus medicamentos', items: arrify(profile.medicamentos), empty: 'Sin medicamentos' },
{ icon: 'alert', label: 'Tus alergias', items: arrify(profile.alergias), empty: 'Sin alergias conocidas' },
{ icon: 'animo', label: 'En tu familia', items: arrify(profile.antecedentes), empty: 'Sin antecedentes' },
];
return (
{/* patient summary */}
{(profile.nombre || 'P').charAt(0)}
{profile.nombre || 'Paciente'}
{[pacienteEdad(profile) !== '—' ? pacienteEdad(profile) + ' años' : null, profile.sexo, profile.eps].filter(Boolean).join(' · ')}
{/* key cards */}
{cards.map((c, i) => (
{Icon[c.icon]({ s: 19, c: accent })}
{c.label}
{c.items.length ? c.items.map((it, j) => (
• {it}
)) :
{c.empty}
}
))}
{/* timeline */}
Tu línea de tiempo
{timeline.map((e, i) => {
const col = colorMap[e.color] || accent;
return (
{i !== timeline.length - 1 &&
}
{Icon[e.icon]({ s: 18, c: col })}
);
})}
);
}
// ── Medical / norm-compliant view ───────────────────────────────
function MedicaView({ t, persona, profile, hc, loading, onShare }) {
if (loading || !hc) {
return (
Vita está estructurando tu historia en formato clínico oficial…
);
}
const ant = hc.antecedentes || {};
// formal document — white "paper" regardless of theme for that official feel
const paper = '#FFFFFF', ink = '#0A1A33', sub = '#5A6B86', line = 'rgba(10,26,51,0.10)';
return (
{/* compliance banner */}
{['Res. 1995/1999', 'Res. 866/2021 · HCE', 'HL7 FHIR', 'CIE-10'].map(b => (
{Icon.shield({ s: 12, c: persona.accent })}{b}
))}
{/* the document */}
{/* doc header */}
{Icon.pulse({ s: 17, c: '#fff', w: 2.4 })}
VITA
HISTORIA CLÍNICA ELECTRÓNICA
Folio {folio(profile)}
{hoy()}
{/* 1. Identificación */}
{/* 2. Motivo de consulta */}
{hc.motivoConsulta}
{/* 3. Enfermedad actual */}
{hc.enfermedadActual}
{/* 4. Revisión por sistemas */}
{hc.revisionSistemas}
{/* 5. Antecedentes */}
{[['Personales / patológicos', ant.personales], ['Familiares', ant.familiares], ['Alérgicos', ant.alergicos], ['Farmacológicos', ant.farmacologicos], ['Hábitos / estilo de vida', ant.habitos]].map(([lab, items], i) => (
{lab}:
{arrify(items).length ? arrify(items).join('; ') : 'No refiere'}
))}
{/* 6. Diagnósticos CIE-10 */}
{arrify(hc.diagnosticos).length ? arrify(hc.diagnosticos).map((d, i) => (
{d.cie10 || '—'}
{d.descripcion}
{d.tipo || ''}
)) : Sin diagnósticos codificados.
}
{/* 7. Plan de manejo */}
{arrify(hc.planManejo).map((p, i) => (
{i + 1}. {p}
))}
{/* 8. Órdenes / pendientes */}
{arrify(hc.ordenesPendientes).length > 0 && (
{arrify(hc.ordenesPendientes).map((o, i) => (
{o}
))}
)}
{/* signature footer */}
{Icon.shield({ s: 16, c: persona.accentDeep })}
Registro generado y custodiado por Vita · VITA . Documento con trazabilidad y firma digital. La verificación de identidad documental se completa en la primera atención presencial.
{Icon.upload({ s: 18, c: t.onAccent })} Compartir con mi médico
);
}
function DocSection({ ink, sub, line, n, titulo, children, last }) {
return (
);
}
function P({ ink, children }) { return {children}
; }
function IdGrid({ ink, sub, rows }) {
return (
{rows.map(([k, v], i) => (
))}
);
}
// ── Share sheet ─────────────────────────────────────────────────
function ShareSheet({ t, persona, profile, onClose }) {
const [sent, setSent] = React.useState(false);
const accent = persona.accent;
const options = [
{ icon: 'doc', label: 'Descargar PDF oficial', desc: 'Formato historia clínica · Res. 1995/1999' },
{ icon: 'mail', label: 'Enviar a mi médico', desc: 'Por correo seguro y cifrado' },
{ icon: 'card', label: 'Código QR temporal', desc: 'El médico lo escanea en consulta' },
{ icon: 'shield', label: 'Acceso por interoperabilidad', desc: 'HL7 FHIR a la institución (Res. 866/2021)' },
];
return (
{!sent ? (
<>
Compartir con tu médico
Tú decides qué se comparte y por cuánto tiempo. Vita entrega tu historia en formato clínico oficial.
{options.map((o, i) => (
setSent(o.label)} style={{
display: 'flex', alignItems: 'center', gap: 13, padding: 14, borderRadius: 15, cursor: 'pointer', textAlign: 'left', width: '100%',
border: `1px solid ${t.stroke}`, background: t.dark ? 'rgba(255,255,255,0.04)' : '#FFFFFF', WebkitTapHighlightColor: 'transparent',
}}>
{Icon[o.icon]({ s: 21, c: accent })}
{Icon.chevron({ s: 17, c: t.muted })}
))}
{Icon.lock({ s: 13, c: t.muted })} Acceso revocable en cualquier momento
>
) : (
{Icon.check({ s: 40, c: '#fff', w: 3 })}
Listo, ya lo compartí
“{sent}” quedó disponible en formato clínico oficial. Tu médico verá una historia completa y conforme a la norma.
Entendido
)}
);
}
Object.assign(window, { HistoryScreen, ShareSheet });