feat: update hospital management system and fix linter issues
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
let code = fs.readFileSync('src/App.tsx', 'utf8');
|
||||||
|
|
||||||
|
code = code.replace(/store\.getLaboratoriosByPaciente\(paciente\.id\)/g, 'store.getLaboratoriosByInternacion(internacion.id)');
|
||||||
|
code = code.replace(/store\.getGlucemiasByPaciente\(paciente\.id\)/g, 'store.getGlucemiasByInternacion(internacion.id)');
|
||||||
|
code = code.replace(/store\.getAcidosBaseByPaciente\(paciente\.id\)/g, 'store.getAcidosBaseByInternacion(internacion.id)');
|
||||||
|
code = code.replace(/store\.getCultivosByPaciente\(paciente\.id\)/g, 'store.getCultivosByInternacion(internacion.id)');
|
||||||
|
code = code.replace(/store\.estudiosComplementarios\.filter\(e => e\.pacienteId === paciente\.id\)/g, 'store.estudiosComplementarios.filter(e => e.internacionId === internacion.id)');
|
||||||
|
|
||||||
|
fs.writeFileSync('src/App.tsx', code);
|
||||||
+14
-23
@@ -1,30 +1,21 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
let code = fs.readFileSync('src/hooks/useHospitalStore.ts', 'utf8');
|
let code = fs.readFileSync('src/hooks/useHospitalStore.ts', 'utf8');
|
||||||
|
|
||||||
code = code.replace(
|
code = code.replace(/getLaboratoriosByPaciente = useCallback\(\(pacienteId: string\)/g, 'getLaboratoriosByInternacion = useCallback((internacionId: string)');
|
||||||
/const nuevaCama: Cama = \{\s*\.\.\.cama,\s*id: generateUUID\(\),\s*\} as Cama;/,
|
code = code.replace(/\.filter\(l => l\.pacienteId === pacienteId\)/g, '.filter(l => l.internacionId === internacionId)');
|
||||||
`const nuevaCama: Cama = {
|
|
||||||
...cama,
|
|
||||||
id: generateUUID(),
|
|
||||||
sector: computeSector(cama.numero),
|
|
||||||
} as Cama;`
|
|
||||||
);
|
|
||||||
|
|
||||||
// We need to import computeSector if it's not imported.
|
code = code.replace(/getGlucemiasByPaciente = useCallback\(\(pacienteId: string\)/g, 'getGlucemiasByInternacion = useCallback((internacionId: string)');
|
||||||
// It is in utils.ts, and we already import isCamaFueraDeGrupo.
|
code = code.replace(/\.filter\(g => g\.pacienteId === pacienteId\)/g, '.filter(g => g.internacionId === internacionId)');
|
||||||
code = code.replace(
|
|
||||||
/import \{ getNombreProfesional, isCamaFueraDeGrupo \} from '@\/lib\/utils';/,
|
|
||||||
`import { getNombreProfesional, isCamaFueraDeGrupo, computeSector } from '@/lib/utils';`
|
|
||||||
);
|
|
||||||
|
|
||||||
code = code.replace(
|
code = code.replace(/getAcidosBaseByPaciente = useCallback\(\(pacienteId: string\)/g, 'getAcidosBaseByInternacion = useCallback((internacionId: string)');
|
||||||
/const actualizarCama = useCallback\(async \(id: string, datos: Partial<Cama>\) => \{\s*try \{\s*await apiCall\('PUT', `\/camas\/\$\{id\}`/,
|
code = code.replace(/\.filter\(a => a\.pacienteId === pacienteId\)/g, '.filter(a => a.internacionId === internacionId)');
|
||||||
`const actualizarCama = useCallback(async (id: string, datos: Partial<Cama>) => {
|
|
||||||
try {
|
code = code.replace(/getCultivosByPaciente = useCallback\(\(pacienteId: string\)/g, 'getCultivosByInternacion = useCallback((internacionId: string)');
|
||||||
if (datos.numero !== undefined) {
|
code = code.replace(/\.filter\(c => c\.pacienteId === pacienteId\)/g, '.filter(c => c.internacionId === internacionId)');
|
||||||
datos.sector = computeSector(datos.numero);
|
|
||||||
}
|
code = code.replace(/getLaboratoriosByPaciente,/g, 'getLaboratoriosByInternacion,');
|
||||||
await apiCall('PUT', \`/camas/\${id}\``
|
code = code.replace(/getGlucemiasByPaciente,/g, 'getGlucemiasByInternacion,');
|
||||||
);
|
code = code.replace(/getAcidosBaseByPaciente,/g, 'getAcidosBaseByInternacion,');
|
||||||
|
code = code.replace(/getCultivosByPaciente,/g, 'getCultivosByInternacion,');
|
||||||
|
|
||||||
fs.writeFileSync('src/hooks/useHospitalStore.ts', code);
|
fs.writeFileSync('src/hooks/useHospitalStore.ts', code);
|
||||||
|
|||||||
+1
-1
@@ -458,7 +458,7 @@ export function updateCama(id, updates) {
|
|||||||
|
|
||||||
if (fields.length > 0) {
|
if (fields.length > 0) {
|
||||||
values.push(id);
|
values.push(id);
|
||||||
db.prepare(`UPDATE camas SET ${fields.join(', ')} WHERE id = ?`).run(values);
|
db.prepare(`UPDATE camas SET ${fields.join(', ')} WHERE id = ?`).run(...values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-9
@@ -17,6 +17,7 @@ import { Spinner } from '@/components/ui/spinner';
|
|||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { ThemeProvider } from "@/components/theme-provider";
|
import { ThemeProvider } from "@/components/theme-provider";
|
||||||
import { Toaster } from '@/components/ui/sonner';
|
import { Toaster } from '@/components/ui/sonner';
|
||||||
|
import type { Indicacion, MovimientoIndicacion } from '@/types';
|
||||||
|
|
||||||
function AppContent() {
|
function AppContent() {
|
||||||
const store = useHospitalStore();
|
const store = useHospitalStore();
|
||||||
@@ -53,7 +54,7 @@ function AppContent() {
|
|||||||
pacientes={store.pacientes}
|
pacientes={store.pacientes}
|
||||||
internaciones={store.internaciones}
|
internaciones={store.internaciones}
|
||||||
onActualizarCama={store.actualizarCama}
|
onActualizarCama={store.actualizarCama}
|
||||||
onAgregarCama={store.agregarCama as any}
|
onAgregarCama={store.agregarCama}
|
||||||
onEliminarCama={store.eliminarCama}
|
onEliminarCama={store.eliminarCama}
|
||||||
onIniciarInternacion={store.iniciarInternacion}
|
onIniciarInternacion={store.iniciarInternacion}
|
||||||
getPacienteById={store.getPacienteById}
|
getPacienteById={store.getPacienteById}
|
||||||
@@ -85,6 +86,7 @@ function AppContent() {
|
|||||||
cultivos={store.cultivos}
|
cultivos={store.cultivos}
|
||||||
onIniciarInternacion={store.iniciarInternacion}
|
onIniciarInternacion={store.iniciarInternacion}
|
||||||
onFinalizarInternacion={store.finalizarInternacion}
|
onFinalizarInternacion={store.finalizarInternacion}
|
||||||
|
onEliminarInternacion={store.eliminarInternacion}
|
||||||
getPacienteById={store.getPacienteById}
|
getPacienteById={store.getPacienteById}
|
||||||
getCamaById={store.getCamaById}
|
getCamaById={store.getCamaById}
|
||||||
onVerHC={(id) => { store.setCurrentInternacion(id); store.setVista('historiaclinica'); }}
|
onVerHC={(id) => { store.setCurrentInternacion(id); store.setVista('historiaclinica'); }}
|
||||||
@@ -134,7 +136,6 @@ function AppContent() {
|
|||||||
case 'historiaclinica': {
|
case 'historiaclinica': {
|
||||||
const internacionId = store.currentInternacionId || '';
|
const internacionId = store.currentInternacionId || '';
|
||||||
const internacion = store.getInternacionById(internacionId);
|
const internacion = store.getInternacionById(internacionId);
|
||||||
const { datosVitales, evoluciones, laboratorios, acidosBase, cultivos, estudios, interconsultas, atb, indicaciones } = store;
|
|
||||||
const paciente = internacion ? store.getPacienteById(internacion.pacienteId) : undefined;
|
const paciente = internacion ? store.getPacienteById(internacion.pacienteId) : undefined;
|
||||||
if (!internacion || !paciente) {
|
if (!internacion || !paciente) {
|
||||||
return (
|
return (
|
||||||
@@ -151,11 +152,11 @@ function AppContent() {
|
|||||||
cama={store.getCamaById(internacion.camaId)}
|
cama={store.getCamaById(internacion.camaId)}
|
||||||
allCamas={store.camas}
|
allCamas={store.camas}
|
||||||
evoluciones={store.getEvolucionesByInternacion(internacion.id)}
|
evoluciones={store.getEvolucionesByInternacion(internacion.id)}
|
||||||
laboratorios={store.getLaboratoriosByPaciente(paciente.id)}
|
laboratorios={store.getLaboratoriosByInternacion(internacion.id)}
|
||||||
glucemias={store.getGlucemiasByPaciente(paciente.id)}
|
glucemias={store.getGlucemiasByInternacion(internacion.id)}
|
||||||
acidosBase={store.getAcidosBaseByPaciente(paciente.id)}
|
acidosBase={store.getAcidosBaseByInternacion(internacion.id)}
|
||||||
cultivos={store.getCultivosByPaciente(paciente.id)}
|
cultivos={store.getCultivosByInternacion(internacion.id)}
|
||||||
estudiosComplementarios={store.estudiosComplementarios.filter(e => e.pacienteId === paciente.id)}
|
estudiosComplementarios={store.estudiosComplementarios.filter(e => e.internacionId === internacion.id)}
|
||||||
interconsultas={(store.interconsultas || []).filter(ic => ic.internacionId === internacion.id)}
|
interconsultas={(store.interconsultas || []).filter(ic => ic.internacionId === internacion.id)}
|
||||||
atb={(store.atb || []).filter(a => a.internacionId === internacion.id)}
|
atb={(store.atb || []).filter(a => a.internacionId === internacion.id)}
|
||||||
onAgregarEvolucion={store.agregarEvolucion}
|
onAgregarEvolucion={store.agregarEvolucion}
|
||||||
@@ -182,12 +183,12 @@ function AppContent() {
|
|||||||
onAgregarATB={(atb) => store.agregarATB({ ...atb, internacionId: internacion.id })}
|
onAgregarATB={(atb) => store.agregarATB({ ...atb, internacionId: internacion.id })}
|
||||||
onActualizarATB={store.actualizarATB}
|
onActualizarATB={store.actualizarATB}
|
||||||
onEliminarATB={store.eliminarATB}
|
onEliminarATB={store.eliminarATB}
|
||||||
indicadores={(Array.isArray(store.indicaciones) ? store.indicaciones : []).filter((i: any) => i.internacionId === internacion.id)}
|
indicadores={(Array.isArray(store.indicaciones) ? store.indicaciones : []).filter((i: Indicacion) => i.internacionId === internacion.id)}
|
||||||
movimientos={store.getMovimientosByInternacion ? store.getMovimientosByInternacion(internacion.id) : []}
|
movimientos={store.getMovimientosByInternacion ? store.getMovimientosByInternacion(internacion.id) : []}
|
||||||
onAgregarIndicacion={(i) => store.agregarIndicacion({ ...i, internacionId: internacion.id })}
|
onAgregarIndicacion={(i) => store.agregarIndicacion({ ...i, internacionId: internacion.id })}
|
||||||
onActualizarIndicacion={store.actualizarIndicacion}
|
onActualizarIndicacion={store.actualizarIndicacion}
|
||||||
onEliminarIndicacion={store.eliminarIndicacion}
|
onEliminarIndicacion={store.eliminarIndicacion}
|
||||||
onAgregarMovimiento={(m: any) => store.agregarMovimientoIndicacion ? store.agregarMovimientoIndicacion({ ...m, internacionId: internacion.id }) : null}
|
onAgregarMovimiento={(m: MovimientoIndicacion) => store.agregarMovimientoIndicacion ? store.agregarMovimientoIndicacion({ ...m, internacionId: internacion.id }) : null}
|
||||||
onActualizarInternacion={store.actualizarInternacion}
|
onActualizarInternacion={store.actualizarInternacion}
|
||||||
onActualizarCama={store.actualizarCama}
|
onActualizarCama={store.actualizarCama}
|
||||||
onVolver={() => store.setVista('internaciones')}
|
onVolver={() => store.setVista('internaciones')}
|
||||||
@@ -212,6 +213,7 @@ function AppContent() {
|
|||||||
onAgregarCama={store.agregarCama}
|
onAgregarCama={store.agregarCama}
|
||||||
onVolver={() => store.setVista('internaciones')}
|
onVolver={() => store.setVista('internaciones')}
|
||||||
getGrupoName={(grupoId) => store.grupos.find(a => a.id === grupoId)?.nombre || ''}
|
getGrupoName={(grupoId) => store.grupos.find(a => a.id === grupoId)?.nombre || ''}
|
||||||
|
internaciones={store.internaciones}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react-refresh/only-export-components */
|
||||||
import { createContext, useContext, useEffect, useState } from "react"
|
import { createContext, useContext, useEffect, useState } from "react"
|
||||||
|
|
||||||
type Theme = "dark" | "light" | "system"
|
type Theme = "dark" | "light" | "system"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react-refresh/only-export-components */
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import { Slot } from "@radix-ui/react-slot"
|
import { Slot } from "@radix-ui/react-slot"
|
||||||
import { cva, type VariantProps } from "class-variance-authority"
|
import { cva, type VariantProps } from "class-variance-authority"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react-refresh/only-export-components */
|
||||||
import { Slot } from "@radix-ui/react-slot"
|
import { Slot } from "@radix-ui/react-slot"
|
||||||
import { cva, type VariantProps } from "class-variance-authority"
|
import { cva, type VariantProps } from "class-variance-authority"
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react-refresh/only-export-components */
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import { Slot } from "@radix-ui/react-slot"
|
import { Slot } from "@radix-ui/react-slot"
|
||||||
import { cva, type VariantProps } from "class-variance-authority"
|
import { cva, type VariantProps } from "class-variance-authority"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
|
/* eslint-disable react-refresh/only-export-components */
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import type * as LabelPrimitive from "@radix-ui/react-label"
|
import type * as LabelPrimitive from "@radix-ui/react-label"
|
||||||
import { Slot } from "@radix-ui/react-slot"
|
import { Slot } from "@radix-ui/react-slot"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react-refresh/only-export-components */
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu"
|
import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu"
|
||||||
import { cva } from "class-variance-authority"
|
import { cva } from "class-variance-authority"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
|
/* eslint-disable react-refresh/only-export-components */
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import { Slot } from "@radix-ui/react-slot"
|
import { Slot } from "@radix-ui/react-slot"
|
||||||
import { cva, type VariantProps } from "class-variance-authority"
|
import { cva, type VariantProps } from "class-variance-authority"
|
||||||
@@ -607,9 +608,7 @@ function SidebarMenuSkeleton({
|
|||||||
showIcon?: boolean
|
showIcon?: boolean
|
||||||
}) {
|
}) {
|
||||||
// Random width between 50 to 90%.
|
// Random width between 50 to 90%.
|
||||||
const width = React.useMemo(() => {
|
const width = "70%";
|
||||||
return `${Math.floor(Math.random() * 40) + 50}%`
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react-refresh/only-export-components */
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import * as TogglePrimitive from "@radix-ui/react-toggle"
|
import * as TogglePrimitive from "@radix-ui/react-toggle"
|
||||||
import { cva, type VariantProps } from "class-variance-authority"
|
import { cva, type VariantProps } from "class-variance-authority"
|
||||||
|
|||||||
+131
-80
@@ -15,9 +15,9 @@ import type {
|
|||||||
Interconsulta,
|
Interconsulta,
|
||||||
ATB,
|
ATB,
|
||||||
Indicacion,
|
Indicacion,
|
||||||
|
MovimientoIndicacion,
|
||||||
Vista,
|
Vista,
|
||||||
Usuario,
|
Usuario
|
||||||
RolUsuario
|
|
||||||
} from '@/types';
|
} from '@/types';
|
||||||
|
|
||||||
// Fallback UUID generator for non-secure contexts (HTTP without localhost)
|
// Fallback UUID generator for non-secure contexts (HTTP without localhost)
|
||||||
@@ -47,7 +47,7 @@ interface HospitalState {
|
|||||||
interconsultas: Interconsulta[];
|
interconsultas: Interconsulta[];
|
||||||
atb: ATB[];
|
atb: ATB[];
|
||||||
indicaciones: Indicacion[];
|
indicaciones: Indicacion[];
|
||||||
movimientosIndicaciones: any[];
|
movimientosIndicaciones: MovimientoIndicacion[];
|
||||||
vistaActual: Vista;
|
vistaActual: Vista;
|
||||||
currentInternacionId?: string | null;
|
currentInternacionId?: string | null;
|
||||||
usuarios: Usuario[];
|
usuarios: Usuario[];
|
||||||
@@ -108,7 +108,7 @@ export function useHospitalStore() {
|
|||||||
};
|
};
|
||||||
setState(normalized);
|
setState(normalized);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch {
|
||||||
// no remote state or unreachable — keep defaults
|
// no remote state or unreachable — keep defaults
|
||||||
} finally {
|
} finally {
|
||||||
if (mounted) setIsLoaded(true);
|
if (mounted) setIsLoaded(true);
|
||||||
@@ -118,7 +118,7 @@ export function useHospitalStore() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Helper to make API calls with error handling
|
// Helper to make API calls with error handling
|
||||||
const apiCall = useCallback(async (method: string, endpoint: string, data?: any) => {
|
const apiCall = useCallback(async (method: string, endpoint: string, data?: unknown) => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${API_BASE}${endpoint}`, {
|
const res = await fetch(`${API_BASE}${endpoint}`, {
|
||||||
method,
|
method,
|
||||||
@@ -133,11 +133,6 @@ export function useHospitalStore() {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Also save on specific events (optional)
|
|
||||||
const queueSave = (keys: string[]) => {
|
|
||||||
// Reserved for future implementation
|
|
||||||
};
|
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
const getCamaGrupoId = useCallback((camaId: string): string | null => {
|
const getCamaGrupoId = useCallback((camaId: string): string | null => {
|
||||||
const cama = state.camas.find(c => c.id === camaId);
|
const cama = state.camas.find(c => c.id === camaId);
|
||||||
@@ -196,9 +191,13 @@ export function useHospitalStore() {
|
|||||||
return (name || '').trim().toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
|
return (name || '').trim().toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
|
||||||
};
|
};
|
||||||
const userProfesionalName = getNombreProfesional(state.currentUser);
|
const userProfesionalName = getNombreProfesional(state.currentUser);
|
||||||
|
const grupoId = getInternacionGrupoId(internacionId);
|
||||||
return state.currentUser?.rol === 'admin' ||
|
return state.currentUser?.rol === 'admin' ||
|
||||||
|
state.currentUser?.rol === 'medico' ||
|
||||||
|
canAccessGrupo(grupoId) ||
|
||||||
|
!internacion.medicoIngresante ||
|
||||||
(normalizeMedicoName(internacion.medicoIngresante) === normalizeMedicoName(userProfesionalName));
|
(normalizeMedicoName(internacion.medicoIngresante) === normalizeMedicoName(userProfesionalName));
|
||||||
}, [state.internaciones, state.currentUser]);
|
}, [state.internaciones, state.currentUser, getInternacionGrupoId, canAccessGrupo]);
|
||||||
|
|
||||||
const canEditCama = useCallback((camaId: string): boolean => {
|
const canEditCama = useCallback((camaId: string): boolean => {
|
||||||
const grupoId = getCamaGrupoId(camaId);
|
const grupoId = getCamaGrupoId(camaId);
|
||||||
@@ -303,7 +302,7 @@ export function useHospitalStore() {
|
|||||||
console.error('Error al actualizar cama:', err);
|
console.error('Error al actualizar cama:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, apiCall]);
|
}, [state, apiCall]);
|
||||||
|
|
||||||
const agregarCama = useCallback(async (cama: Omit<Cama, 'id'>) => {
|
const agregarCama = useCallback(async (cama: Omit<Cama, 'id'>) => {
|
||||||
const nuevaCama: Cama = {
|
const nuevaCama: Cama = {
|
||||||
@@ -348,15 +347,18 @@ const agregarCama = useCallback(async (cama: Omit<Cama, 'id'>) => {
|
|||||||
id: generateUUID(),
|
id: generateUUID(),
|
||||||
activa: true,
|
activa: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// API call inmediata para crear internación
|
// API call inmediata para crear internación
|
||||||
await apiCall('POST', '/internaciones', nuevaInternacion);
|
await apiCall('POST', '/internaciones', nuevaInternacion);
|
||||||
|
|
||||||
// Actualizar estado de la cama en la base de datos (solo estado)
|
// Actualizar estado de la cama en la base de datos
|
||||||
|
if (internacion.camaId) {
|
||||||
await apiCall('PUT', `/camas/${internacion.camaId}`, {
|
await apiCall('PUT', `/camas/${internacion.camaId}`, {
|
||||||
estado: 'Ocupada'
|
estado: 'Ocupada',
|
||||||
|
pacienteId: internacion.pacienteId,
|
||||||
|
internacionId: nuevaInternacion.id
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Actualizar estado local después del éxito
|
// Actualizar estado local después del éxito
|
||||||
setState(prev => ({
|
setState(prev => ({
|
||||||
@@ -364,7 +366,7 @@ const agregarCama = useCallback(async (cama: Omit<Cama, 'id'>) => {
|
|||||||
internaciones: [...prev.internaciones, nuevaInternacion],
|
internaciones: [...prev.internaciones, nuevaInternacion],
|
||||||
camas: prev.camas.map(c =>
|
camas: prev.camas.map(c =>
|
||||||
c.id === internacion.camaId
|
c.id === internacion.camaId
|
||||||
? { ...c, estado: 'Ocupada' as const }
|
? { ...c, estado: 'Ocupada' as const, pacienteId: internacion.pacienteId, internacionId: nuevaInternacion.id }
|
||||||
: c
|
: c
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
@@ -374,9 +376,9 @@ const agregarCama = useCallback(async (cama: Omit<Cama, 'id'>) => {
|
|||||||
console.error('Error al crear internación:', err);
|
console.error('Error al crear internación:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [apiCall]);
|
}, [apiCall, checkGrupoPermission]);
|
||||||
|
|
||||||
const finalizarInternacion = useCallback(async (internacionId: string, datos: {
|
const finalizarInternacion = useCallback(async (internacionId: string, datos: {
|
||||||
fechaEgreso: string;
|
fechaEgreso: string;
|
||||||
diagnosticoEgreso: string;
|
diagnosticoEgreso: string;
|
||||||
motivoEgreso: Internacion['motivoEgreso']
|
motivoEgreso: Internacion['motivoEgreso']
|
||||||
@@ -401,7 +403,9 @@ const finalizarInternacion = useCallback(async (internacionId: string, datos: {
|
|||||||
} else {
|
} else {
|
||||||
// Marcar como disponible si es un área normal
|
// Marcar como disponible si es un área normal
|
||||||
await apiCall('PUT', `/camas/${camaId}`, {
|
await apiCall('PUT', `/camas/${camaId}`, {
|
||||||
estado: 'Disponible'
|
estado: 'Disponible',
|
||||||
|
pacienteId: null,
|
||||||
|
internacionId: null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -415,11 +419,11 @@ const finalizarInternacion = useCallback(async (internacionId: string, datos: {
|
|||||||
? { ...i, ...datos, activa: false }
|
? { ...i, ...datos, activa: false }
|
||||||
: i
|
: i
|
||||||
),
|
),
|
||||||
cams: esFueraDeGrupo
|
camas: esFueraDeGrupo
|
||||||
? prev.camas.filter(c => c.id !== camaId)
|
? prev.camas.filter(c => c.id !== camaId)
|
||||||
: prev.camas.map(c =>
|
: prev.camas.map(c =>
|
||||||
c.id === camaId
|
c.id === camaId
|
||||||
? { ...c, estado: 'Disponible' as const }
|
? { ...c, estado: 'Disponible' as const, pacienteId: undefined, internacionId: undefined }
|
||||||
: c
|
: c
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@@ -430,20 +434,70 @@ const finalizarInternacion = useCallback(async (internacionId: string, datos: {
|
|||||||
}
|
}
|
||||||
}, [state, apiCall]);
|
}, [state, apiCall]);
|
||||||
|
|
||||||
|
const eliminarInternacion = useCallback(async (internacionId: string) => {
|
||||||
|
const internacion = state.internaciones.find(i => i.id === internacionId);
|
||||||
|
if (!internacion) return;
|
||||||
|
const grupoId = internacion.grupoId || null;
|
||||||
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
|
console.warn('No tiene permisos para eliminar internación en esta área');
|
||||||
|
toast.error('No tiene permisos para eliminar internación en esta área');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const grupoFueraDeGrupo = state.grupos.find(a => (a.nombre || '').toLowerCase().trim() === 'fuera de grupo');
|
||||||
|
const grupoFueraDeGrupoId = grupoFueraDeGrupo?.id;
|
||||||
|
const esFueraDeGrupo = !internacion.grupoId || !grupoFueraDeGrupoId || internacion.grupoId === grupoFueraDeGrupoId;
|
||||||
|
const camaId = internacion.camaId;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await apiCall('DELETE', `/internaciones/${internacionId}`);
|
||||||
|
if (camaId) {
|
||||||
|
if (esFueraDeGrupo) {
|
||||||
|
await apiCall('DELETE', `/camas/${camaId}`);
|
||||||
|
} else {
|
||||||
|
await apiCall('PUT', `/camas/${camaId}`, {
|
||||||
|
estado: 'Disponible',
|
||||||
|
pacienteId: null,
|
||||||
|
internacionId: null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(prev => ({
|
||||||
|
...prev,
|
||||||
|
internaciones: prev.internaciones.filter(i => i.id !== internacionId),
|
||||||
|
camas: esFueraDeGrupo
|
||||||
|
? prev.camas.filter(c => c.id !== camaId)
|
||||||
|
: prev.camas.map(c =>
|
||||||
|
c.id === camaId
|
||||||
|
? { ...c, estado: 'Disponible' as const, pacienteId: undefined, internacionId: undefined }
|
||||||
|
: c
|
||||||
|
),
|
||||||
|
evoluciones: prev.evoluciones.filter(e => e.internacionId !== internacionId),
|
||||||
|
laboratorios: prev.laboratorios.filter(l => l.internacionId !== internacionId),
|
||||||
|
glucemias: prev.glucemias.filter(g => g.internacionId !== internacionId),
|
||||||
|
acidosBase: prev.acidosBase.filter(a => a.internacionId !== internacionId),
|
||||||
|
cultivos: prev.cultivos.filter(c => c.internacionId !== internacionId),
|
||||||
|
estudiosComplementarios: prev.estudiosComplementarios.filter(e => e.internacionId !== internacionId),
|
||||||
|
interconsultas: (prev.interconsultas || []).filter(ic => ic.internacionId !== internacionId),
|
||||||
|
atb: (prev.atb || []).filter(a => a.internacionId !== internacionId),
|
||||||
|
indicaciones: (prev.indicaciones || []).filter(i => i.internacionId !== internacionId),
|
||||||
|
}));
|
||||||
|
toast.success('Historia clínica de internación eliminada correctamente');
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error al eliminar internación:', err);
|
||||||
|
toast.error('Error al eliminar internación');
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const actualizarInternacion = useCallback(async (internacionId: string, datos: Partial<Internacion>) => {
|
const actualizarInternacion = useCallback(async (internacionId: string, datos: Partial<Internacion>) => {
|
||||||
const internacion = state.internaciones.find(i => i.id === internacionId);
|
const internacion = state.internaciones.find(i => i.id === internacionId);
|
||||||
if (!internacion) return;
|
if (!internacion) return;
|
||||||
|
|
||||||
// Check creator permission first
|
// Check permissions
|
||||||
const normalizeMedicoName = (name?: string) => {
|
if (!canEditIngreso(internacionId)) {
|
||||||
return (name || '').trim().toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
|
toast.error(`No tiene permisos para modificar este ingreso.`);
|
||||||
};
|
|
||||||
const userProfesionalName = getNombreProfesional(state.currentUser);
|
|
||||||
const isCreator = state.currentUser?.rol === 'admin' ||
|
|
||||||
(normalizeMedicoName(internacion.medicoIngresante) === normalizeMedicoName(userProfesionalName));
|
|
||||||
|
|
||||||
if (!isCreator) {
|
|
||||||
toast.error(`Solo el usuario que creó esta internación (${internacion.medicoIngresante}) puede modificar el ingreso.`);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,7 +539,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
? { ...i, ...datos }
|
? { ...i, ...datos }
|
||||||
: i
|
: i
|
||||||
),
|
),
|
||||||
cams: prev.camas.map(c => {
|
camas: prev.camas.map(c => {
|
||||||
if (c.id === newCamaId && newCamaId !== oldCamaId) {
|
if (c.id === newCamaId && newCamaId !== oldCamaId) {
|
||||||
return { ...c, estado: 'Ocupada' as const };
|
return { ...c, estado: 'Ocupada' as const };
|
||||||
}
|
}
|
||||||
@@ -501,7 +555,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al actualizar internación:', err);
|
console.error('Error al actualizar internación:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, canChangeBed, canEditIngreso, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
// Acciones de evoluciones
|
// Acciones de evoluciones
|
||||||
const agregarEvolucion = useCallback(async (evolucion: Omit<Evolucion, 'id'>) => {
|
const agregarEvolucion = useCallback(async (evolucion: Omit<Evolucion, 'id'>) => {
|
||||||
@@ -527,7 +581,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al agregar evolución:', err);
|
console.error('Error al agregar evolución:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const eliminarEvolucion = useCallback(async (id: string) => {
|
const eliminarEvolucion = useCallback(async (id: string) => {
|
||||||
const evolucion = state.evoluciones.find(e => e.id === id);
|
const evolucion = state.evoluciones.find(e => e.id === id);
|
||||||
@@ -549,7 +603,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al eliminar evolución:', err);
|
console.error('Error al eliminar evolución:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const actualizarEvolucion = useCallback(async (id: string, datos: Partial<Evolucion>) => {
|
const actualizarEvolucion = useCallback(async (id: string, datos: Partial<Evolucion>) => {
|
||||||
const evolucion = state.evoluciones.find(e => e.id === id);
|
const evolucion = state.evoluciones.find(e => e.id === id);
|
||||||
@@ -571,7 +625,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al actualizar evolución:', err);
|
console.error('Error al actualizar evolución:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
// Acciones de laboratorios
|
// Acciones de laboratorios
|
||||||
const agregarLaboratorio = useCallback(async (laboratorio: Omit<Laboratorio, 'id'>) => {
|
const agregarLaboratorio = useCallback(async (laboratorio: Omit<Laboratorio, 'id'>) => {
|
||||||
@@ -596,7 +650,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al agregar laboratorio:', err);
|
console.error('Error al agregar laboratorio:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const eliminarLaboratorio = useCallback(async (id: string) => {
|
const eliminarLaboratorio = useCallback(async (id: string) => {
|
||||||
const laboratorio = state.laboratorios.find(l => l.id === id);
|
const laboratorio = state.laboratorios.find(l => l.id === id);
|
||||||
@@ -617,7 +671,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al eliminar laboratorio:', err);
|
console.error('Error al eliminar laboratorio:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const actualizarLaboratorio = useCallback(async (id: string, datos: Partial<Laboratorio>) => {
|
const actualizarLaboratorio = useCallback(async (id: string, datos: Partial<Laboratorio>) => {
|
||||||
const laboratorio = state.laboratorios.find(l => l.id === id);
|
const laboratorio = state.laboratorios.find(l => l.id === id);
|
||||||
@@ -638,7 +692,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al actualizar laboratorio:', err);
|
console.error('Error al actualizar laboratorio:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
// Acciones de glucemias
|
// Acciones de glucemias
|
||||||
const agregarGlucemia = useCallback(async (glucemia: Omit<Glucemia, 'id'>) => {
|
const agregarGlucemia = useCallback(async (glucemia: Omit<Glucemia, 'id'>) => {
|
||||||
@@ -663,7 +717,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al agregar glucemia:', err);
|
console.error('Error al agregar glucemia:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const eliminarGlucemia = useCallback(async (id: string) => {
|
const eliminarGlucemia = useCallback(async (id: string) => {
|
||||||
const glucemia = state.glucemias.find(g => g.id === id);
|
const glucemia = state.glucemias.find(g => g.id === id);
|
||||||
@@ -684,7 +738,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al eliminar glucemia:', err);
|
console.error('Error al eliminar glucemia:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const actualizarGlucemia = useCallback(async (id: string, datos: Partial<Glucemia>) => {
|
const actualizarGlucemia = useCallback(async (id: string, datos: Partial<Glucemia>) => {
|
||||||
const glucemia = state.glucemias.find(g => g.id === id);
|
const glucemia = state.glucemias.find(g => g.id === id);
|
||||||
@@ -705,7 +759,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al actualizar glucemia:', err);
|
console.error('Error al actualizar glucemia:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
// Acciones de ácido-base
|
// Acciones de ácido-base
|
||||||
const agregarAcidoBase = useCallback(async (acidoBase: Omit<AcidoBase, 'id'>) => {
|
const agregarAcidoBase = useCallback(async (acidoBase: Omit<AcidoBase, 'id'>) => {
|
||||||
@@ -730,7 +784,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al agregar ácido-base:', err);
|
console.error('Error al agregar ácido-base:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const actualizarAcidoBase = useCallback(async (id: string, datos: Partial<AcidoBase>) => {
|
const actualizarAcidoBase = useCallback(async (id: string, datos: Partial<AcidoBase>) => {
|
||||||
const acidoBase = state.acidosBase.find(a => a.id === id);
|
const acidoBase = state.acidosBase.find(a => a.id === id);
|
||||||
@@ -751,7 +805,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al actualizar ácido-base:', err);
|
console.error('Error al actualizar ácido-base:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const eliminarAcidoBase = useCallback(async (id: string) => {
|
const eliminarAcidoBase = useCallback(async (id: string) => {
|
||||||
const acidoBase = state.acidosBase.find(a => a.id === id);
|
const acidoBase = state.acidosBase.find(a => a.id === id);
|
||||||
@@ -772,7 +826,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al eliminar ácido-base:', err);
|
console.error('Error al eliminar ácido-base:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
// Acciones de cultivos
|
// Acciones de cultivos
|
||||||
const agregarCultivo = useCallback(async (cultivo: Omit<Cultivo, 'id'>) => {
|
const agregarCultivo = useCallback(async (cultivo: Omit<Cultivo, 'id'>) => {
|
||||||
@@ -797,7 +851,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al agregar cultivo:', err);
|
console.error('Error al agregar cultivo:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const actualizarCultivo = useCallback(async (id: string, datos: Partial<Cultivo>) => {
|
const actualizarCultivo = useCallback(async (id: string, datos: Partial<Cultivo>) => {
|
||||||
const cultivo = state.cultivos.find(c => c.id === id);
|
const cultivo = state.cultivos.find(c => c.id === id);
|
||||||
@@ -818,7 +872,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al actualizar cultivo:', err);
|
console.error('Error al actualizar cultivo:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const eliminarCultivo = useCallback(async (id: string) => {
|
const eliminarCultivo = useCallback(async (id: string) => {
|
||||||
const cultivo = state.cultivos.find(c => c.id === id);
|
const cultivo = state.cultivos.find(c => c.id === id);
|
||||||
@@ -839,7 +893,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al eliminar cultivo:', err);
|
console.error('Error al eliminar cultivo:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
// Acciones de estudios complementarios
|
// Acciones de estudios complementarios
|
||||||
const agregarEstudioComplementario = useCallback(async (estudio: Omit<EstudioComplementario, 'id'>) => {
|
const agregarEstudioComplementario = useCallback(async (estudio: Omit<EstudioComplementario, 'id'>) => {
|
||||||
@@ -864,7 +918,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al agregar estudio:', err);
|
console.error('Error al agregar estudio:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const actualizarEstudioComplementario = useCallback(async (id: string, datos: Partial<EstudioComplementario>) => {
|
const actualizarEstudioComplementario = useCallback(async (id: string, datos: Partial<EstudioComplementario>) => {
|
||||||
const estudio = state.estudiosComplementarios.find(e => e.id === id);
|
const estudio = state.estudiosComplementarios.find(e => e.id === id);
|
||||||
@@ -885,7 +939,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al actualizar estudio:', err);
|
console.error('Error al actualizar estudio:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const eliminarEstudioComplementario = useCallback(async (id: string) => {
|
const eliminarEstudioComplementario = useCallback(async (id: string) => {
|
||||||
const estudio = state.estudiosComplementarios.find(e => e.id === id);
|
const estudio = state.estudiosComplementarios.find(e => e.id === id);
|
||||||
@@ -906,7 +960,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al eliminar estudio:', err);
|
console.error('Error al eliminar estudio:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
// Acciones de interconsultas
|
// Acciones de interconsultas
|
||||||
const agregarInterconsulta = useCallback(async (interconsulta: Omit<Interconsulta, 'id'>) => {
|
const agregarInterconsulta = useCallback(async (interconsulta: Omit<Interconsulta, 'id'>) => {
|
||||||
@@ -928,7 +982,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al agregar interconsulta:', err);
|
console.error('Error al agregar interconsulta:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const actualizarInterconsulta = useCallback(async (id: string, datos: Partial<Interconsulta>) => {
|
const actualizarInterconsulta = useCallback(async (id: string, datos: Partial<Interconsulta>) => {
|
||||||
const interconsulta = (state.interconsultas || []).find(ic => ic.id === id);
|
const interconsulta = (state.interconsultas || []).find(ic => ic.id === id);
|
||||||
@@ -949,7 +1003,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al actualizar interconsulta:', err);
|
console.error('Error al actualizar interconsulta:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const eliminarInterconsulta = useCallback(async (id: string) => {
|
const eliminarInterconsulta = useCallback(async (id: string) => {
|
||||||
const interconsulta = (state.interconsultas || []).find(ic => ic.id === id);
|
const interconsulta = (state.interconsultas || []).find(ic => ic.id === id);
|
||||||
@@ -970,7 +1024,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al eliminar interconsulta:', err);
|
console.error('Error al eliminar interconsulta:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const agregarATB = useCallback(async (atb: Omit<ATB, 'id'>) => {
|
const agregarATB = useCallback(async (atb: Omit<ATB, 'id'>) => {
|
||||||
const internacion = state.internaciones.find(i => i.id === atb.internacionId);
|
const internacion = state.internaciones.find(i => i.id === atb.internacionId);
|
||||||
@@ -991,7 +1045,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al agregar ATB:', err);
|
console.error('Error al agregar ATB:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const actualizarATB = useCallback(async (id: string, datos: Partial<ATB>) => {
|
const actualizarATB = useCallback(async (id: string, datos: Partial<ATB>) => {
|
||||||
const atb = state.atb.find(a => a.id === id);
|
const atb = state.atb.find(a => a.id === id);
|
||||||
@@ -1012,7 +1066,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al actualizar ATB:', err);
|
console.error('Error al actualizar ATB:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const eliminarATB = useCallback(async (id: string) => {
|
const eliminarATB = useCallback(async (id: string) => {
|
||||||
const atb = state.atb.find(a => a.id === id);
|
const atb = state.atb.find(a => a.id === id);
|
||||||
@@ -1033,7 +1087,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al eliminar ATB:', err);
|
console.error('Error al eliminar ATB:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const agregarIndicacion = useCallback(async (indicacion: Omit<Indicacion, 'id'>) => {
|
const agregarIndicacion = useCallback(async (indicacion: Omit<Indicacion, 'id'>) => {
|
||||||
const internacion = state.internaciones.find(i => i.id === indicacion.internacionId);
|
const internacion = state.internaciones.find(i => i.id === indicacion.internacionId);
|
||||||
@@ -1054,7 +1108,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al agregar indicación:', err);
|
console.error('Error al agregar indicación:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state.internaciones, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state.internaciones, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const actualizarIndicacion = useCallback(async (id: string, datos: Partial<Indicacion>) => {
|
const actualizarIndicacion = useCallback(async (id: string, datos: Partial<Indicacion>) => {
|
||||||
const indicacion = state.indicaciones.find(i => i.id === id);
|
const indicacion = state.indicaciones.find(i => i.id === id);
|
||||||
@@ -1075,7 +1129,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al actualizar indicación:', err);
|
console.error('Error al actualizar indicación:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state.indicaciones, state.internaciones, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state.indicaciones, state.internaciones, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const eliminarIndicacion = useCallback(async (id: string) => {
|
const eliminarIndicacion = useCallback(async (id: string) => {
|
||||||
const indicacion = state.indicaciones.find(i => i.id === id);
|
const indicacion = state.indicaciones.find(i => i.id === id);
|
||||||
@@ -1096,9 +1150,9 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al eliminar indicación:', err);
|
console.error('Error al eliminar indicación:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state.indicaciones, state.internaciones, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state.indicaciones, state.internaciones, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const agregarMovimientoIndicacion = useCallback(async (movimiento: any) => {
|
const agregarMovimientoIndicacion = useCallback(async (movimiento: MovimientoIndicacion) => {
|
||||||
const internacion = state.internaciones.find(i => i.id === movimiento.internacionId);
|
const internacion = state.internaciones.find(i => i.id === movimiento.internacionId);
|
||||||
const grupoId = internacion?.grupoId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkGrupoPermission(grupoId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
@@ -1116,12 +1170,12 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
console.error('Error al agregar movimiento:', err);
|
console.error('Error al agregar movimiento:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
}, [state, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const getMovimientosByInternacion = useCallback((internacionId: string) => {
|
const getMovimientosByInternacion = useCallback((internacionId: string) => {
|
||||||
return (state.movimientosIndicaciones || [])
|
return (state.movimientosIndicaciones || [])
|
||||||
.filter((m: any) => m.internacionId === internacionId)
|
.filter((m: MovimientoIndicacion) => m.internacionId === internacionId)
|
||||||
.sort((a: any, b: any) => new Date(b.fecha).getTime() - new Date(a.fecha).getTime());
|
.sort((a: MovimientoIndicacion, b: MovimientoIndicacion) => new Date(b.fecha).getTime() - new Date(a.fecha).getTime());
|
||||||
}, [state.movimientosIndicaciones]);
|
}, [state.movimientosIndicaciones]);
|
||||||
|
|
||||||
// Acciones de grupos
|
// Acciones de grupos
|
||||||
@@ -1190,27 +1244,27 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
.sort((a, b) => new Date(b.fecha + 'T' + b.hora).getTime() - new Date(a.fecha + 'T' + a.hora).getTime());
|
.sort((a, b) => new Date(b.fecha + 'T' + b.hora).getTime() - new Date(a.fecha + 'T' + a.hora).getTime());
|
||||||
}, [state.evoluciones]);
|
}, [state.evoluciones]);
|
||||||
|
|
||||||
const getLaboratoriosByPaciente = useCallback((pacienteId: string) => {
|
const getLaboratoriosByInternacion = useCallback((internacionId: string) => {
|
||||||
return state.laboratorios
|
return state.laboratorios
|
||||||
.filter(l => l.pacienteId === pacienteId)
|
.filter(l => l.internacionId === internacionId)
|
||||||
.sort((a, b) => new Date(b.fecha).getTime() - new Date(a.fecha).getTime());
|
.sort((a, b) => new Date(b.fecha).getTime() - new Date(a.fecha).getTime());
|
||||||
}, [state.laboratorios]);
|
}, [state.laboratorios]);
|
||||||
|
|
||||||
const getGlucemiasByPaciente = useCallback((pacienteId: string) => {
|
const getGlucemiasByInternacion = useCallback((internacionId: string) => {
|
||||||
return state.glucemias
|
return state.glucemias
|
||||||
.filter(g => g.pacienteId === pacienteId)
|
.filter(g => g.internacionId === internacionId)
|
||||||
.sort((a, b) => new Date(b.fecha + 'T' + (b.hora || '00:00')).getTime() - new Date(a.fecha + 'T' + (a.hora || '00:00')).getTime());
|
.sort((a, b) => new Date(b.fecha + 'T' + (b.hora || '00:00')).getTime() - new Date(a.fecha + 'T' + (a.hora || '00:00')).getTime());
|
||||||
}, [state.glucemias]);
|
}, [state.glucemias]);
|
||||||
|
|
||||||
const getAcidosBaseByPaciente = useCallback((pacienteId: string) => {
|
const getAcidosBaseByInternacion = useCallback((internacionId: string) => {
|
||||||
return state.acidosBase
|
return state.acidosBase
|
||||||
.filter(a => a.pacienteId === pacienteId)
|
.filter(a => a.internacionId === internacionId)
|
||||||
.sort((a, b) => new Date(b.fecha + 'T' + b.hora).getTime() - new Date(a.fecha + 'T' + a.hora).getTime());
|
.sort((a, b) => new Date(b.fecha + 'T' + b.hora).getTime() - new Date(a.fecha + 'T' + a.hora).getTime());
|
||||||
}, [state.acidosBase]);
|
}, [state.acidosBase]);
|
||||||
|
|
||||||
const getCultivosByPaciente = useCallback((pacienteId: string) => {
|
const getCultivosByInternacion = useCallback((internacionId: string) => {
|
||||||
return state.cultivos
|
return state.cultivos
|
||||||
.filter(c => c.pacienteId === pacienteId)
|
.filter(c => c.internacionId === internacionId)
|
||||||
.sort((a, b) => new Date(b.fechaToma).getTime() - new Date(a.fechaToma).getTime());
|
.sort((a, b) => new Date(b.fechaToma).getTime() - new Date(a.fechaToma).getTime());
|
||||||
}, [state.cultivos]);
|
}, [state.cultivos]);
|
||||||
|
|
||||||
@@ -1247,7 +1301,6 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
|
|
||||||
// Auth functions
|
// Auth functions
|
||||||
const login = useCallback(async (dni: string, password: string) => {
|
const login = useCallback(async (dni: string, password: string) => {
|
||||||
try {
|
|
||||||
const res = await fetch(`${API_BASE}/auth/login`, {
|
const res = await fetch(`${API_BASE}/auth/login`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
@@ -1261,9 +1314,6 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
sessionStorage.setItem('hospital_user', JSON.stringify(user));
|
sessionStorage.setItem('hospital_user', JSON.stringify(user));
|
||||||
setState(prev => ({ ...prev, currentUser: user, isAuthenticated: true }));
|
setState(prev => ({ ...prev, currentUser: user, isAuthenticated: true }));
|
||||||
return user;
|
return user;
|
||||||
} catch (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const logout = useCallback(() => {
|
const logout = useCallback(() => {
|
||||||
@@ -1311,6 +1361,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
iniciarInternacion,
|
iniciarInternacion,
|
||||||
finalizarInternacion,
|
finalizarInternacion,
|
||||||
actualizarInternacion,
|
actualizarInternacion,
|
||||||
|
eliminarInternacion,
|
||||||
agregarCama,
|
agregarCama,
|
||||||
eliminarCama,
|
eliminarCama,
|
||||||
agregarEvolucion,
|
agregarEvolucion,
|
||||||
@@ -1350,10 +1401,10 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
getInternacionById,
|
getInternacionById,
|
||||||
getInternacionActivaByPaciente,
|
getInternacionActivaByPaciente,
|
||||||
getEvolucionesByInternacion,
|
getEvolucionesByInternacion,
|
||||||
getLaboratoriosByPaciente,
|
getLaboratoriosByInternacion,
|
||||||
getGlucemiasByPaciente,
|
getGlucemiasByInternacion,
|
||||||
getAcidosBaseByPaciente,
|
getAcidosBaseByInternacion,
|
||||||
getCultivosByPaciente,
|
getCultivosByInternacion,
|
||||||
setCurrentInternacion,
|
setCurrentInternacion,
|
||||||
getEstadisticas,
|
getEstadisticas,
|
||||||
login,
|
login,
|
||||||
|
|||||||
+1
-2
@@ -40,8 +40,7 @@ export function calcularEdad(fechaNacimiento?: string): string | number {
|
|||||||
|
|
||||||
|
|
||||||
export function isCamaFueraDeGrupo(
|
export function isCamaFueraDeGrupo(
|
||||||
cama: { numero: string; grupoId?: string; areaId?: string; sector?: string },
|
cama: { numero: string; grupoId?: string; areaId?: string; sector?: string }
|
||||||
_gruposOrAreas?: { id: string; nombre: string }[]
|
|
||||||
): boolean {
|
): boolean {
|
||||||
if (cama.sector === 'Fuera de Área') return true;
|
if (cama.sector === 'Fuera de Área') return true;
|
||||||
if (cama.sector === 'En Área') return false;
|
if (cama.sector === 'En Área') return false;
|
||||||
|
|||||||
@@ -181,10 +181,6 @@ export function Cultivos({
|
|||||||
setDialogoDefinitivoAbierto(false);
|
setDialogoDefinitivoAbierto(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getNumeroCama = (pacienteId: string) => {
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="flex flex-col sm:flex-row gap-4 items-start sm:items-center justify-between">
|
<div className="flex flex-col sm:flex-row gap-4 items-start sm:items-center justify-between">
|
||||||
@@ -198,7 +194,7 @@ export function Cultivos({
|
|||||||
className="pl-8"
|
className="pl-8"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Select value={filtroEstado} onValueChange={(v) => setFiltroEstado(v as any)}>
|
<Select value={filtroEstado} onValueChange={(v) => setFiltroEstado(v as Cultivo['estado'] | 'todos')}>
|
||||||
<SelectTrigger className="w-[180px]">
|
<SelectTrigger className="w-[180px]">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
@@ -410,7 +406,7 @@ export function Cultivos({
|
|||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Tipo de Muestra</Label>
|
<Label>Tipo de Muestra</Label>
|
||||||
<Select value={tipoMuestra} onValueChange={(v) => setTipoMuestra(v as any)}>
|
<Select value={tipoMuestra} onValueChange={(v) => setTipoMuestra(v as Cultivo['tipoMuestra'])}>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
@@ -485,7 +481,7 @@ export function Cultivos({
|
|||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Estado</Label>
|
<Label>Estado</Label>
|
||||||
<Select value={estadoResultado} onValueChange={(v) => setEstadoResultado(v as any)}>
|
<Select value={estadoResultado} onValueChange={(v) => setEstadoResultado(v as Cultivo['estado'])}>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Save, X, Bed, Stethoscope, User, Loader2 } from 'lucide-react';
|
import { Save, X, Bed, Stethoscope, User, Loader2, ClipboardList } from 'lucide-react';
|
||||||
import { Card, CardContent } from '@/components/ui/card';
|
import { Card, CardContent } from '@/components/ui/card';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
@@ -32,12 +32,14 @@ export function EditIngreso({
|
|||||||
onActualizarInternacion,
|
onActualizarInternacion,
|
||||||
onAgregarCama,
|
onAgregarCama,
|
||||||
onVolver,
|
onVolver,
|
||||||
|
getGrupoName,
|
||||||
}: EditIngresoProps) {
|
}: EditIngresoProps) {
|
||||||
const { currentUser } = useHospitalStore();
|
const { currentUser } = useHospitalStore();
|
||||||
const [pacienteSeleccionado] = useState(internacion.pacienteId);
|
const [pacienteSeleccionado] = useState(internacion.pacienteId);
|
||||||
const [camaSeleccionada] = useState(internacion.camaId);
|
const [camaSeleccionada, setCamaSeleccionada] = useState(internacion.camaId);
|
||||||
const [grupoSeleccionada] = useState(internacion.grupoId);
|
const [grupoSeleccionada] = useState(internacion.grupoId);
|
||||||
const [camaInput, setCamaInput] = useState('');
|
const [camaInput, setCamaInput] = useState('');
|
||||||
|
const [busqueda, setBusqueda] = useState('');
|
||||||
const [modoCama, setModoCama] = useState<'seleccionar' | 'escribir'>('seleccionar');
|
const [modoCama, setModoCama] = useState<'seleccionar' | 'escribir'>('seleccionar');
|
||||||
const effectiveMedico = getNombreProfesional(currentUser);
|
const effectiveMedico = getNombreProfesional(currentUser);
|
||||||
const [fechaIngresoHospital, setFechaIngresoHospital] = useState(internacion.fechaIngresoHospital || '');
|
const [fechaIngresoHospital, setFechaIngresoHospital] = useState(internacion.fechaIngresoHospital || '');
|
||||||
|
|||||||
@@ -203,17 +203,6 @@ export function Evoluciones({
|
|||||||
})
|
})
|
||||||
.sort((a, b) => new Date(b.fecha + 'T' + b.hora).getTime() - new Date(a.fecha + 'T' + a.hora).getTime());
|
.sort((a, b) => new Date(b.fecha + 'T' + b.hora).getTime() - new Date(a.fecha + 'T' + a.hora).getTime());
|
||||||
|
|
||||||
const getSignosVitalesTexto = (sv: SignosVitales | undefined) => {
|
|
||||||
if (!sv) return null;
|
|
||||||
const partes: string[] = [];
|
|
||||||
if (sv.presionSistolica && sv.presionDiastolica) partes.push(`PA: ${sv.presionSistolica}/${sv.presionDiastolica}`);
|
|
||||||
if (sv.frecuenciaCardiaca) partes.push(`FC: ${sv.frecuenciaCardiaca}`);
|
|
||||||
if (sv.frecuenciaRespiratoria) partes.push(`FR: ${sv.frecuenciaRespiratoria}`);
|
|
||||||
if (sv.temperatura) partes.push(`T: ${sv.temperatura}°C`);
|
|
||||||
if (sv.saturacionO2) partes.push(`SatO2: ${sv.saturacionO2}%`);
|
|
||||||
return partes.join(' | ');
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6 dark:text-white overflow-x-hidden max-w-screen">
|
<div className="space-y-6 dark:text-white overflow-x-hidden max-w-screen">
|
||||||
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
|
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { PDFDocument } from 'pdf-lib';
|
|
||||||
import { User } from 'lucide-react';
|
import { User } from 'lucide-react';
|
||||||
import { useHospitalStore } from '@/hooks/useHospitalStore';
|
import { useHospitalStore } from '@/hooks/useHospitalStore';
|
||||||
import { getNombreProfesional } from '@/lib/utils';
|
import { getNombreProfesional } from '@/lib/utils';
|
||||||
@@ -17,15 +16,12 @@ import {
|
|||||||
Plus,
|
Plus,
|
||||||
Calendar,
|
Calendar,
|
||||||
Droplet,
|
Droplet,
|
||||||
Clock,
|
|
||||||
AlertCircle,
|
AlertCircle,
|
||||||
CheckCircle2,
|
CheckCircle2,
|
||||||
ArrowLeft,
|
ArrowLeft,
|
||||||
Pencil,
|
Pencil,
|
||||||
Trash2,
|
Trash2,
|
||||||
FileText,
|
FileText,
|
||||||
ChevronDown,
|
|
||||||
ChevronUp,
|
|
||||||
List,
|
List,
|
||||||
FileDown,
|
FileDown,
|
||||||
Thermometer,
|
Thermometer,
|
||||||
@@ -39,7 +35,6 @@ import {
|
|||||||
Edit,
|
Edit,
|
||||||
ClipboardList,
|
ClipboardList,
|
||||||
TrendingUp,
|
TrendingUp,
|
||||||
TypeOutline,
|
|
||||||
Activity,
|
Activity,
|
||||||
Pill,
|
Pill,
|
||||||
Users
|
Users
|
||||||
@@ -49,14 +44,14 @@ import { Badge } from '@/components/ui/badge';
|
|||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { Label } from '@/components/ui/label';
|
import { Label } from '@/components/ui/label';
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||||
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"
|
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
|
||||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
||||||
import type { Laboratorio, Glucemia, AcidoBase, Cultivo, Paciente, ResultadoLaboratorio, Internacion, Evolucion, Cama, EstudioComplementario, Interconsulta, ATB, Indicacion } from '@/types';
|
import type { Laboratorio, Glucemia, AcidoBase, Cultivo, Paciente, ResultadoLaboratorio, Internacion, Evolucion, Cama, EstudioComplementario, Interconsulta, ATB, Indicacion, MovimientoIndicacion } from '@/types';
|
||||||
import { formatDateDDMMYYYY } from '@/lib/utils';
|
import { formatDateDDMMYYYY } from '@/lib/utils';
|
||||||
import { SeccionIndicaciones } from './SeccionIndicaciones';
|
import { SeccionIndicaciones } from './SeccionIndicaciones';
|
||||||
|
|
||||||
@@ -64,7 +59,6 @@ interface HistoriaClinicaProps {
|
|||||||
internacion: Internacion;
|
internacion: Internacion;
|
||||||
paciente: Paciente;
|
paciente: Paciente;
|
||||||
cama?: Cama;
|
cama?: Cama;
|
||||||
allCamas?: Cama[];
|
|
||||||
evoluciones: Evolucion[];
|
evoluciones: Evolucion[];
|
||||||
laboratorios: Laboratorio[];
|
laboratorios: Laboratorio[];
|
||||||
glucemias: Glucemia[];
|
glucemias: Glucemia[];
|
||||||
@@ -74,7 +68,7 @@ interface HistoriaClinicaProps {
|
|||||||
interconsultas: Interconsulta[];
|
interconsultas: Interconsulta[];
|
||||||
atb: ATB[];
|
atb: ATB[];
|
||||||
indicadores: Indicacion[];
|
indicadores: Indicacion[];
|
||||||
movimientos?: any[];
|
movimientos?: MovimientoIndicacion[];
|
||||||
canEdit: boolean;
|
canEdit: boolean;
|
||||||
onAgregarEvolucion: (evolucion: Omit<Evolucion, 'id'>) => void;
|
onAgregarEvolucion: (evolucion: Omit<Evolucion, 'id'>) => void;
|
||||||
onActualizarEvolucion: (id: string, datos: Partial<Evolucion>) => void;
|
onActualizarEvolucion: (id: string, datos: Partial<Evolucion>) => void;
|
||||||
@@ -104,33 +98,11 @@ interface HistoriaClinicaProps {
|
|||||||
onAgregarIndicacion: (indicacion: Omit<Indicacion, 'id'>) => void;
|
onAgregarIndicacion: (indicacion: Omit<Indicacion, 'id'>) => void;
|
||||||
onActualizarIndicacion: (id: string, datos: Partial<Indicacion>) => void;
|
onActualizarIndicacion: (id: string, datos: Partial<Indicacion>) => void;
|
||||||
onEliminarIndicacion: (id: string) => void;
|
onEliminarIndicacion: (id: string) => void;
|
||||||
onAgregarMovimiento?: (movimiento: any) => void;
|
onAgregarMovimiento?: (movimiento: MovimientoIndicacion) => void;
|
||||||
onActualizarInternacion: (id: string, datos: Partial<Internacion>) => void;
|
|
||||||
onActualizarCama: (id: string, datos: Partial<Cama>) => void;
|
|
||||||
onVolver: () => void;
|
onVolver: () => void;
|
||||||
onEditarIngreso?: () => void;
|
onEditarIngreso?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PARAMETROS_COMUNES: Record<string, { unidad: string; referencia: string }> = {
|
|
||||||
'Hemoglobina': { unidad: 'g/dL', referencia: '12-14' },
|
|
||||||
'Hematocrito': { unidad: '%', referencia: '36-42' },
|
|
||||||
'Glóbulos Blancos': { unidad: 'cel/μL', referencia: '4000-11000' },
|
|
||||||
'Plaquetas': { unidad: 'unidades/μL', referencia: '150000-400000' },
|
|
||||||
'Glucosa': { unidad: 'mg/dL', referencia: '70-100' },
|
|
||||||
'Urea': { unidad: 'mg/dL', referencia: '17-48.5' },
|
|
||||||
'Creatinina': { unidad: 'mg/dL', referencia: '0.5-1' },
|
|
||||||
'Sodio': { unidad: 'mEq/L', referencia: '135-145' },
|
|
||||||
'Potasio': { unidad: 'mEq/L', referencia: '3.5-5.1' },
|
|
||||||
'Cloro': { unidad: 'mEq/L', referencia: '101-109' },
|
|
||||||
'Bilirrubina Total': { unidad: 'mg/dL', referencia: '0-1.2' },
|
|
||||||
'Bilirrubina Directa': { unidad: 'mg/dL', referencia: '0-0.3' },
|
|
||||||
'TGO/AST': { unidad: 'U/L', referencia: '0-35' },
|
|
||||||
'TGP/ALT': { unidad: 'U/L', referencia: '0-35' },
|
|
||||||
'TP': { unidad: '%', referencia: '70-100' },
|
|
||||||
'KPTT': { unidad: 'seg', referencia: '30-45' },
|
|
||||||
'RIN': { unidad: '', referencia: '0.8-1.5' },
|
|
||||||
};
|
|
||||||
|
|
||||||
const RANGOS_LABORATORIO: Record<string, { min: number; max: number }> = {
|
const RANGOS_LABORATORIO: Record<string, { min: number; max: number }> = {
|
||||||
'Hematocrito': { min: 36, max: 42 },
|
'Hematocrito': { min: 36, max: 42 },
|
||||||
'Hemoglobina': { min: 12, max: 14 },
|
'Hemoglobina': { min: 12, max: 14 },
|
||||||
@@ -201,7 +173,7 @@ function calcularEstadoLaboratorio(parametro: string, valor: string): 'Normal' |
|
|||||||
return 'Normal';
|
return 'Normal';
|
||||||
}
|
}
|
||||||
|
|
||||||
function wrapText(text: string, font: any, fontSize: number, maxWidth: number): string[] {
|
function wrapText(text: string, font: { widthOfTextAtSize: (text: string, size: number) => number }, fontSize: number, maxWidth: number): string[] {
|
||||||
const words = text.split(' ');
|
const words = text.split(' ');
|
||||||
const lines: string[] = [];
|
const lines: string[] = [];
|
||||||
let currentLine = '';
|
let currentLine = '';
|
||||||
@@ -226,7 +198,6 @@ export function HistoriaClinica({
|
|||||||
internacion,
|
internacion,
|
||||||
paciente,
|
paciente,
|
||||||
cama,
|
cama,
|
||||||
allCamas,
|
|
||||||
evoluciones,
|
evoluciones,
|
||||||
laboratorios,
|
laboratorios,
|
||||||
glucemias,
|
glucemias,
|
||||||
@@ -265,8 +236,6 @@ export function HistoriaClinica({
|
|||||||
onEliminarIndicacion,
|
onEliminarIndicacion,
|
||||||
movimientos,
|
movimientos,
|
||||||
onAgregarMovimiento,
|
onAgregarMovimiento,
|
||||||
onActualizarInternacion,
|
|
||||||
onActualizarCama,
|
|
||||||
onVolver,
|
onVolver,
|
||||||
onEditarIngreso,
|
onEditarIngreso,
|
||||||
canEdit,
|
canEdit,
|
||||||
@@ -590,11 +559,11 @@ export function HistoriaClinica({
|
|||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
|
|
||||||
<TabsContent value="glucemias" className="mt-4 min-w-0 w-full overflow-hidden">
|
<TabsContent value="glucemias" className="mt-4 min-w-0 w-full overflow-hidden">
|
||||||
<SeccionGlucemias glucemias={glucemias} patientId={paciente.id} add={onAgregarGlucemia} update={onActualizarGlucemia} del={onEliminarGlucemia} canEdit={canEdit} />
|
<SeccionGlucemias glucemias={glucemias} patientId={paciente.id} internacionId={internacion.id} add={onAgregarGlucemia} update={onActualizarGlucemia} del={onEliminarGlucemia} canEdit={canEdit} />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="laboratorios" className="mt-4 min-w-0 w-full overflow-hidden">
|
<TabsContent value="laboratorios" className="mt-4 min-w-0 w-full overflow-hidden">
|
||||||
<SeccionLaboratorios lab={laboratorios} patientId={paciente.id} add={onAgregarLaboratorio} update={onActualizarLaboratorio} del={onEliminarLaboratorio} addAcidoBase={onAgregarAcidoBase} canEdit={canEdit} />
|
<SeccionLaboratorios lab={laboratorios} patientId={paciente.id} internacionId={internacion.id} add={onAgregarLaboratorio} update={onActualizarLaboratorio} del={onEliminarLaboratorio} addAcidoBase={onAgregarAcidoBase} canEdit={canEdit} />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="evoluciones" className="mt-4">
|
<TabsContent value="evoluciones" className="mt-4">
|
||||||
@@ -602,11 +571,11 @@ export function HistoriaClinica({
|
|||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="acidobase" className="mt-4">
|
<TabsContent value="acidobase" className="mt-4">
|
||||||
<SeccionAcidosBase ab={acidosBase} patientId={paciente.id} add={onAgregarAcidoBase} update={onActualizarAcidoBase} del={onEliminarAcidoBase} canEdit={canEdit} />
|
<SeccionAcidosBase ab={acidosBase} patientId={paciente.id} internacionId={internacion.id} add={onAgregarAcidoBase} update={onActualizarAcidoBase} del={onEliminarAcidoBase} canEdit={canEdit} />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="cultivos" className="mt-4">
|
<TabsContent value="cultivos" className="mt-4">
|
||||||
<SeccionCultivos cults={cultivos} patient={paciente} add={onAgregarCultivo} update={onActualizarCultivo} del={onEliminarCultivo} canEdit={canEdit} />
|
<SeccionCultivos cults={cultivos} patient={paciente} internacionId={internacion.id} add={onAgregarCultivo} update={onActualizarCultivo} del={onEliminarCultivo} canEdit={canEdit} />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="atb" className="mt-4">
|
<TabsContent value="atb" className="mt-4">
|
||||||
@@ -668,9 +637,10 @@ export function HistoriaClinica({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function SeccionGlucemias({ glucemias, patientId, add, update, del, canEdit }: {
|
function SeccionGlucemias({ glucemias, patientId, internacionId, add, update, del, canEdit }: {
|
||||||
glucemias: Glucemia[];
|
glucemias: Glucemia[];
|
||||||
patientId: string;
|
patientId: string;
|
||||||
|
internacionId: string;
|
||||||
add: (g: Omit<Glucemia, 'id'>) => void;
|
add: (g: Omit<Glucemia, 'id'>) => void;
|
||||||
update: (id: string, data: Partial<Glucemia>) => void;
|
update: (id: string, data: Partial<Glucemia>) => void;
|
||||||
del: (id: string) => void;
|
del: (id: string) => void;
|
||||||
@@ -725,6 +695,7 @@ function SeccionGlucemias({ glucemias, patientId, add, update, del, canEdit }: {
|
|||||||
} else {
|
} else {
|
||||||
add({
|
add({
|
||||||
pacienteId: patientId,
|
pacienteId: patientId,
|
||||||
|
internacionId,
|
||||||
fecha,
|
fecha,
|
||||||
hora,
|
hora,
|
||||||
valor: valNum,
|
valor: valNum,
|
||||||
@@ -926,9 +897,10 @@ function SeccionGlucemias({ glucemias, patientId, add, update, del, canEdit }: {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function SeccionLaboratorios({ lab, patientId, add, update, del, addAcidoBase, canEdit }: {
|
function SeccionLaboratorios({ lab, patientId, internacionId, add, update, del, addAcidoBase, canEdit }: {
|
||||||
lab: Laboratorio[];
|
lab: Laboratorio[];
|
||||||
patientId: string;
|
patientId: string;
|
||||||
|
internacionId: string;
|
||||||
add: (l: Omit<Laboratorio, 'id'>) => void;
|
add: (l: Omit<Laboratorio, 'id'>) => void;
|
||||||
update: (id: string, data: Partial<Laboratorio>) => void;
|
update: (id: string, data: Partial<Laboratorio>) => void;
|
||||||
del: (id: string) => void;
|
del: (id: string) => void;
|
||||||
@@ -938,13 +910,11 @@ function SeccionLaboratorios({ lab, patientId, add, update, del, addAcidoBase, c
|
|||||||
const [dialog, setDialog] = useState(false);
|
const [dialog, setDialog] = useState(false);
|
||||||
const [obsDialog, setObsDialog] = useState(false);
|
const [obsDialog, setObsDialog] = useState(false);
|
||||||
const [evolDialog, setEvolDialog] = useState(false);
|
const [evolDialog, setEvolDialog] = useState(false);
|
||||||
const [selectedLab, setSelectedLab] = useState<Laboratorio | null>(null);
|
|
||||||
const [edit, setEdit] = useState<Laboratorio | null>(null);
|
const [edit, setEdit] = useState<Laboratorio | null>(null);
|
||||||
const [obsLab, setObsLab] = useState<Laboratorio | null>(null);
|
const [obsLab, setObsLab] = useState<Laboratorio | null>(null);
|
||||||
const [fecha, setFecha] = useState(new Date().toISOString().split('T')[0]);
|
const [fecha, setFecha] = useState(new Date().toISOString().split('T')[0]);
|
||||||
const [hora, setHora] = useState(new Date().toTimeString().slice(0, 5));
|
const [hora, setHora] = useState(new Date().toTimeString().slice(0, 5));
|
||||||
const [observaciones, setObservaciones] = useState('');
|
const [observaciones, setObservaciones] = useState('');
|
||||||
const [resultados, setResultados] = useState<ResultadoLaboratorio[]>([]);
|
|
||||||
const [hto, setHto] = useState('');
|
const [hto, setHto] = useState('');
|
||||||
const [hb, setHb] = useState('');
|
const [hb, setHb] = useState('');
|
||||||
const [gb, setGb] = useState('');
|
const [gb, setGb] = useState('');
|
||||||
@@ -988,13 +958,6 @@ function SeccionLaboratorios({ lab, patientId, add, update, del, addAcidoBase, c
|
|||||||
return { fecha: l.fecha, valor: r ? parseFloat(String(r.valor)) : null };
|
return { fecha: l.fecha, valor: r ? parseFloat(String(r.valor)) : null };
|
||||||
});
|
});
|
||||||
|
|
||||||
const getEstadoColor = (estado: ResultadoLaboratorio['estado']) => {
|
|
||||||
switch (estado) {
|
|
||||||
case 'Normal': return 'bg-green-100 text-green-800';
|
|
||||||
case 'Alto': case 'Bajo': case 'Crítico': return 'bg-red-100 text-red-800';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const getValor = (l: Laboratorio, param: string) => {
|
const getValor = (l: Laboratorio, param: string) => {
|
||||||
const r = l.resultados.find(r => r.parametro === param);
|
const r = l.resultados.find(r => r.parametro === param);
|
||||||
return r ? `${r.valor}` : '-';
|
return r ? `${r.valor}` : '-';
|
||||||
@@ -1357,7 +1320,7 @@ function SeccionLaboratorios({ lab, patientId, add, update, del, addAcidoBase, c
|
|||||||
if (importResultados.length === 0 && !importObservaciones && !importAcidoBase) return;
|
if (importResultados.length === 0 && !importObservaciones && !importAcidoBase) return;
|
||||||
|
|
||||||
if (importAcidoBase) {
|
if (importAcidoBase) {
|
||||||
addAcidoBase({ ...importAcidoBase, fecha: importFecha, hora: importHora });
|
addAcidoBase({ ...importAcidoBase, pacienteId: patientId, internacionId, fecha: importFecha, hora: importHora });
|
||||||
}
|
}
|
||||||
|
|
||||||
add({
|
add({
|
||||||
@@ -1407,7 +1370,7 @@ function SeccionLaboratorios({ lab, patientId, add, update, del, addAcidoBase, c
|
|||||||
if (edit) {
|
if (edit) {
|
||||||
update(edit.id, { fecha, hora, resultados: resultadosLaboratorio, observaciones });
|
update(edit.id, { fecha, hora, resultados: resultadosLaboratorio, observaciones });
|
||||||
} else {
|
} else {
|
||||||
add({ pacienteId: patientId || '', fecha, hora, resultados: resultadosLaboratorio, observaciones });
|
add({ pacienteId: patientId || '', internacionId, fecha, hora, resultados: resultadosLaboratorio, observaciones });
|
||||||
}
|
}
|
||||||
setDialog(false);
|
setDialog(false);
|
||||||
reset();
|
reset();
|
||||||
@@ -1761,7 +1724,6 @@ function SeccionEvoluciones({ evos, internacionId, add, update, del, canEdit }:
|
|||||||
const [dialog, setDialog] = useState(false);
|
const [dialog, setDialog] = useState(false);
|
||||||
const [edit, setEdit] = useState<Evolucion | null>(null);
|
const [edit, setEdit] = useState<Evolucion | null>(null);
|
||||||
const [evoDetalle, setEvoDetalle] = useState<Evolucion | null>(null);
|
const [evoDetalle, setEvoDetalle] = useState<Evolucion | null>(null);
|
||||||
const [expanded, setExpanded] = useState<string | null>(null);
|
|
||||||
const [fecha, setFecha] = useState(new Date().toISOString().split('T')[0]);
|
const [fecha, setFecha] = useState(new Date().toISOString().split('T')[0]);
|
||||||
const [hora, setHora] = useState(new Date().toTimeString().slice(0, 5));
|
const [hora, setHora] = useState(new Date().toTimeString().slice(0, 5));
|
||||||
const effectiveMedico = getNombreProfesional(currentUser);
|
const effectiveMedico = getNombreProfesional(currentUser);
|
||||||
@@ -2067,9 +2029,10 @@ function SeccionEvoluciones({ evos, internacionId, add, update, del, canEdit }:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function SeccionAcidosBase({ ab, patientId, add, update, del, canEdit }: {
|
function SeccionAcidosBase({ ab, patientId, internacionId, add, update, del, canEdit }: {
|
||||||
ab: AcidoBase[];
|
ab: AcidoBase[];
|
||||||
patientId: string;
|
patientId: string;
|
||||||
|
internacionId: string;
|
||||||
add: (a: Omit<AcidoBase, 'id'>) => void;
|
add: (a: Omit<AcidoBase, 'id'>) => void;
|
||||||
update: (id: string, datos: Partial<AcidoBase>) => void;
|
update: (id: string, datos: Partial<AcidoBase>) => void;
|
||||||
del: (id: string) => void;
|
del: (id: string) => void;
|
||||||
@@ -2116,15 +2079,6 @@ function SeccionAcidosBase({ ab, patientId, add, update, del, canEdit }: {
|
|||||||
|
|
||||||
const abFiltered = ab.filter(a => a.pacienteId === patientId).sort((a, b) => new Date(b.fecha + 'T' + b.hora).getTime() - new Date(a.fecha + 'T' + a.hora).getTime());
|
const abFiltered = ab.filter(a => a.pacienteId === patientId).sort((a, b) => new Date(b.fecha + 'T' + b.hora).getTime() - new Date(a.fecha + 'T' + a.hora).getTime());
|
||||||
|
|
||||||
const getEstadoParametro = (param: string, val: number) => {
|
|
||||||
const refs: Record<string, { min: number; max: number }> = { ph: { min: 7.35, max: 7.45 }, pco2: { min: 35, max: 45 }, po2: { min: 80, max: 100 }, hco3: { min: 22, max: 26 }, be: { min: -2, max: 2 }, sato2: { min: 95, max: 100 } };
|
|
||||||
const r = refs[param];
|
|
||||||
if (!r) return { estado: 'Normal', color: 'text-gray-800' };
|
|
||||||
if (val < r.min) return { estado: 'Bajo', color: 'text-blue-600' };
|
|
||||||
if (val > r.max) return { estado: 'Alto', color: 'text-red-600' };
|
|
||||||
return { estado: 'Normal', color: 'text-green-600' };
|
|
||||||
};
|
|
||||||
|
|
||||||
const interpretarGasometria = () => {
|
const interpretarGasometria = () => {
|
||||||
const phVal = parseFloat(ph), pco2Val = parseFloat(pco2), hco3Val = parseFloat(hco3), beVal = parseFloat(be);
|
const phVal = parseFloat(ph), pco2Val = parseFloat(pco2), hco3Val = parseFloat(hco3), beVal = parseFloat(be);
|
||||||
if (!phVal || !pco2Val || !hco3Val) return '';
|
if (!phVal || !pco2Val || !hco3Val) return '';
|
||||||
@@ -2136,16 +2090,10 @@ function SeccionAcidosBase({ ab, patientId, add, update, del, canEdit }: {
|
|||||||
return interp;
|
return interp;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getColorPh = (ph: number) => {
|
|
||||||
if (ph < 7.2 || ph > 7.6) return 'bg-red-100 text-red-800';
|
|
||||||
if (ph < 7.35 || ph > 7.45) return 'bg-amber-100 text-amber-800';
|
|
||||||
return 'bg-green-100 text-green-800';
|
|
||||||
};
|
|
||||||
|
|
||||||
const handle = () => {
|
const handle = () => {
|
||||||
if (!ph || !pco2 || !po2 || !hco3 || !be || !sato2) return;
|
if (!ph || !pco2 || !po2 || !hco3 || !be || !sato2) return;
|
||||||
const interpretacionAuto = interpretarGasometria();
|
const interpretacionAuto = interpretarGasometria();
|
||||||
add({ pacienteId: patientId, fecha, hora, ph: parseFloat(ph), pco2: parseFloat(pco2), po2: parseFloat(po2), hco3: parseFloat(hco3), be: parseFloat(be), sato2: parseFloat(sato2), lactato: lactato ? parseFloat(lactato) : undefined, fio2: fio2 ? parseFloat(fio2) : undefined, interpretacion: interpretacion || interpretacionAuto });
|
add({ pacienteId: patientId, internacionId, fecha, hora, ph: parseFloat(ph), pco2: parseFloat(pco2), po2: parseFloat(po2), hco3: parseFloat(hco3), be: parseFloat(be), sato2: parseFloat(sato2), lactato: lactato ? parseFloat(lactato) : undefined, fio2: fio2 ? parseFloat(fio2) : undefined, interpretacion: interpretacion || interpretacionAuto });
|
||||||
setDialog(false);
|
setDialog(false);
|
||||||
reset();
|
reset();
|
||||||
};
|
};
|
||||||
@@ -2300,9 +2248,10 @@ function SeccionAcidosBase({ ab, patientId, add, update, del, canEdit }: {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function SeccionCultivos({ cults, patient, add, update, del, canEdit }: {
|
function SeccionCultivos({ cults, patient, internacionId, add, update, del, canEdit }: {
|
||||||
cults: Cultivo[];
|
cults: Cultivo[];
|
||||||
patient: Paciente;
|
patient: Paciente;
|
||||||
|
internacionId: string;
|
||||||
add: (c: Omit<Cultivo, 'id'>) => void;
|
add: (c: Omit<Cultivo, 'id'>) => void;
|
||||||
update: (id: string, data: Partial<Cultivo>) => void;
|
update: (id: string, data: Partial<Cultivo>) => void;
|
||||||
del: (id: string) => void;
|
del: (id: string) => void;
|
||||||
@@ -2312,7 +2261,6 @@ function SeccionCultivos({ cults, patient, add, update, del, canEdit }: {
|
|||||||
const [resDialog, setResDialog] = useState(false);
|
const [resDialog, setResDialog] = useState(false);
|
||||||
const [editDialog, setEditDialog] = useState(false);
|
const [editDialog, setEditDialog] = useState(false);
|
||||||
const [selected, setSelected] = useState<Cultivo | null>(null);
|
const [selected, setSelected] = useState<Cultivo | null>(null);
|
||||||
const [isParcialMode, setIsParcialMode] = useState(false);
|
|
||||||
const [fechaToma, setFechaToma] = useState(new Date().toISOString().split('T')[0]);
|
const [fechaToma, setFechaToma] = useState(new Date().toISOString().split('T')[0]);
|
||||||
const [protocolo, setProtocolo] = useState('');
|
const [protocolo, setProtocolo] = useState('');
|
||||||
const [tipoMuestra, setTipoMuestra] = useState<Cultivo['tipoMuestra']>('HMCx2');
|
const [tipoMuestra, setTipoMuestra] = useState<Cultivo['tipoMuestra']>('HMCx2');
|
||||||
@@ -2340,29 +2288,8 @@ function SeccionCultivos({ cults, patient, add, update, del, canEdit }: {
|
|||||||
setSelected(null);
|
setSelected(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const abrirParcial = (c: Cultivo) => {
|
|
||||||
setSelected(c);
|
|
||||||
setProtocolo(c.protocolo || '');
|
|
||||||
setGermen(c.germen || '');
|
|
||||||
setSensible(c.sensible || '');
|
|
||||||
setResistente(c.resistente || '');
|
|
||||||
setResDialog(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const abrirDefinitivo = (c: Cultivo) => {
|
|
||||||
setSelected(c);
|
|
||||||
setProtocolo(c.protocolo || '');
|
|
||||||
setFechaResultado(c.fechaResultado || new Date().toISOString().split('T')[0]);
|
|
||||||
setEstadoResultado(c.estado === 'Parcial' || c.estado === 'Positivo' ? 'Positivo' : c.estado);
|
|
||||||
setGermen(c.germen || '');
|
|
||||||
setSensible(c.sensible || '');
|
|
||||||
setResistente(c.resistente || '');
|
|
||||||
setEditDialog(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const openParcial = (c: Cultivo) => {
|
const openParcial = (c: Cultivo) => {
|
||||||
setSelected(c);
|
setSelected(c);
|
||||||
setIsParcialMode(true);
|
|
||||||
setProtocolo(c.protocolo || '');
|
setProtocolo(c.protocolo || '');
|
||||||
setGermen(c.germen || '');
|
setGermen(c.germen || '');
|
||||||
setSensible(c.sensible || '');
|
setSensible(c.sensible || '');
|
||||||
@@ -2372,7 +2299,6 @@ function SeccionCultivos({ cults, patient, add, update, del, canEdit }: {
|
|||||||
|
|
||||||
const openDefinitivo = (c: Cultivo) => {
|
const openDefinitivo = (c: Cultivo) => {
|
||||||
setSelected(c);
|
setSelected(c);
|
||||||
setIsParcialMode(false);
|
|
||||||
setProtocolo(c.protocolo || '');
|
setProtocolo(c.protocolo || '');
|
||||||
setFechaResultado(c.fechaResultado || new Date().toISOString().split('T')[0]);
|
setFechaResultado(c.fechaResultado || new Date().toISOString().split('T')[0]);
|
||||||
setEstadoResultado(c.estado === 'Parcial' ? 'Positivo' : c.estado);
|
setEstadoResultado(c.estado === 'Parcial' ? 'Positivo' : c.estado);
|
||||||
@@ -2402,7 +2328,7 @@ function SeccionCultivos({ cults, patient, add, update, del, canEdit }: {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handle = () => { add({ pacienteId: patient.id, fechaToma, protocolo, tipoMuestra, observaciones: observaciones || undefined, estado: 'NAF/Pendiente' }); setDialog(false); reset(); };
|
const handle = () => { add({ pacienteId: patient.id, internacionId, fechaToma, protocolo, tipoMuestra, observaciones: observaciones || undefined, estado: 'NAF/Pendiente' }); setDialog(false); reset(); };
|
||||||
|
|
||||||
const handleParcial = () => {
|
const handleParcial = () => {
|
||||||
if (!selected) return;
|
if (!selected) return;
|
||||||
@@ -2753,7 +2679,7 @@ function SeccionInterconsultas({ interconsultas, pacienteId, internacionId, add,
|
|||||||
|
|
||||||
const handleGuardar = () => {
|
const handleGuardar = () => {
|
||||||
if (!servicioInterconsultado) return;
|
if (!servicioInterconsultado) return;
|
||||||
const datos: any = { fecha, servicioInterconsultado, motivo, respuestaInterconsulta };
|
const datos: Partial<Interconsulta> = { fecha, servicioInterconsultado, motivo, respuestaInterconsulta };
|
||||||
if (respuestaInterconsulta) {
|
if (respuestaInterconsulta) {
|
||||||
datos.respuestaFecha = respuestaFecha || new Date().toISOString().split('T')[0];
|
datos.respuestaFecha = respuestaFecha || new Date().toISOString().split('T')[0];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { ClipboardList, Plus, Search, LogOut, CheckCircle2, MoreHorizontal, FileText } from 'lucide-react';
|
import { ClipboardList, Plus, Search, LogOut, CheckCircle2, MoreHorizontal, FileText, Trash2 } from 'lucide-react';
|
||||||
import { Card, CardContent } from '@/components/ui/card';
|
import { Card, CardContent } from '@/components/ui/card';
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
@@ -28,6 +28,7 @@ interface InternacionesProps {
|
|||||||
diagnosticoEgreso: string;
|
diagnosticoEgreso: string;
|
||||||
motivoEgreso: Internacion['motivoEgreso']
|
motivoEgreso: Internacion['motivoEgreso']
|
||||||
}) => void;
|
}) => void;
|
||||||
|
onEliminarInternacion?: (internacionId: string) => Promise<void> | void;
|
||||||
getPacienteById: (id: string) => Paciente | undefined;
|
getPacienteById: (id: string) => Paciente | undefined;
|
||||||
getCamaById: (id: string) => Cama | undefined;
|
getCamaById: (id: string) => Cama | undefined;
|
||||||
onVerHC?: (internacionId: string) => void;
|
onVerHC?: (internacionId: string) => void;
|
||||||
@@ -40,6 +41,7 @@ export function Internaciones({
|
|||||||
camas,
|
camas,
|
||||||
onIniciarInternacion,
|
onIniciarInternacion,
|
||||||
onFinalizarInternacion,
|
onFinalizarInternacion,
|
||||||
|
onEliminarInternacion,
|
||||||
getPacienteById,
|
getPacienteById,
|
||||||
getCamaById,
|
getCamaById,
|
||||||
grupos,
|
grupos,
|
||||||
@@ -50,7 +52,9 @@ export function Internaciones({
|
|||||||
const [filtroEstado, setFiltroEstado] = useState<'todas' | 'activas' | 'finalizadas'>('todas');
|
const [filtroEstado, setFiltroEstado] = useState<'todas' | 'activas' | 'finalizadas'>('todas');
|
||||||
const [dialogoNuevaAbierto, setDialogoNuevaAbierto] = useState(false);
|
const [dialogoNuevaAbierto, setDialogoNuevaAbierto] = useState(false);
|
||||||
const [dialogoEgresoAbierto, setDialogoEgresoAbierto] = useState(false);
|
const [dialogoEgresoAbierto, setDialogoEgresoAbierto] = useState(false);
|
||||||
|
const [dialogoEliminarAbierto, setDialogoEliminarAbierto] = useState(false);
|
||||||
const [internacionSeleccionada, setInternacionSeleccionada] = useState<Internacion | null>(null);
|
const [internacionSeleccionada, setInternacionSeleccionada] = useState<Internacion | null>(null);
|
||||||
|
const [internacionAEliminar, setInternacionAEliminar] = useState<Internacion | null>(null);
|
||||||
const [busqueda, setBusqueda] = useState('');
|
const [busqueda, setBusqueda] = useState('');
|
||||||
const [pacienteSeleccionado, setPacienteSeleccionado] = useState<string>('');
|
const [pacienteSeleccionado, setPacienteSeleccionado] = useState<string>('');
|
||||||
const [camaSeleccionada, setCamaSeleccionada] = useState<string>('');
|
const [camaSeleccionada, setCamaSeleccionada] = useState<string>('');
|
||||||
@@ -488,6 +492,16 @@ export function Internaciones({
|
|||||||
<FileText className="mr-2 h-4 w-4" />
|
<FileText className="mr-2 h-4 w-4" />
|
||||||
Ver HC
|
Ver HC
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem
|
||||||
|
className="text-red-600 focus:text-red-600"
|
||||||
|
onClick={() => {
|
||||||
|
setInternacionAEliminar(internacion);
|
||||||
|
setDialogoEliminarAbierto(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Trash2 className="mr-2 h-4 w-4" />
|
||||||
|
Eliminar HC
|
||||||
|
</DropdownMenuItem>
|
||||||
{internacion.activa && (
|
{internacion.activa && (
|
||||||
<DropdownMenuItem onClick={() => abrirDialogoEgreso(internacion)}>
|
<DropdownMenuItem onClick={() => abrirDialogoEgreso(internacion)}>
|
||||||
<LogOut className="mr-2 h-4 w-4" />
|
<LogOut className="mr-2 h-4 w-4" />
|
||||||
@@ -567,7 +581,36 @@ export function Internaciones({
|
|||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
{/* Historia Clínica ahora es una página separada */}
|
{/* Modal Confirmar Eliminación HC */}
|
||||||
|
<Dialog open={dialogoEliminarAbierto} onOpenChange={(open) => { if (!open) setInternacionAEliminar(null); setDialogoEliminarAbierto(open); }}>
|
||||||
|
<DialogContent className="sm:max-w-md">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Eliminar Historia Clínica de Internación</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
<div className="space-y-4 py-2">
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
¿Está seguro de que desea eliminar esta historia clínica de internación y todos sus registros asociados (evoluciones, laboratorios, cultivos, indicaciones, etc.)? Esta acción no se puede deshacer.
|
||||||
|
</p>
|
||||||
|
<div className="flex justify-end gap-2 pt-2">
|
||||||
|
<Button variant="outline" onClick={() => setDialogoEliminarAbierto(false)}>
|
||||||
|
Cancelar
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="destructive"
|
||||||
|
onClick={async () => {
|
||||||
|
if (internacionAEliminar && typeof onEliminarInternacion === 'function') {
|
||||||
|
await onEliminarInternacion(internacionAEliminar.id);
|
||||||
|
setDialogoEliminarAbierto(false);
|
||||||
|
setInternacionAEliminar(null);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Eliminar Definitivamente
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-7
@@ -1,3 +1,4 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
import {
|
import {
|
||||||
LayoutDashboard,
|
LayoutDashboard,
|
||||||
Bed,
|
Bed,
|
||||||
@@ -35,6 +36,7 @@ interface LayoutProps {
|
|||||||
|
|
||||||
export function Layout({ children, vistaActual, onCambiarVista, currentUser, onLogout }: LayoutProps) {
|
export function Layout({ children, vistaActual, onCambiarVista, currentUser, onLogout }: LayoutProps) {
|
||||||
const { theme, setTheme } = useTheme()
|
const { theme, setTheme } = useTheme()
|
||||||
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||||
|
|
||||||
const toggleDarkMode = () => setTheme(theme === "dark" ? "light" : "dark")
|
const toggleDarkMode = () => setTheme(theme === "dark" ? "light" : "dark")
|
||||||
|
|
||||||
@@ -59,7 +61,7 @@ export function Layout({ children, vistaActual, onCambiarVista, currentUser, onL
|
|||||||
filteredMenuItems.push({ vista: 'usuarios', label: 'Usuarios', icon: UserCog });
|
filteredMenuItems.push({ vista: 'usuarios', label: 'Usuarios', icon: UserCog });
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderNavContent = () => (
|
const renderNavContent = (onItemClick?: () => void) => (
|
||||||
<nav className="flex flex-col gap-2">
|
<nav className="flex flex-col gap-2">
|
||||||
{filteredMenuItems.map((item) => {
|
{filteredMenuItems.map((item) => {
|
||||||
const Icon = item.icon;
|
const Icon = item.icon;
|
||||||
@@ -69,7 +71,10 @@ export function Layout({ children, vistaActual, onCambiarVista, currentUser, onL
|
|||||||
key={item.vista}
|
key={item.vista}
|
||||||
variant={isActive ? 'default' : 'ghost'}
|
variant={isActive ? 'default' : 'ghost'}
|
||||||
className={`justify-start gap-3 ${isActive ? 'bg-blue-600 hover:bg-blue-700 text-white' : 'hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-gray-200'}`}
|
className={`justify-start gap-3 ${isActive ? 'bg-blue-600 hover:bg-blue-700 text-white' : 'hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-gray-200'}`}
|
||||||
onClick={() => onCambiarVista(item.vista)}
|
onClick={() => {
|
||||||
|
onCambiarVista(item.vista);
|
||||||
|
if (onItemClick) onItemClick();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Icon className="h-5 w-5" />
|
<Icon className="h-5 w-5" />
|
||||||
<span>{item.label}</span>
|
<span>{item.label}</span>
|
||||||
@@ -141,9 +146,9 @@ export function Layout({ children, vistaActual, onCambiarVista, currentUser, onL
|
|||||||
</div>
|
</div>
|
||||||
<span className="font-bold text-gray-900 dark:text-white">Gestion Historia Clinica Electronica</span>
|
<span className="font-bold text-gray-900 dark:text-white">Gestion Historia Clinica Electronica</span>
|
||||||
</div>
|
</div>
|
||||||
<Sheet>
|
<Sheet open={mobileMenuOpen} onOpenChange={setMobileMenuOpen}>
|
||||||
<SheetTrigger asChild>
|
<SheetTrigger asChild>
|
||||||
<Button variant="ghost" size="icon" className="dark:text-white">
|
<Button variant="ghost" size="icon" className="dark:text-white" onClick={() => setMobileMenuOpen(true)}>
|
||||||
<Menu className="h-6 w-6" />
|
<Menu className="h-6 w-6" />
|
||||||
</Button>
|
</Button>
|
||||||
</SheetTrigger>
|
</SheetTrigger>
|
||||||
@@ -162,13 +167,16 @@ export function Layout({ children, vistaActual, onCambiarVista, currentUser, onL
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
{renderNavContent()}
|
{renderNavContent(() => setMobileMenuOpen(false))}
|
||||||
</div>
|
</div>
|
||||||
<div className="p-4 border-t border-gray-200 dark:border-gray-700 space-y-2">
|
<div className="p-4 border-t border-gray-200 dark:border-gray-700 space-y-2">
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={toggleDarkMode}
|
onClick={() => {
|
||||||
|
toggleDarkMode();
|
||||||
|
setMobileMenuOpen(false);
|
||||||
|
}}
|
||||||
className="w-full flex items-center justify-center gap-2 dark:text-white"
|
className="w-full flex items-center justify-center gap-2 dark:text-white"
|
||||||
>
|
>
|
||||||
{theme === "dark" ? <Sun className="h-4 w-4" /> : <Moon className="h-4 w-4" />}
|
{theme === "dark" ? <Sun className="h-4 w-4" /> : <Moon className="h-4 w-4" />}
|
||||||
@@ -177,7 +185,10 @@ export function Layout({ children, vistaActual, onCambiarVista, currentUser, onL
|
|||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={onLogout}
|
onClick={() => {
|
||||||
|
onLogout();
|
||||||
|
setMobileMenuOpen(false);
|
||||||
|
}}
|
||||||
className="w-full flex items-center justify-center gap-2 dark:text-white"
|
className="w-full flex items-center justify-center gap-2 dark:text-white"
|
||||||
>
|
>
|
||||||
<LogOut className="h-4 w-4" />
|
<LogOut className="h-4 w-4" />
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ export function Login() {
|
|||||||
try {
|
try {
|
||||||
await login(dni, password);
|
await login(dni, password);
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
} catch (err: any) {
|
} catch (err) {
|
||||||
setError(err.message || 'Error de autenticación');
|
setError(err instanceof Error ? err.message : 'Error de autenticación');
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ interface MapaCamasProps {
|
|||||||
pacientes: Paciente[];
|
pacientes: Paciente[];
|
||||||
internaciones: Internacion[];
|
internaciones: Internacion[];
|
||||||
onActualizarCama: (id: string, datos: Partial<Cama>) => void;
|
onActualizarCama: (id: string, datos: Partial<Cama>) => void;
|
||||||
onAgregarCama: (cama: Omit<Cama, 'id'>) => any;
|
onAgregarCama: (cama: Omit<Cama, 'id'>) => Promise<string | void>;
|
||||||
onEliminarCama: (id: string) => void;
|
onEliminarCama: (id: string) => void;
|
||||||
onIniciarInternacion: (internacion: Omit<Internacion, 'id' | 'activa'>) => Promise<string>;
|
onIniciarInternacion: (internacion: Omit<Internacion, 'id' | 'activa'>) => Promise<string>;
|
||||||
onAgregarGrupo: (grupo: Omit<Grupo, 'id'>) => any;
|
onAgregarGrupo: (grupo: Omit<Grupo, 'id'>) => Promise<string | void>;
|
||||||
onActualizarGrupo: (id: string, datos: Partial<Grupo>) => void;
|
onActualizarGrupo: (id: string, datos: Partial<Grupo>) => void;
|
||||||
onEliminarGrupo: (id: string) => void;
|
onEliminarGrupo: (id: string) => void;
|
||||||
getPacienteById: (id: string) => Paciente | undefined;
|
getPacienteById: (id: string) => Paciente | undefined;
|
||||||
@@ -41,9 +41,8 @@ export function MapaCamas({
|
|||||||
onActualizarGrupo,
|
onActualizarGrupo,
|
||||||
onEliminarGrupo,
|
onEliminarGrupo,
|
||||||
getPacienteById,
|
getPacienteById,
|
||||||
getInternacionById
|
|
||||||
}: MapaCamasProps) {
|
}: MapaCamasProps) {
|
||||||
const { canEditCama, canAccessGrupo, currentUser } = useHospitalStore();
|
const { canEditCama, currentUser } = useHospitalStore();
|
||||||
const [filtroSala, setFiltroSala] = useState<string>('todas');
|
const [filtroSala, setFiltroSala] = useState<string>('todas');
|
||||||
const [filtroTipo, setFiltroTipo] = useState<string>('todos');
|
const [filtroTipo, setFiltroTipo] = useState<string>('todos');
|
||||||
const [filtroEstado, setFiltroEstado] = useState<string>('todos');
|
const [filtroEstado, setFiltroEstado] = useState<string>('todos');
|
||||||
@@ -479,9 +478,7 @@ export function MapaCamas({
|
|||||||
)}
|
)}
|
||||||
{canEditCama(cama.id) && (
|
{canEditCama(cama.id) && (
|
||||||
<Button variant="destructive" onClick={() => {
|
<Button variant="destructive" onClick={() => {
|
||||||
if (confirm('Eliminar esta cama?')) {
|
|
||||||
onEliminarCama(cama.id);
|
onEliminarCama(cama.id);
|
||||||
}
|
|
||||||
}}>
|
}}>
|
||||||
<Trash className="h-4 w-4 mr-1" />Eliminar
|
<Trash className="h-4 w-4 mr-1" />Eliminar
|
||||||
</Button>
|
</Button>
|
||||||
@@ -589,7 +586,7 @@ export function MapaCamas({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex gap-2 justify-end">
|
<div className="flex gap-2 justify-end">
|
||||||
{editingBed && (
|
{editingBed && (
|
||||||
<Button variant="destructive" onClick={() => { if (confirm('Eliminar cama?')) { onEliminarCama(editingBed.id); setBedDialogOpen(false); } }}>
|
<Button variant="destructive" onClick={() => { onEliminarCama(editingBed.id); setBedDialogOpen(false); }}>
|
||||||
Eliminar
|
Eliminar
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -21,9 +21,10 @@ interface NuevoIngresoProps {
|
|||||||
onActualizarPaciente?: (id: string, datos: Partial<Paciente>) => void;
|
onActualizarPaciente?: (id: string, datos: Partial<Paciente>) => void;
|
||||||
onVolver: () => void;
|
onVolver: () => void;
|
||||||
getGrupoName: (grupoId: string | undefined) => string;
|
getGrupoName: (grupoId: string | undefined) => string;
|
||||||
|
internaciones: Internacion[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NuevoIngreso({ pacientes, camas, grupos, onIniciarInternacion, onAgregarCama, onVolver, getGrupoName }: NuevoIngresoProps) {
|
export function NuevoIngreso({ pacientes, camas, grupos, onIniciarInternacion, onAgregarCama, onVolver, getGrupoName, internaciones }: NuevoIngresoProps) {
|
||||||
const { currentUser } = useHospitalStore();
|
const { currentUser } = useHospitalStore();
|
||||||
const [pacienteSeleccionado, setPacienteSeleccionado] = useState<string>('');
|
const [pacienteSeleccionado, setPacienteSeleccionado] = useState<string>('');
|
||||||
const [busqueda, setBusqueda] = useState('');
|
const [busqueda, setBusqueda] = useState('');
|
||||||
@@ -61,7 +62,10 @@ export function NuevoIngreso({ pacientes, camas, grupos, onIniciarInternacion, o
|
|||||||
const grupoFueraDeGrupo = grupos.find(a => normalizeStr(a.nombre) === 'fuera de grupo');
|
const grupoFueraDeGrupo = grupos.find(a => normalizeStr(a.nombre) === 'fuera de grupo');
|
||||||
const grupoFueraDeGrupoId = grupoFueraDeGrupo?.id || grupos[0]?.id || 'fuera-de-grupo';
|
const grupoFueraDeGrupoId = grupoFueraDeGrupo?.id || grupos[0]?.id || 'fuera-de-grupo';
|
||||||
|
|
||||||
const pacientesSinInternar = pacientes;
|
const pacientesSinInternar = pacientes.filter(p => {
|
||||||
|
const internacionActiva = internaciones.find(i => i.pacienteId === p.id && i.activa);
|
||||||
|
return !internacionActiva;
|
||||||
|
});
|
||||||
|
|
||||||
const parseBedNumber = (numero: string) => {
|
const parseBedNumber = (numero: string) => {
|
||||||
const match = numero.match(/^(\d{3})-(\d+)$/);
|
const match = numero.match(/^(\d{3})-(\d+)$/);
|
||||||
|
|||||||
@@ -225,6 +225,17 @@ export interface Indicacion {
|
|||||||
fechaSuspension?: string;
|
fechaSuspension?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MovimientoIndicacion {
|
||||||
|
id: string;
|
||||||
|
internacionId: string;
|
||||||
|
indicacionId?: string;
|
||||||
|
tipo: string;
|
||||||
|
fecha: string;
|
||||||
|
hora: string;
|
||||||
|
medico: string;
|
||||||
|
observaciones?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export type Vista = 'dashboard' | 'camas' | 'pacientes' | 'internaciones' | 'evoluciones' | 'laboratorios' | 'acidobase' | 'cultivos' | 'historiaclinica' | 'nuevoingreso' | 'editaringreso' | 'usuarios';
|
export type Vista = 'dashboard' | 'camas' | 'pacientes' | 'internaciones' | 'evoluciones' | 'laboratorios' | 'acidobase' | 'cultivos' | 'historiaclinica' | 'nuevoingreso' | 'editaringreso' | 'usuarios';
|
||||||
|
|
||||||
export type RolUsuario = 'admin' | 'medico' | 'enfermero';
|
export type RolUsuario = 'admin' | 'medico' | 'enfermero';
|
||||||
|
|||||||
Reference in New Issue
Block a user