From 091bbc0e95a8878c3919154eb64954589641e07a Mon Sep 17 00:00:00 2001 From: Sergio Nicolas Lavaise Date: Mon, 10 Aug 2026 02:14:30 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20update=20hospital=20management=20system?= =?UTF-8?q?=20-=20cama=20fuera=20de=20=C3=A1rea=20features=20and=20dashboa?= =?UTF-8?q?rd=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useHospitalStore.ts | 19 +++++------ src/lib/utils.ts | 8 +++-- src/sections/Dashboard.tsx | 6 ++-- src/sections/NuevoIngreso.tsx | 63 ++++++++++++++++++++++++++--------- 4 files changed, 65 insertions(+), 31 deletions(-) diff --git a/src/hooks/useHospitalStore.ts b/src/hooks/useHospitalStore.ts index d07948e..d839037 100644 --- a/src/hooks/useHospitalStore.ts +++ b/src/hooks/useHospitalStore.ts @@ -1269,28 +1269,27 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P }, [state.cultivos]); const getEstadisticas = useCallback(() => { - const fueraDeGrupoList = state.camas.filter(c => isCamaFueraDeGrupo(c, state.grupos)); - const camasActivas = state.camas.filter(c => !isCamaFueraDeGrupo(c, state.grupos)); - const camaPrincipal = state.camas.filter(c => !isCamaFueraDeGrupo(c, state.grupos)); - const camaOcupadas = state.camas.filter(c => c.estado === 'Ocupada' && !isCamaFueraDeGrupo(c, state.grupos)).length; - const camasDisponibles = state.camas.filter(c => c.estado === 'Disponible' && !isCamaFueraDeGrupo(c, state.grupos)).length; + const camasEnArea = state.camas.filter(c => !isCamaFueraDeGrupo(c)); + const camasFueraDeArea = state.camas.filter(c => isCamaFueraDeGrupo(c)); + + const camasOcupadas = camasEnArea.filter(c => c.estado === 'Ocupada').length; + const camasDisponibles = camasEnArea.filter(c => c.estado === 'Disponible').length; const camasMantenimiento = state.camas.filter(c => c.estado === 'Reparacion').length; const internacionesActivas = state.internaciones.filter(i => i.activa).length; const totalPacientes = state.pacientes.length; const cultivosPendientes = state.cultivos.filter(c => c.estado === 'NAF/Pendiente').length; return { - camaOcupadas, - camasOcupadas: camaOcupadas, + camasOcupadas, camasDisponibles, camasMantenimiento, totalCamas: state.camas.length, - totalCamasActivas: camasActivas.length, - camasFueraDeGrupo: fueraDeGrupoList.length, + totalCamasActivas: camasEnArea.length, + camasFueraDeArea: camasFueraDeArea.length, internacionesActivas, totalPacientes, cultivosPendientes, - porcentajeOcupacion: camaPrincipal.length > 0 ? Math.round((camaOcupadas / camaPrincipal.length) * 100) : 0, + porcentajeOcupacion: camasEnArea.length > 0 ? Math.round((camasOcupadas / camasEnArea.length) * 100) : 0, }; }, [state]); diff --git a/src/lib/utils.ts b/src/lib/utils.ts index ab3b730..c521cbb 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -55,11 +55,15 @@ export function computeSector(numero: string): "En Área" | "Fuera de Área" { const salaNum = parseInt(salaStr, 10); if (isNaN(salaNum)) return 'En Área'; - if (salaNum >= 300 && salaNum < 400 && salaNum % 2 !== 0) { + // 3XX-YY where XX is odd (so the whole 3XX is odd) + if (salaStr.length === 3 && salaStr.startsWith('3') && salaNum % 2 !== 0) { return 'Fuera de Área'; } - if (salaNum >= 400 && salaNum < 500) { + + // All those starting with 4 + if (salaStr.startsWith('4')) { return 'Fuera de Área'; } + return 'En Área'; } diff --git a/src/sections/Dashboard.tsx b/src/sections/Dashboard.tsx index 376db1d..78f4ea4 100644 --- a/src/sections/Dashboard.tsx +++ b/src/sections/Dashboard.tsx @@ -75,7 +75,7 @@ export function Dashboard({
{estadisticas.porcentajeOcupacion}% - {estadisticas.camasOcupadas}/{estadisticas.totalCamas} + {estadisticas.camasOcupadas}/{estadisticas.totalCamasActivas}

{estadisticas.camasDisponibles} camas disponibles @@ -87,7 +87,7 @@ export function Dashboard({ - Camas Fuera de Área + Camas fuera de área @@ -95,7 +95,7 @@ export function Dashboard({ {estadisticas.camasFueraDeArea}

- Camas Fuera de Grupo + Total de camas fuera de área

diff --git a/src/sections/NuevoIngreso.tsx b/src/sections/NuevoIngreso.tsx index 8704ad2..869e646 100644 --- a/src/sections/NuevoIngreso.tsx +++ b/src/sections/NuevoIngreso.tsx @@ -40,6 +40,7 @@ export function NuevoIngreso({ pacientes, camas, grupos, onIniciarInternacion, o const [antecedentesEnfermedadActual, setAntecedentesEnfermedadActual] = useState(''); const [apache, setApache] = useState(''); const [derivacion, setDerivacion] = useState(''); + const [grupoSeleccionado, setGrupoSeleccionado] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); const resetFormulario = () => { @@ -47,6 +48,7 @@ export function NuevoIngreso({ pacientes, camas, grupos, onIniciarInternacion, o setBusqueda(''); setCamaSeleccionada(''); setCamaInput(''); + setGrupoSeleccionado(''); setFechaIngresoHospital(''); setFechaIngresoClinica(''); setMotivoConsulta(''); @@ -57,11 +59,6 @@ export function NuevoIngreso({ pacientes, camas, grupos, onIniciarInternacion, o setDerivacion(''); }; - const normalizeStr = (str?: string) => (str || '').normalize('NFD').replace(/[\u0300-\u036f]/g, '').trim().toLowerCase(); - - const grupoFueraDeGrupo = grupos.find(a => normalizeStr(a.nombre) === 'fuera de grupo'); - const grupoFueraDeGrupoId = grupoFueraDeGrupo?.id || grupos[0]?.id || 'fuera-de-grupo'; - const pacientesSinInternar = pacientes.filter(p => { const internacionActiva = internaciones.find(i => i.pacienteId === p.id && i.activa); return !internacionActiva; @@ -127,6 +124,11 @@ export function NuevoIngreso({ pacientes, camas, grupos, onIniciarInternacion, o return; } + if (!grupoSeleccionado) { + toast.error('Debe seleccionar un grupo para el seguimiento'); + return; + } + if (!diagnosticoIngreso.trim()) { toast.error('Debe completar el Diagnóstico de Ingreso'); return; @@ -146,22 +148,22 @@ export function NuevoIngreso({ pacientes, camas, grupos, onIniciarInternacion, o try { let camaId = ''; - let newGrupoId = ''; if (modoCama === 'escribir') { const numeroCama = camaInput.trim(); const camaExistente = camas.find(c => c.numero === numeroCama); if (camaExistente) { - camaId = camaExistente.id; - newGrupoId = camaExistente.grupoId || grupoFueraDeGrupoId; + toast.error(`La cama ${numeroCama} ya existe en el sistema. Seleccione la cama del listado o ingrese un número diferente.`); + setIsSubmitting(false); + return; } else if (onAgregarCama) { camaId = await onAgregarCama({ numero: numeroCama, - grupoId: grupoFueraDeGrupoId, + grupoId: grupoSeleccionado, tipo: 'General', - estado: 'Ocupada' + estado: 'Ocupada', + sector: 'Fuera de Área' }); - newGrupoId = grupoFueraDeGrupoId; } else { toast.error('No se puede crear la cama'); setIsSubmitting(false); @@ -175,13 +177,12 @@ export function NuevoIngreso({ pacientes, camas, grupos, onIniciarInternacion, o return; } camaId = camaSeleccionada; - newGrupoId = camaElegida.grupoId || grupoFueraDeGrupoId; } await onIniciarInternacion({ pacienteId: pacienteSeleccionado, camaId: camaId, - grupoId: newGrupoId, + grupoId: grupoSeleccionado, medicoIngresante: effectiveMedico.trim(), diagnosticoIngreso: diagnosticoIngreso.trim(), motivoConsulta: motivoConsulta.trim() || undefined, @@ -317,17 +318,47 @@ export function NuevoIngreso({ pacientes, camas, grupos, onIniciarInternacion, o + {modoCama === 'escribir' && ( +
+ + +
+ )} + {modoCama === 'seleccionar' ? ( <>
- { + setCamaSeleccionada(val); + const cama = camas.find(c => c.id === val); + if (cama?.grupoId) { + setGrupoSeleccionado(cama.grupoId); + } + }} + >