import React, { useMemo, useState } from "react";
import { z } from "zod";
import { useForm, Controller } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Card as UICard, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
import { Switch } from "@/components/ui/switch";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Badge } from "@/components/ui/badge";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
ResponsiveContainer,
LineChart,
Line,
XAxis,
YAxis,
Tooltip,
ReferenceLine,
BarChart,
Bar,
Legend,
AreaChart,
Area,
} from "recharts";
import {
Activity,
Pill as PillIcon,
ClipboardList,
Calendar,
FileText,
Search,
FileUp,
Users,
Stethoscope,
Shield,
TriangleAlert,
QrCode,
Settings,
Brain,
DollarSign,
ListCheck,
Sparkles,
Layers,
Share2,
RadioTower,
FileCheck,
FolderLock,
MessageSquare,
SlidersHorizontal,
Globe,
Clock,
Landmark,
LifeBuoy,
} from "lucide-react";
// ========= componentes base reutilizables =========
function Section({ title, children, actions }: any) {
return (
{title}
{actions}
{children}
);
}
function FieldRow({ label, children, hint, id, required }: any) {
return (
{label && (
)}
{hint && {hint}}
{children}
);
}
function Kpi({ title, value, hint }: any) {
return (
{title}
{value}
{hint && {hint}
}
);
}
function ChartCard({ title, children, height = 240 }: any) {
return (
{title}
{children}
);
}
function EmptyState({ icon: Icon, title, desc, action }: any) {
return (
{Icon &&
}
{title}
{desc}
{action}
);
}
// ========= 01 Tablero =========
function Mod01Tablero() {
const kpis = [
{ t: "Adherencia (7d)", v: "86%" },
{ t: "PA promedio", v: "132/84" },
{ t: "Síntomas hoy", v: "1" },
];
return (
{kpis.map((k, i) => (
))}
{[
{ m: "Losartán 50mg", h: "08:00", done: true },
{ m: "Trazodona 100mg", h: "22:00", done: false },
].map((r, i) => (
{r.h}
{r.m}
{r.done ? "Tomado" : "Pendiente"}
))}
);
}
// ========= 02 Bitácora =========
const zSymptoms = z.object({
mood: z.enum(["bien", "neutral", "mal"]),
symptom: z.string().min(2),
intensity: z.coerce.number().min(1).max(10),
});
function Mod02Bitacora() {
const form = useForm({ resolver: zodResolver(zSymptoms), defaultValues: { intensity: 5 } });
const [saved, setSaved] = useState();
return (
);
}
// ========= 03 Medicación =========
const zMed = z.object({
name: z.string().min(2),
dose: z.string().min(1),
hour: z.string().regex(/^\d{2}:\d{2}$/),
});
function Mod03Medicamentos() {
const form = useForm({ resolver: zodResolver(zMed) });
const [rows, setRows] = useState([
{ name: "Trazodona", dose: "100mg", hour: "22:00" },
{ name: "Armodafinilo", dose: "150mg", hour: "08:00" },
]);
return (
| Medicamento |
Dosis |
Hora |
{rows.map((r, i) => (
| {r.name} |
{r.dose} |
{r.hour} |
))}
);
}
// ========= 04 Signos =========
const zVitals = z
.object({
sys: z.coerce.number().min(80).max(220),
dia: z.coerce.number().min(40).max(140),
hr: z.coerce.number().min(30).max(200),
})
.refine((v) => v.dia < v.sys, { path: ["dia"], message: "Diastólica < Sistólica" });
function Mod04Signos() {
const form = useForm({ resolver: zodResolver(zVitals) });
const data = useMemo(
() => [
{ d: "Lun", pa: 136 },
{ d: "Mar", pa: 134 },
{ d: "Mié", pa: 133 },
{ d: "Jue", pa: 135 },
{ d: "Vie", pa: 132 },
{ d: "Sáb", pa: 131 },
{ d: "Dom", pa: 130 },
],
[]
);
return (
{form.formState.errors.dia && (
{String(form.formState.errors.dia.message)}
)}
);
}
// ========= 05 a 34 (demo rápido) =========
function Mod05Consultas() {
const f = useForm();
return (
);
}
function Mod06Documentos() {
return (
);
}
function Mod07Costos() {
const data = [
{ m: "Ene", v: 63200 },
{ m: "Feb", v: 80400 },
{ m: "Mar", v: 75400 },
{ m: "Abr", v: 91200 },
];
return (
);
}
function Mod08Auditorias() {
const logs = Array.from({ length: 12 }, (_, i) => ({
t: `2025-11-${String(i + 1).padStart(2, "0")} 08:${String(i % 60).padStart(2, "0")}`,
e: i % 2 ? "Lectura de historial" : "Actualización de registro",
a: i % 3 ? "Titular" : "Cuidador",
}));
return (
{logs.map((l, i) => (
))}
);
}
function Mod09Analisis() {
return (
- Registrar PA dos veces al día por 7 días.
- Anotar rigidez matinal en bitácora si dura más de 30 minutos.
);
}
function Mod10Cotizacion() {
const items = [
{ f: "Farmacia A", p: 3990 },
{ f: "Farmacia B", p: 4290 },
{ f: "Farmacia C", p: 3890 },
];
const best = items.reduce((a, b) => (a.p < b.p ? a : b));
return (
| Farmacia |
Precio |
{items.map((x, i) => (
|
{x.f}
{x.f === best.f && Mejor precio}
|
${x.p} |
))}
);
}
function Mod11Reportes() {
const [gen, setGen] = useState(false);
return (
);
}
function Mod12Comunidad() {
return (
Muro
Grupos
{["Hoy me sentí mejor", "Busco grupo de HTA"].map((p, i) => (
{p}
))}
{["Diabetes", "Hipertensión", "Rehabilitación"].map((g) => (
))}
);
}
function Mod13Agenda() {
const [items, setItems] = useState([
{ t: "Tomar Trazodona 100mg", h: "22:00", done: false },
{ t: "Registrar PA", h: "08:00", done: true },
]);
return (
{items.map((it, i) => (
{it.h}
{it.t}
setItems((prev) =>
prev.map((p, ix) => (ix === i ? { ...p, done: v } : p))
)
}
/>
))}
);
}
function Mod14Profesional() {
const pts = [
{ n: "Walter P.", p: "Alta", u: "hoy 08:10" },
{ n: "Paciente demo", p: "Media", u: "ayer 19:40" },
];
return (
Paciente
Prioridad
Última act.
Acciones
{pts.map((p, i) => (
))}
);
}
function Mod15Privacidad() {
return (
| Nombre |
Relación |
Alcance |
Vence |
Acción |
| Cuidador demo |
Familiar |
Red de apoyo |
2025-12-01 |
|
);
}
function Mod16Ciclos() {
return (
Fase: Inicio · Meta: TA < 140/90
Activa
Fase: Mantenimiento · Meta: 130–139/80–89
Próxima
);
}
function Mod17Familiar() {
const [list, setList] = useState([
{ t: "Verificar toma de Trazodona", done: false },
{ t: "Registrar PA en la app", done: false },
]);
return (
{list.map((x, i) => (
{x.t}
setList((prev) =>
prev.map((p, ix) => (ix === i ? { ...p, done: v } : p))
)
}
/>
))}
);
}
function Mod18Psico() {
return (
);
}
function Mod19Economico() {
const series = [
{ m: "Ene", g: 63200 },
{ m: "Feb", g: 80400 },
{ m: "Mar", g: 75400 },
{ m: "Abr", g: 91200 },
];
return (
);
}
function Mod20Rutinas() {
return (
{["Lun", "Mar", "Mié", "Jue", "Vie", "Sáb", "Dom"].map((d) => (
{d}
- Desayuno: Avena + fruta
- Almuerzo: Proteína + ensalada
- Cena: Sopa de verduras
))}
Caminar 30′
Fuerza suave 15′
);
}
function Mod21Resumen() {
return (
- Ingreso a GES HTA · 2025-07-03
- Estudio tolerancia a la glucosa · 2025-07-15
- Consulta dolor manos/pies · 2025-11-10
);
}
function Mod22Acces() {
const [hc, setHc] = useState(false);
const [font, setFont] = useState(16);
return (
);
}
function Mod23Profesional() {
return (
{["Ver ficha", "Firmar receta", "Solicitar exámenes"].map((a) => (
))}
);
}
function Mod24Multiprof() {
const tasks = [
{ t: "Ajuste de dosis", own: "Médico", st: "pendiente" },
{ t: "Plan nutricional", own: "Nutrición", st: "en curso" },
];
return (
| Tarea |
Responsable |
Estado |
{tasks.map((x, i) => (
| {x.t} |
{x.own} |
{x.st}
|
))}
);
}
function Mod25Permisos() {
return (
{["Nutrición (lectura)", "Kinesiología (R/W)", "Psicología (lectura)"].map(
(p) => (
)
)}
);
}
function Mod26Integr() {
return (
FONASA · Atenciones: 0 · Licencias: 0 · Interconsultas: 0
);
}
function Mod27SOS() {
return (
- Alergias: Penicilina
- Dx relevante: HTA
- Meds: Losartán (ejemplo)
- Contacto: +56 9 1234 5678
);
}
function Mod28Licencias() {
const f = useForm();
return (
);
}
function Mod29Comunidad() {
return (
Grupo HTA
Rehabilitación
);
}
function Mod30IA() {
const [thr, setThr] = useState(140);
return (
);
}
function Mod31Config() {
return (
);
}
function Mod32Timeline() {
const events = [
{ t: "Ingreso GES HTA", d: "2025-07-03" },
{ t: "Estudio PTGO", d: "2025-07-15" },
{ t: "Consulta dolor manos/pies", d: "2025-11-10" },
];
return (
{events.map((e, i) => (
))}
);
}
function Mod33Legado() {
return (
);
}
function Mod34Cuidador() {
const [t, setT] = useState([
{ t: "Dar Trazodona 100mg 22:00", done: false },
{ t: "Registrar PA 08:00", done: false },
]);
return (
{t.map((x, i) => (
{x.t}
setT((prev) =>
prev.map((p, ix) => (ix === i ? { ...p, done: v } : p))
)
}
/>
))}
);
}
// ========= shell navegación =========
const NAV = [
{ id: 1, label: "01 · Tablero", icon: Activity },
{ id: 2, label: "02 · Bitácora", icon: ClipboardList },
{ id: 3, label: "03 · Medicamentos", icon: PillIcon },
{ id: 4, label: "04 · Signos", icon: Activity },
{ id: 5, label: "05 · Consultas", icon: Calendar },
{ id: 6, label: "06 · Documentos", icon: FileText },
{ id: 7, label: "07 · Costos", icon: DollarSign },
{ id: 8, label: "08 · Auditorías", icon: FileCheck },
{ id: 9, label: "09 · Análisis", icon: Sparkles },
{ id: 10, label: "10 · Cotización", icon: Search },
{ id: 11, label: "11 · Reportes", icon: FileText },
{ id: 12, label: "12 · Comunidad", icon: Users },
{ id: 13, label: "13 · Agenda", icon: Calendar },
{ id: 14, label: "14 · Profesional", icon: Stethoscope },
{ id: 15, label: "15 · Privacidad", icon: Shield },
{ id: 16, label: "16 · Ciclos", icon: Layers },
{ id: 17, label: "17 · Familiar", icon: Users },
{ id: 18, label: "18 · Psicología", icon: Brain },
{ id: 19, label: "19 · Económico", icon: DollarSign },
{ id: 20, label: "20 · Rutinas", icon: ListCheck },
{ id: 21, label: "21 · Resumen 360", icon: Activity },
{ id: 22, label: "22 · Accesibilidad", icon: SlidersHorizontal },
{ id: 23, label: "23 · Profesional tratante", icon: Stethoscope },
{ id: 24, label: "24 · Multiprofesional", icon: Users },
{ id: 25, label: "25 · Permisos", icon: FolderLock },
{ id: 26, label: "26 · Integraciones", icon: Landmark },
{ id: 27, label: "27 · SOS", icon: LifeBuoy },
{ id: 28, label: "28 · Licencias", icon: FileText },
{ id: 29, label: "29 · Comunidad+", icon: MessageSquare },
{ id: 30, label: "30 · IA", icon: Sparkles },
{ id: 31, label: "31 · Config", icon: Settings },
{ id: 32, label: "32 · Timeline", icon: Clock },
{ id: 33, label: "33 · Legado", icon: Globe },
{ id: 34, label: "34 · Cuidador", icon: Users },
];
const MODULES: Record> = {
1: Mod01Tablero,
2: Mod02Bitacora,
3: Mod03Medicamentos,
4: Mod04Signos,
5: Mod05Consultas,
6: Mod06Documentos,
7: Mod07Costos,
8: Mod08Auditorias,
9: Mod09Analisis,
10: Mod10Cotizacion,
11: Mod11Reportes,
12: Mod12Comunidad,
13: Mod13Agenda,
14: Mod14Profesional,
15: Mod15Privacidad,
16: Mod16Ciclos,
17: Mod17Familiar,
18: Mod18Psico,
19: Mod19Economico,
20: Mod20Rutinas,
21: Mod21Resumen,
22: Mod22Acces,
23: Mod23Profesional,
24: Mod24Multiprof,
25: Mod25Permisos,
26: Mod26Integr,
27: Mod27SOS,
28: Mod28Licencias,
29: Mod29Comunidad,
30: Mod30IA,
31: Mod31Config,
32: Mod32Timeline,
33: Mod33Legado,
34: Mod34Cuidador,
};
function Header() {
return (
);
}
function Sidebar({
current,
onSelect,
}: {
current: number;
onSelect: (id: number) => void;
}) {
return (
);
}
export default function TsProVistaNavegable0134() {
const [current, setCurrent] = useState(1);
const CurrentMod = useMemo(
() => MODULES[current] ?? Mod01Tablero,
[current]
);
return (
{NAV.find((n) => n.id === current)?.label}
);
}