import { useState } from 'react'; import { Bed, CheckCircle2, Clock, Wrench, User, Plus, Trash, Edit2, Save, X } from 'lucide-react'; import { Card, CardContent } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { formatDateDDMMYYYY, getNombreProfesional, isCamaFueraDeGrupo } from '@/lib/utils'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Label } from '@/components/ui/label'; import { Input } from '@/components/ui/input'; import type { Cama, Paciente, Internacion, Grupo } from '@/types'; import { useHospitalStore } from '@/hooks/useHospitalStore'; interface MapaCamasProps { camas: Cama[]; grupos: Grupo[]; pacientes: Paciente[]; internaciones: Internacion[]; onActualizarCama: (id: string, datos: Partial) => void; onAgregarCama: (cama: Omit) => any; onEliminarCama: (id: string) => void; onIniciarInternacion: (internacion: Omit) => Promise; onAgregarGrupo: (grupo: Omit) => any; onActualizarGrupo: (id: string, datos: Partial) => void; onEliminarGrupo: (id: string) => void; getPacienteById: (id: string) => Paciente | undefined; getInternacionById: (id: string) => Internacion | undefined; } export function MapaCamas({ camas, grupos, pacientes, internaciones, onActualizarCama, onAgregarCama, onEliminarCama, onIniciarInternacion, onAgregarGrupo, onActualizarGrupo, onEliminarGrupo, getPacienteById, getInternacionById }: MapaCamasProps) { const { canEditCama, canAccessGrupo, currentUser } = useHospitalStore(); const [filtroSala, setFiltroSala] = useState('todas'); const [filtroTipo, setFiltroTipo] = useState('todos'); const [filtroEstado, setFiltroEstado] = useState('todos'); const [camaSeleccionada, setCamaSeleccionada] = useState(null); const [grupoSeleccionada, setGrupoSeleccionada] = useState(''); const [pacienteSeleccionado, setPacienteSeleccionado] = useState(''); const [diagnostico, setDiagnostico] = useState(''); const [enfermedadActual, setEnfermedadActual] = useState(''); const [antecedentesEnfermedadActual, setAntecedentesEnfermedadActual] = useState(''); const effectiveMedico = getNombreProfesional(currentUser); const [dialogoAbierto, setDialogoAbierto] = useState(false); // Grupo dialog state const [grupoDialogOpen, setGrupoDialogOpen] = useState(false); const [grupoNombre, setGrupoNombre] = useState(''); const [editingGrupoId, setEditingGrupoId] = useState(null); // Cama dialog state const [bedDialogOpen, setBedDialogOpen] = useState(false); const [editingBed, setEditingBed] = useState(null); const [bedNumero, setBedNumero] = useState(''); const [bedTipo, setBedTipo] = useState('General'); const [bedGrupoId, setBedGrupoId] = useState(undefined); const salas = Array.from(new Set(camas.map(c => c.grupoId).filter(Boolean))) as string[]; const grupoById = Object.fromEntries(grupos.map(a => [a.id, a.nombre])); const tipos = Array.from(new Set(camas.map(c => c.tipo))); const camasFiltradas = camas.filter(cama => { if (filtroSala !== 'todas' && cama.grupoId !== filtroSala) return false; if (filtroTipo !== 'todos' && cama.tipo !== filtroTipo) return false; if (filtroEstado !== 'todos' && cama.estado !== filtroEstado) return false; return true; }); const getEstadoColor = (cama: Cama) => { if (cama.estado === 'Disponible') { return 'bg-emerald-100 border-emerald-300 text-emerald-800 dark:bg-emerald-950/80 dark:border-emerald-700/60 dark:text-emerald-200'; } if (cama.estado === 'Reservada') { return 'bg-orange-100 border-orange-300 text-orange-800 dark:bg-orange-950/80 dark:border-orange-700/60 dark:text-orange-200'; } if (cama.estado === 'Ocupada') { // Tipos de aislamiento const aislamientos = ['Aislamiento KPC', 'Aislamiento COVID', 'Aislamiento Clostridium', 'Aislamiento Neutropenico']; if (aislamientos.includes(cama.tipo)) { return 'bg-red-100 border-red-300 text-red-800 dark:bg-red-950/80 dark:border-red-700/60 dark:text-red-200'; } return 'bg-blue-100 border-blue-300 text-blue-800 dark:bg-blue-950/80 dark:border-blue-700/60 dark:text-blue-200'; } return 'bg-amber-100 border-amber-300 text-amber-800 dark:bg-amber-950/80 dark:border-amber-700/60 dark:text-amber-200'; }; const getEstadoIcono = (cama: Cama) => { switch (cama.estado) { case 'Disponible': return ; case 'Ocupada': return ; case 'Reparacion': return ; case 'Reservada': return ; } }; const parseBedNumber = (numero: string) => { const match = numero.match(/^(\d{3})-(\d+)$/); if (!match) return { sala: 0, cama: 0 }; return { sala: parseInt(match[1]), cama: parseInt(match[2]) }; }; const sortedCamas = [...camasFiltradas].sort((a, b) => { const pa = parseBedNumber(a.numero); const pb = parseBedNumber(b.numero); const getOrden = (sala: number) => { const grupo = Math.floor(sala / 100); const esPar = sala % 2 === 0; if (grupo === 2) { if (esPar) return { grupo: 2, suborden: 0, sala }; // 2XX pares, menor a mayor return { grupo: 1, suborden: 1, sala }; // 2XX impares, mayor a menor } if (grupo === 3) { if (esPar) return { grupo: 3, suborden: 0, sala }; // 3XX pares, menor a mayor return { grupo: 4, suborden: 1, sala }; // 3XX impares, mayor a menor } if (grupo === 4) { if (esPar) return { grupo: 6, suborden: 0, sala }; // 4XX pares, menor a mayor return { grupo: 5, suborden: 1, sala }; // 4XX impares, mayor a menor } return { grupo: 10, suborden: 1, sala }; }; const oa = getOrden(pa.sala); const ob = getOrden(pb.sala); if (oa.grupo !== ob.grupo) return oa.grupo - ob.grupo; if (oa.suborden === ob.suborden) { if (oa.suborden === 0) return (oa.sala || pa.sala) - (ob.sala || pb.sala); return (ob.sala || 0) - (oa.sala || 0); } return oa.suborden - ob.suborden; }); const handleOcuparCama = () => { if (camaSeleccionada && grupoSeleccionada && pacienteSeleccionado && diagnostico && enfermedadActual && effectiveMedico) { onIniciarInternacion({ pacienteId: pacienteSeleccionado, camaId: camaSeleccionada.id, grupoId: grupoSeleccionada, diagnosticoIngreso: diagnostico, enfermedadActual, antecedentesEnfermedadActual: antecedentesEnfermedadActual || undefined, medicoIngresante: effectiveMedico, }); setDialogoAbierto(false); setCamaSeleccionada(null); setGrupoSeleccionada(''); setPacienteSeleccionado(''); setDiagnostico(''); setEnfermedadActual(''); setAntecedentesEnfermedadActual(''); } }; const handleCambiarEstado = (cama: Cama, nuevoEstado: Cama['estado']) => { onActualizarCama(cama.id, { estado: nuevoEstado }); }; const pacientesSinInternar = pacientes.filter(p => { const internacionActiva = internaciones.find(i => i.pacienteId === p.id && i.activa); return !internacionActiva; }); return (

Mapa de Camas

Gestión de camas del servicio

{camas.filter(c => c.estado === 'Disponible' && !isCamaFueraDeGrupo(c, grupos)).length} Disponibles {camas.filter(c => c.estado === 'Ocupada' && !isCamaFueraDeGrupo(c, grupos)).length} Ocupadas
{/* Filtros */}
{/* Mapa de Camas */}
{sortedCamas.map((cama) => { const internacion = internaciones.find(i => i.camaId === cama.id && i.activa); const paciente = internacion ? getPacienteById(internacion.pacienteId) : null; return ( setCamaSeleccionada(cama)} >
{getEstadoIcono(cama)}

{cama.numero}

{cama.grupoId ? grupoById[cama.grupoId] ?? 'Grupo desconocido' : 'Sin grupo'} - {cama.sector || 'En Área'}

{cama.tipo} {cama.estado === 'Ocupada' && paciente && (

{paciente.apellido}, {paciente.nombre}

)}
Cama {cama.numero} - {cama.grupoId ? grupoById[cama.grupoId] ?? 'Grupo desconocido' : 'Sin grupo'}
{cama.estado} {cama.tipo}
{cama.estado === 'Ocupada' && paciente && internacion && (

Paciente:

{paciente.apellido}, {paciente.nombre}

DNI: {paciente.dni}

Ingreso: {internacion.fechaIngresoClinica ? formatDateDDMMYYYY(internacion.fechaIngresoClinica) : 'N/A'}

Diagnóstico: {internacion.diagnosticoIngreso}

Médico: {internacion.medicoIngresante}

)}

Acciones:

{cama.estado === 'Disponible' && canEditCama(cama.id) && ( Nueva Internación - Cama {cama.numero}