Renombrar 'Areas' a 'Grupos' y actualizar dependencias
This commit is contained in:
+74
-11
@@ -67,9 +67,15 @@ export function initDb() {
|
|||||||
nombre TEXT NOT NULL UNIQUE
|
nombre TEXT NOT NULL UNIQUE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS grupos (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
nombre TEXT NOT NULL UNIQUE
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS camas (
|
CREATE TABLE IF NOT EXISTS camas (
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
numero TEXT NOT NULL,
|
numero TEXT NOT NULL,
|
||||||
|
grupoId TEXT,
|
||||||
areaId TEXT,
|
areaId TEXT,
|
||||||
tipo TEXT DEFAULT 'Estándar',
|
tipo TEXT DEFAULT 'Estándar',
|
||||||
estado TEXT DEFAULT 'Disponible',
|
estado TEXT DEFAULT 'Disponible',
|
||||||
@@ -81,6 +87,7 @@ export function initDb() {
|
|||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
pacienteId TEXT NOT NULL,
|
pacienteId TEXT NOT NULL,
|
||||||
camaId TEXT,
|
camaId TEXT,
|
||||||
|
grupoId TEXT,
|
||||||
areaId TEXT,
|
areaId TEXT,
|
||||||
fechaIngresoHospital TEXT,
|
fechaIngresoHospital TEXT,
|
||||||
fechaIngresoClinica TEXT,
|
fechaIngresoClinica TEXT,
|
||||||
@@ -233,6 +240,36 @@ export function initDb() {
|
|||||||
);
|
);
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
// Migration helpers for columns if existing DB
|
||||||
|
try { db.exec('ALTER TABLE usuarios ADD COLUMN grupoId TEXT;'); } catch (_) {}
|
||||||
|
try { db.exec('ALTER TABLE camas ADD COLUMN grupoId TEXT;'); } catch (_) {}
|
||||||
|
try { db.exec('ALTER TABLE internaciones ADD COLUMN grupoId TEXT;'); } catch (_) {}
|
||||||
|
try { db.exec('ALTER TABLE usuarios ADD COLUMN areaId TEXT;'); } catch (_) {}
|
||||||
|
try { db.exec('ALTER TABLE camas ADD COLUMN areaId TEXT;'); } catch (_) {}
|
||||||
|
try { db.exec('ALTER TABLE internaciones ADD COLUMN areaId TEXT;'); } catch (_) {}
|
||||||
|
|
||||||
|
// Seed default 4 grupos if empty
|
||||||
|
try {
|
||||||
|
const defaultGrupos = [
|
||||||
|
{ id: 'patron-fondo', nombre: 'Patron Fondo' },
|
||||||
|
{ id: 'patron-adelante', nombre: 'Patron Adelante' },
|
||||||
|
{ id: 'segundo-acassuso', nombre: 'Segundo Acassuso' },
|
||||||
|
{ id: 'tercero-acassuso', nombre: 'Tercero Acassuso' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const grupoCount = db.prepare('SELECT COUNT(*) as count FROM grupos').get();
|
||||||
|
if (!grupoCount || grupoCount.count === 0) {
|
||||||
|
const stmtG = db.prepare('INSERT OR IGNORE INTO grupos (id, nombre) VALUES (?, ?)');
|
||||||
|
const stmtA = db.prepare('INSERT OR IGNORE INTO areas (id, nombre) VALUES (?, ?)');
|
||||||
|
for (const g of defaultGrupos) {
|
||||||
|
stmtG.run(g.id, g.nombre);
|
||||||
|
stmtA.run(g.id, g.nombre);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error seeding default grupos:', err);
|
||||||
|
}
|
||||||
|
|
||||||
// Create default admin if no users exist
|
// Create default admin if no users exist
|
||||||
try {
|
try {
|
||||||
const userCount = db.prepare('SELECT COUNT(*) as count FROM usuarios').get();
|
const userCount = db.prepare('SELECT COUNT(*) as count FROM usuarios').get();
|
||||||
@@ -351,11 +388,18 @@ export function getAllPacientes() {
|
|||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAllAreas() {
|
export function getAllGrupos() {
|
||||||
const rows = db.prepare('SELECT * FROM areas').all();
|
const rows = db.prepare('SELECT * FROM grupos').all();
|
||||||
|
if (!rows || rows.length === 0) {
|
||||||
|
return db.prepare('SELECT * FROM areas').all();
|
||||||
|
}
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAllAreas() {
|
||||||
|
return getAllGrupos();
|
||||||
|
}
|
||||||
|
|
||||||
export function getAllCamas() {
|
export function getAllCamas() {
|
||||||
const rows = db.prepare('SELECT * FROM camas').all();
|
const rows = db.prepare('SELECT * FROM camas').all();
|
||||||
return rows;
|
return rows;
|
||||||
@@ -467,24 +511,42 @@ export function deletePaciente(id) {
|
|||||||
db.prepare('DELETE FROM pacientes WHERE id = ?').run(id);
|
db.prepare('DELETE FROM pacientes WHERE id = ?').run(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Areas
|
// Grupos & Areas
|
||||||
|
export function createGrupo(grupo) {
|
||||||
|
const stmtG = db.prepare('INSERT INTO grupos (id, nombre) VALUES (?, ?)');
|
||||||
|
const stmtA = db.prepare('INSERT INTO areas (id, nombre) VALUES (?, ?)');
|
||||||
|
stmtG.run(grupo.id, grupo.nombre);
|
||||||
|
try { stmtA.run(grupo.id, grupo.nombre); } catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateGrupo(id, datos) {
|
||||||
|
if (datos.nombre) {
|
||||||
|
db.prepare('UPDATE grupos SET nombre = ? WHERE id = ?').run(datos.nombre, id);
|
||||||
|
try { db.prepare('UPDATE areas SET nombre = ? WHERE id = ?').run(datos.nombre, id); } catch (_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteGrupo(id) {
|
||||||
|
db.prepare('DELETE FROM grupos WHERE id = ?').run(id);
|
||||||
|
try { db.prepare('DELETE FROM areas WHERE id = ?').run(id); } catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
export function createArea(area) {
|
export function createArea(area) {
|
||||||
db.prepare('INSERT INTO areas (id, nombre) VALUES (?, ?)').run(area.id, area.nombre);
|
createGrupo(area);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateArea(id, datos) {
|
export function updateArea(id, datos) {
|
||||||
if (datos.nombre) {
|
updateGrupo(id, datos);
|
||||||
db.prepare('UPDATE areas SET nombre = ? WHERE id = ?').run(datos.nombre, id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteArea(id) {
|
export function deleteArea(id) {
|
||||||
db.prepare('DELETE FROM areas WHERE id = ?').run(id);
|
deleteGrupo(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Camas
|
// Camas
|
||||||
export function createCama(cama) {
|
export function createCama(cama) {
|
||||||
db.prepare('INSERT INTO camas (id, numero, areaId, tipo, estado, pacienteId, internacionId) VALUES (?, ?, ?, ?, ?, ?, ?)').run(cama.id, cama.numero, cama.areaId || null, cama.tipo || 'Estándar', cama.estado || 'Disponible', cama.pacienteId || null, cama.internacionId || null);
|
const gId = cama.grupoId || cama.areaId || null;
|
||||||
|
db.prepare('INSERT INTO camas (id, numero, grupoId, areaId, tipo, estado, pacienteId, internacionId) VALUES (?, ?, ?, ?, ?, ?, ?, ?)').run(cama.id, cama.numero, gId, gId, cama.tipo || 'Estándar', cama.estado || 'Disponible', cama.pacienteId || null, cama.internacionId || null);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteCama(id) {
|
export function deleteCama(id) {
|
||||||
@@ -493,8 +555,9 @@ export function deleteCama(id) {
|
|||||||
|
|
||||||
// Internaciones
|
// Internaciones
|
||||||
export function createInternacion(i) {
|
export function createInternacion(i) {
|
||||||
const stmt = db.prepare('INSERT INTO internaciones (id, pacienteId, camaId, areaId, fechaIngresoHospital, fechaIngresoClinica, fechaEgreso, diagnosticoIngreso, motivoConsulta, enfermedadActual, antecedentesEnfermedadActual, diagnosticoEgreso, medicoIngresante, motivoEgreso, activa, apache, derivacion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
const gId = i.grupoId || i.areaId || null;
|
||||||
stmt.run(i.id, i.pacienteId, i.camaId || null, i.areaId || null, i.fechaIngresoHospital || null, i.fechaIngresoClinica || null, i.fechaEgreso || null, i.diagnosticoIngreso || null, i.motivoConsulta || null, i.enfermedadActual || null, i.antecedentesEnfermedadActual || null, i.diagnosticoEgreso || null, i.medicoIngresante || null, i.motivoEgreso || null, i.activa ? 1 : 0, i.apache || null, i.derivacion || null);
|
const stmt = db.prepare('INSERT INTO internaciones (id, pacienteId, camaId, grupoId, areaId, fechaIngresoHospital, fechaIngresoClinica, fechaEgreso, diagnosticoIngreso, motivoConsulta, enfermedadActual, antecedentesEnfermedadActual, diagnosticoEgreso, medicoIngresante, motivoEgreso, activa, apache, derivacion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
||||||
|
stmt.run(i.id, i.pacienteId, i.camaId || null, gId, gId, i.fechaIngresoHospital || null, i.fechaIngresoClinica || null, i.fechaEgreso || null, i.diagnosticoIngreso || null, i.motivoConsulta || null, i.enfermedadActual || null, i.antecedentesEnfermedadActual || null, i.diagnosticoEgreso || null, i.medicoIngresante || null, i.motivoEgreso || null, i.activa ? 1 : 0, i.apache || null, i.derivacion || null);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateInternacion(id, datos) {
|
export function updateInternacion(id, datos) {
|
||||||
|
|||||||
+26
-18
@@ -3,7 +3,7 @@ import cors from 'cors';
|
|||||||
import {
|
import {
|
||||||
getDb, getValue, setValue, getUsuarioByDni, getUsuarioById, getAllUsuarios, createUsuario, updateUsuario, deleteUsuario, verifyPassword, hashPassword,
|
getDb, getValue, setValue, getUsuarioByDni, getUsuarioById, getAllUsuarios, createUsuario, updateUsuario, deleteUsuario, verifyPassword, hashPassword,
|
||||||
getAllPacientes, createPaciente, updatePaciente, deletePaciente,
|
getAllPacientes, createPaciente, updatePaciente, deletePaciente,
|
||||||
getAllAreas, createArea, updateArea, deleteArea,
|
getAllGrupos, createGrupo, updateGrupo, deleteGrupo,
|
||||||
getAllCamas, createCama, updateCama, deleteCama,
|
getAllCamas, createCama, updateCama, deleteCama,
|
||||||
getAllInternaciones, createInternacion, updateInternacion, deleteInternacion,
|
getAllInternaciones, createInternacion, updateInternacion, deleteInternacion,
|
||||||
getAllEvoluciones, createEvolucion, updateEvolucion, deleteEvolucion,
|
getAllEvoluciones, createEvolucion, updateEvolucion, deleteEvolucion,
|
||||||
@@ -27,9 +27,11 @@ const STORAGE_KEY = 'hospital-data-v1';
|
|||||||
|
|
||||||
app.get('/api/state', (req, res) => {
|
app.get('/api/state', (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
const gruposList = getAllGrupos();
|
||||||
const state = {
|
const state = {
|
||||||
pacientes: getAllPacientes(),
|
pacientes: getAllPacientes(),
|
||||||
areas: getAllAreas(),
|
grupos: gruposList,
|
||||||
|
areas: gruposList,
|
||||||
camas: getAllCamas(),
|
camas: getAllCamas(),
|
||||||
internaciones: getAllInternaciones(),
|
internaciones: getAllInternaciones(),
|
||||||
evoluciones: getAllEvoluciones(),
|
evoluciones: getAllEvoluciones(),
|
||||||
@@ -66,6 +68,7 @@ app.put('/api/state', (req, res) => {
|
|||||||
db.prepare('DELETE FROM glucemias').run();
|
db.prepare('DELETE FROM glucemias').run();
|
||||||
db.prepare('DELETE FROM internaciones').run();
|
db.prepare('DELETE FROM internaciones').run();
|
||||||
db.prepare('DELETE FROM camas').run();
|
db.prepare('DELETE FROM camas').run();
|
||||||
|
db.prepare('DELETE FROM grupos').run();
|
||||||
db.prepare('DELETE FROM areas').run();
|
db.prepare('DELETE FROM areas').run();
|
||||||
db.prepare('DELETE FROM pacientes').run();
|
db.prepare('DELETE FROM pacientes').run();
|
||||||
db.prepare('DELETE FROM estudiosComplementarios').run();
|
db.prepare('DELETE FROM estudiosComplementarios').run();
|
||||||
@@ -81,24 +84,29 @@ app.put('/api/state', (req, res) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.areas?.length) {
|
const gruposData = state.grupos?.length ? state.grupos : state.areas;
|
||||||
const stmt = db.prepare('INSERT INTO areas (id, nombre) VALUES (?, ?)');
|
if (gruposData?.length) {
|
||||||
for (const a of state.areas) {
|
const stmtG = db.prepare('INSERT OR IGNORE INTO grupos (id, nombre) VALUES (?, ?)');
|
||||||
stmt.run(a.id, a.nombre);
|
const stmtA = db.prepare('INSERT OR IGNORE INTO areas (id, nombre) VALUES (?, ?)');
|
||||||
|
for (const g of gruposData) {
|
||||||
|
stmtG.run(g.id, g.nombre);
|
||||||
|
stmtA.run(g.id, g.nombre);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.camas?.length) {
|
if (state.camas?.length) {
|
||||||
const stmt = db.prepare('INSERT OR IGNORE INTO camas (id, numero, areaId, tipo, estado) VALUES (?, ?, ?, ?, ?)');
|
const stmt = db.prepare('INSERT OR IGNORE INTO camas (id, numero, grupoId, areaId, tipo, estado) VALUES (?, ?, ?, ?, ?, ?)');
|
||||||
for (const c of state.camas) {
|
for (const c of state.camas) {
|
||||||
stmt.run(c.id, c.numero, c.areaId, c.tipo, c.estado);
|
const gId = c.grupoId || c.areaId || null;
|
||||||
|
stmt.run(c.id, c.numero, gId, gId, c.tipo, c.estado);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.internaciones?.length) {
|
if (state.internaciones?.length) {
|
||||||
const stmt = db.prepare('INSERT OR IGNORE INTO internaciones (id, pacienteId, camaId, areaId, fechaIngresoHospital, fechaIngresoClinica, fechaEgreso, diagnosticoIngreso, motivoConsulta, enfermedadActual, antecedentesEnfermedadActual, diagnosticoEgreso, medicoIngresante, motivoEgreso, activa, apache, derivacion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
const stmt = db.prepare('INSERT OR IGNORE INTO internaciones (id, pacienteId, camaId, grupoId, areaId, fechaIngresoHospital, fechaIngresoClinica, fechaEgreso, diagnosticoIngreso, motivoConsulta, enfermedadActual, antecedentesEnfermedadActual, diagnosticoEgreso, medicoIngresante, motivoEgreso, activa, apache, derivacion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
||||||
for (const i of state.internaciones) {
|
for (const i of state.internaciones) {
|
||||||
stmt.run(i.id, i.pacienteId, i.camaId, i.areaId || null, i.fechaIngresoHospital || null, i.fechaIngresoClinica || null, i.fechaEgreso || null, i.diagnosticoIngreso || null, i.motivoConsulta || null, i.enfermedadActual || null, i.antecedentesEnfermedadActual || null, i.diagnosticoEgreso || null, i.medicoIngresante || null, i.motivoEgreso || null, i.activa ? 1 : 0, i.apache || null, i.derivacion || null);
|
const gId = i.grupoId || i.areaId || null;
|
||||||
|
stmt.run(i.id, i.pacienteId, i.camaId, gId, gId, i.fechaIngresoHospital || null, i.fechaIngresoClinica || null, i.fechaEgreso || null, i.diagnosticoIngreso || null, i.motivoConsulta || null, i.enfermedadActual || null, i.antecedentesEnfermedadActual || null, i.diagnosticoEgreso || null, i.medicoIngresante || null, i.motivoEgreso || null, i.activa ? 1 : 0, i.apache || null, i.derivacion || null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,9 +334,9 @@ app.put('/api/auth/update-email', (req, res) => {
|
|||||||
|
|
||||||
// === GESTIÓN DE USUARIOS (ADMIN) ===
|
// === GESTIÓN DE USUARIOS (ADMIN) ===
|
||||||
|
|
||||||
app.get('/api/areas', (req, res) => {
|
app.get('/api/grupos', (req, res) => {
|
||||||
try {
|
try {
|
||||||
const areas = getAllAreas();
|
const areas = getAllGrupos();
|
||||||
res.json(areas);
|
res.json(areas);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
@@ -463,18 +471,18 @@ app.delete('/api/pacientes/:id', (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ========== AREAS ==========
|
// ========== AREAS ==========
|
||||||
app.post('/api/areas', (req, res) => {
|
app.post('/api/grupos', (req, res) => {
|
||||||
try {
|
try {
|
||||||
const area = { ...req.body, id: req.body.id || generateUUID() };
|
const area = { ...req.body, id: req.body.id || generateUUID() };
|
||||||
createArea(area);
|
createGrupo(area);
|
||||||
res.json(area);
|
res.json(area);
|
||||||
} catch (err) { res.status(500).json({ error: err.message }); }
|
} catch (err) { res.status(500).json({ error: err.message }); }
|
||||||
});
|
});
|
||||||
app.put('/api/areas/:id', (req, res) => {
|
app.put('/api/grupos/:id', (req, res) => {
|
||||||
try { updateArea(req.params.id, req.body); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
try { updateGrupo(req.params.id, req.body); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
||||||
});
|
});
|
||||||
app.delete('/api/areas/:id', (req, res) => {
|
app.delete('/api/grupos/:id', (req, res) => {
|
||||||
try { deleteArea(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
try { deleteGrupo(req.params.id); res.json({ ok: true }); } catch (err) { res.status(500).json({ error: err.message }); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// ========== CAMAS ==========
|
// ========== CAMAS ==========
|
||||||
|
|||||||
+9
-9
@@ -49,7 +49,7 @@ function AppContent() {
|
|||||||
return (
|
return (
|
||||||
<MapaCamas
|
<MapaCamas
|
||||||
camas={store.camas}
|
camas={store.camas}
|
||||||
areas={store.areas}
|
grupos={store.grupos}
|
||||||
pacientes={store.pacientes}
|
pacientes={store.pacientes}
|
||||||
internaciones={store.internaciones}
|
internaciones={store.internaciones}
|
||||||
onActualizarCama={store.actualizarCama}
|
onActualizarCama={store.actualizarCama}
|
||||||
@@ -58,9 +58,9 @@ function AppContent() {
|
|||||||
onIniciarInternacion={store.iniciarInternacion}
|
onIniciarInternacion={store.iniciarInternacion}
|
||||||
getPacienteById={store.getPacienteById}
|
getPacienteById={store.getPacienteById}
|
||||||
getInternacionById={store.getInternacionById}
|
getInternacionById={store.getInternacionById}
|
||||||
onAgregarArea={store.agregarArea}
|
onAgregarGrupo={store.agregarGrupo}
|
||||||
onActualizarArea={store.actualizarArea}
|
onActualizarGrupo={store.actualizarGrupo}
|
||||||
onEliminarArea={store.eliminarArea}
|
onEliminarGrupo={store.eliminarGrupo}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 'pacientes':
|
case 'pacientes':
|
||||||
@@ -79,7 +79,7 @@ function AppContent() {
|
|||||||
internaciones={store.internaciones}
|
internaciones={store.internaciones}
|
||||||
pacientes={store.pacientes}
|
pacientes={store.pacientes}
|
||||||
camas={store.camas}
|
camas={store.camas}
|
||||||
areas={store.areas}
|
grupos={store.grupos}
|
||||||
evoluciones={store.evoluciones}
|
evoluciones={store.evoluciones}
|
||||||
laboratorios={store.laboratorios}
|
laboratorios={store.laboratorios}
|
||||||
cultivos={store.cultivos}
|
cultivos={store.cultivos}
|
||||||
@@ -207,11 +207,11 @@ function AppContent() {
|
|||||||
<NuevoIngreso
|
<NuevoIngreso
|
||||||
pacientes={store.pacientes}
|
pacientes={store.pacientes}
|
||||||
camas={store.camas}
|
camas={store.camas}
|
||||||
areas={store.areas}
|
grupos={store.grupos}
|
||||||
onIniciarInternacion={store.iniciarInternacion}
|
onIniciarInternacion={store.iniciarInternacion}
|
||||||
onAgregarCama={store.agregarCama}
|
onAgregarCama={store.agregarCama}
|
||||||
onVolver={() => store.setVista('internaciones')}
|
onVolver={() => store.setVista('internaciones')}
|
||||||
getAreaName={(areaId) => store.areas.find(a => a.id === areaId)?.nombre || ''}
|
getGrupoName={(grupoId) => store.grupos.find(a => a.id === grupoId)?.nombre || ''}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -234,11 +234,11 @@ function AppContent() {
|
|||||||
cama={store.getCamaById(internacion.camaId)}
|
cama={store.getCamaById(internacion.camaId)}
|
||||||
pacientes={store.pacientes}
|
pacientes={store.pacientes}
|
||||||
camas={store.camas}
|
camas={store.camas}
|
||||||
areas={store.areas}
|
grupos={store.grupos}
|
||||||
onActualizarInternacion={store.actualizarInternacion}
|
onActualizarInternacion={store.actualizarInternacion}
|
||||||
onAgregarCama={store.agregarCama}
|
onAgregarCama={store.agregarCama}
|
||||||
onVolver={() => store.setVista('historiaclinica')}
|
onVolver={() => store.setVista('historiaclinica')}
|
||||||
getAreaName={(areaId) => store.areas.find(a => a.id === areaId)?.nombre || ''}
|
getGrupoName={(grupoId) => store.grupos.find(a => a.id === grupoId)?.nombre || ''}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+161
-161
@@ -1,10 +1,10 @@
|
|||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { getNombreProfesional, isCamaFueraDeArea } from '@/lib/utils';
|
import { getNombreProfesional, isCamaFueraDeGrupo } from '@/lib/utils';
|
||||||
import type {
|
import type {
|
||||||
Paciente,
|
Paciente,
|
||||||
Cama,
|
Cama,
|
||||||
Area,
|
Grupo,
|
||||||
Internacion,
|
Internacion,
|
||||||
Evolucion,
|
Evolucion,
|
||||||
Laboratorio,
|
Laboratorio,
|
||||||
@@ -36,7 +36,7 @@ function generateUUID(): string {
|
|||||||
interface HospitalState {
|
interface HospitalState {
|
||||||
pacientes: Paciente[];
|
pacientes: Paciente[];
|
||||||
camas: Cama[];
|
camas: Cama[];
|
||||||
areas: Area[];
|
grupos: Grupo[];
|
||||||
internaciones: Internacion[];
|
internaciones: Internacion[];
|
||||||
evoluciones: Evolucion[];
|
evoluciones: Evolucion[];
|
||||||
laboratorios: Laboratorio[];
|
laboratorios: Laboratorio[];
|
||||||
@@ -60,7 +60,7 @@ const API_BASE = import.meta.env.VITE_API_URL || '/api';
|
|||||||
|
|
||||||
const defaultState = (): HospitalState => ({
|
const defaultState = (): HospitalState => ({
|
||||||
pacientes: [],
|
pacientes: [],
|
||||||
areas: [],
|
grupos: [],
|
||||||
internaciones: [],
|
internaciones: [],
|
||||||
evoluciones: [],
|
evoluciones: [],
|
||||||
laboratorios: [],
|
laboratorios: [],
|
||||||
@@ -139,55 +139,55 @@ export function useHospitalStore() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
const getCamaAreaId = 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);
|
||||||
return cama?.areaId || null;
|
return cama?.grupoId || null;
|
||||||
}, [state.camas]);
|
}, [state.camas]);
|
||||||
|
|
||||||
const getInternacionAreaId = useCallback((internacionId: string): string | null => {
|
const getInternacionGrupoId = useCallback((internacionId: string): string | null => {
|
||||||
const internacion = state.internaciones.find(i => i.id === internacionId);
|
const internacion = state.internaciones.find(i => i.id === internacionId);
|
||||||
if (!internacion) return null;
|
if (!internacion) return null;
|
||||||
return internacion.areaId || getCamaAreaId(internacion.camaId) || null;
|
return internacion.grupoId || getCamaGrupoId(internacion.camaId) || null;
|
||||||
}, [state.internaciones, getCamaAreaId]);
|
}, [state.internaciones, getCamaGrupoId]);
|
||||||
|
|
||||||
const getPacienteAreaId = useCallback((pacienteId: string): string | null => {
|
const getPacienteGrupoId = useCallback((pacienteId: string): string | null => {
|
||||||
const internacion = state.internaciones.find(i => i.pacienteId === pacienteId && i.activa);
|
const internacion = state.internaciones.find(i => i.pacienteId === pacienteId && i.activa);
|
||||||
if (!internacion) {
|
if (!internacion) {
|
||||||
const anyInternacion = state.internaciones.find(i => i.pacienteId === pacienteId);
|
const anyInternacion = state.internaciones.find(i => i.pacienteId === pacienteId);
|
||||||
if (anyInternacion) return getCamaAreaId(anyInternacion.camaId);
|
if (anyInternacion) return getCamaGrupoId(anyInternacion.camaId);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return internacion.areaId || getCamaAreaId(internacion.camaId) || null;
|
return internacion.grupoId || getCamaGrupoId(internacion.camaId) || null;
|
||||||
}, [state.internaciones, getCamaAreaId]);
|
}, [state.internaciones, getCamaGrupoId]);
|
||||||
|
|
||||||
// Permission functions
|
// Permission functions
|
||||||
const canAccessArea = useCallback((areaId: string | null | undefined): boolean => {
|
const canAccessGrupo = useCallback((grupoId: string | null | undefined): boolean => {
|
||||||
const user = state.currentUser;
|
const user = state.currentUser;
|
||||||
if (!user) return false;
|
if (!user) return false;
|
||||||
if (user.rol === 'admin') return true;
|
if (user.rol === 'admin') return true;
|
||||||
if (!areaId) return true;
|
if (!grupoId) return true;
|
||||||
if (!user.areaId) return true;
|
if (!user.grupoId) return true;
|
||||||
return user.areaId === areaId;
|
return user.grupoId === grupoId;
|
||||||
}, [state.currentUser]);
|
}, [state.currentUser]);
|
||||||
|
|
||||||
const checkAreaPermission = useCallback((areaId: string | null | undefined): boolean => {
|
const checkGrupoPermission = useCallback((grupoId: string | null | undefined): boolean => {
|
||||||
const allowed = canAccessArea(areaId);
|
const allowed = canAccessGrupo(grupoId);
|
||||||
if (!allowed) {
|
if (!allowed) {
|
||||||
toast.error("no pertenecen al area de trabajo por la que se encuentra internado el paciente");
|
toast.error("no pertenecen al grupo de trabajo por la que se encuentra internado el paciente");
|
||||||
}
|
}
|
||||||
return allowed;
|
return allowed;
|
||||||
}, [canAccessArea]);
|
}, [canAccessGrupo]);
|
||||||
|
|
||||||
const canChangeBed = useCallback((internacionId: string): boolean => {
|
const canChangeBed = useCallback((internacionId: string): boolean => {
|
||||||
const internacion = state.internaciones.find(i => i.id === internacionId);
|
const internacion = state.internaciones.find(i => i.id === internacionId);
|
||||||
if (!internacion) return false;
|
if (!internacion) return false;
|
||||||
return canAccessArea(internacion.areaId);
|
return canAccessGrupo(internacion.grupoId);
|
||||||
}, [state.internaciones, canAccessArea]);
|
}, [state.internaciones, canAccessGrupo]);
|
||||||
|
|
||||||
const canEditInternacion = useCallback((internacionId: string): boolean => {
|
const canEditInternacion = useCallback((internacionId: string): boolean => {
|
||||||
const areaId = getInternacionAreaId(internacionId);
|
const grupoId = getInternacionGrupoId(internacionId);
|
||||||
return canAccessArea(areaId);
|
return canAccessGrupo(grupoId);
|
||||||
}, [getInternacionAreaId, canAccessArea]);
|
}, [getInternacionGrupoId, canAccessGrupo]);
|
||||||
|
|
||||||
const canEditIngreso = useCallback((internacionId: string): boolean => {
|
const canEditIngreso = useCallback((internacionId: string): boolean => {
|
||||||
const internacion = state.internaciones.find(i => i.id === internacionId);
|
const internacion = state.internaciones.find(i => i.id === internacionId);
|
||||||
@@ -201,14 +201,14 @@ export function useHospitalStore() {
|
|||||||
}, [state.internaciones, state.currentUser]);
|
}, [state.internaciones, state.currentUser]);
|
||||||
|
|
||||||
const canEditCama = useCallback((camaId: string): boolean => {
|
const canEditCama = useCallback((camaId: string): boolean => {
|
||||||
const areaId = getCamaAreaId(camaId);
|
const grupoId = getCamaGrupoId(camaId);
|
||||||
return canAccessArea(areaId);
|
return canAccessGrupo(grupoId);
|
||||||
}, [getCamaAreaId, canAccessArea]);
|
}, [getCamaGrupoId, canAccessGrupo]);
|
||||||
|
|
||||||
const canEditPaciente = useCallback((pacienteId: string): boolean => {
|
const canEditPaciente = useCallback((pacienteId: string): boolean => {
|
||||||
const areaId = getPacienteAreaId(pacienteId);
|
const grupoId = getPacienteGrupoId(pacienteId);
|
||||||
return canAccessArea(areaId);
|
return canAccessGrupo(grupoId);
|
||||||
}, [getPacienteAreaId, canAccessArea]);
|
}, [getPacienteGrupoId, canAccessGrupo]);
|
||||||
|
|
||||||
const hasPermission = useCallback((permission: 'read' | 'write', section: string): boolean => {
|
const hasPermission = useCallback((permission: 'read' | 'write', section: string): boolean => {
|
||||||
const user = state.currentUser;
|
const user = state.currentUser;
|
||||||
@@ -219,7 +219,7 @@ export function useHospitalStore() {
|
|||||||
return permission === 'read';
|
return permission === 'read';
|
||||||
}
|
}
|
||||||
if (user.rol === 'medico') {
|
if (user.rol === 'medico') {
|
||||||
if (section === 'miArea') return permission === 'read' || permission === 'write';
|
if (section === 'miGrupo') return permission === 'read' || permission === 'write';
|
||||||
return permission === 'read';
|
return permission === 'read';
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -251,8 +251,8 @@ export function useHospitalStore() {
|
|||||||
}, [apiCall]);
|
}, [apiCall]);
|
||||||
|
|
||||||
const actualizarPaciente = useCallback(async (id: string, datos: Partial<Paciente>) => {
|
const actualizarPaciente = useCallback(async (id: string, datos: Partial<Paciente>) => {
|
||||||
const areaId = getPacienteAreaId(id);
|
const grupoId = getPacienteGrupoId(id);
|
||||||
if (!checkAreaPermission(areaId)) return;
|
if (!checkGrupoPermission(grupoId)) return;
|
||||||
try {
|
try {
|
||||||
await apiCall('PUT', `/pacientes/${id}`, datos);
|
await apiCall('PUT', `/pacientes/${id}`, datos);
|
||||||
setState(prev => ({
|
setState(prev => ({
|
||||||
@@ -263,11 +263,11 @@ export function useHospitalStore() {
|
|||||||
console.error('Error al actualizar paciente:', err);
|
console.error('Error al actualizar paciente:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [apiCall, checkAreaPermission, getPacienteAreaId]);
|
}, [apiCall, checkGrupoPermission, getPacienteGrupoId]);
|
||||||
|
|
||||||
const eliminarPaciente = useCallback(async (id: string) => {
|
const eliminarPaciente = useCallback(async (id: string) => {
|
||||||
const areaId = getPacienteAreaId(id);
|
const grupoId = getPacienteGrupoId(id);
|
||||||
if (!checkAreaPermission(areaId)) return;
|
if (!checkGrupoPermission(grupoId)) return;
|
||||||
try {
|
try {
|
||||||
await apiCall('DELETE', `/pacientes/${id}`);
|
await apiCall('DELETE', `/pacientes/${id}`);
|
||||||
setState(prev => ({
|
setState(prev => ({
|
||||||
@@ -278,15 +278,15 @@ export function useHospitalStore() {
|
|||||||
console.error('Error al eliminar paciente:', err);
|
console.error('Error al eliminar paciente:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [apiCall, checkAreaPermission, getPacienteAreaId]);
|
}, [apiCall, checkGrupoPermission, getPacienteGrupoId]);
|
||||||
|
|
||||||
// Acciones de camas
|
// Acciones de camas
|
||||||
const actualizarCama = useCallback(async (id: string, datos: Partial<Cama>) => {
|
const actualizarCama = useCallback(async (id: string, datos: Partial<Cama>) => {
|
||||||
const cama = state.camas.find(c => c.id === id);
|
const cama = state.camas.find(c => c.id === id);
|
||||||
if (!cama) return;
|
if (!cama) return;
|
||||||
const user = state.currentUser;
|
const user = state.currentUser;
|
||||||
const areaId = cama.areaId || null;
|
const grupoId = cama.grupoId || null;
|
||||||
if (user && user.rol !== 'admin' && areaId && user.areaId !== areaId) {
|
if (user && user.rol !== 'admin' && grupoId && user.grupoId !== grupoId) {
|
||||||
console.warn('No tiene permisos para actualizar cama en esta área');
|
console.warn('No tiene permisos para actualizar cama en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -300,7 +300,7 @@ export function useHospitalStore() {
|
|||||||
console.error('Error al actualizar cama:', err);
|
console.error('Error al actualizar cama:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [state, canAccessArea, apiCall]);
|
}, [state, canAccessGrupo, apiCall]);
|
||||||
|
|
||||||
const agregarCama = useCallback(async (cama: Omit<Cama, 'id'>) => {
|
const agregarCama = useCallback(async (cama: Omit<Cama, 'id'>) => {
|
||||||
const nuevaCama: Cama = {
|
const nuevaCama: Cama = {
|
||||||
@@ -336,7 +336,7 @@ const agregarCama = useCallback(async (cama: Omit<Cama, 'id'>) => {
|
|||||||
|
|
||||||
// Acciones de internaciones
|
// Acciones de internaciones
|
||||||
const iniciarInternacion = useCallback(async (internacion: Omit<Internacion, 'id' | 'activa'>) => {
|
const iniciarInternacion = useCallback(async (internacion: Omit<Internacion, 'id' | 'activa'>) => {
|
||||||
if (!checkAreaPermission(internacion.areaId)) {
|
if (!checkGrupoPermission(internacion.grupoId)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const nuevaInternacion: Internacion = {
|
const nuevaInternacion: Internacion = {
|
||||||
@@ -380,9 +380,9 @@ const finalizarInternacion = useCallback(async (internacionId: string, datos: {
|
|||||||
const internacion = state.internaciones.find(i => i.id === internacionId);
|
const internacion = state.internaciones.find(i => i.id === internacionId);
|
||||||
if (!internacion) return;
|
if (!internacion) return;
|
||||||
|
|
||||||
const areaFueraDeArea = state.areas.find(a => (a.nombre || '').toLowerCase().trim() === 'fuera de area');
|
const grupoFueraDeGrupo = state.grupos.find(a => (a.nombre || '').toLowerCase().trim() === 'fuera de grupo');
|
||||||
const areaFueraDeAreaId = areaFueraDeArea?.id;
|
const grupoFueraDeGrupoId = grupoFueraDeGrupo?.id;
|
||||||
const esFueraDeArea = !internacion.areaId || !areaFueraDeAreaId || internacion.areaId === areaFueraDeAreaId;
|
const esFueraDeGrupo = !internacion.grupoId || !grupoFueraDeGrupoId || internacion.grupoId === grupoFueraDeGrupoId;
|
||||||
const camaId = internacion.camaId;
|
const camaId = internacion.camaId;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -391,7 +391,7 @@ const finalizarInternacion = useCallback(async (internacionId: string, datos: {
|
|||||||
|
|
||||||
// Eliminar o actualizar la cama según el área
|
// Eliminar o actualizar la cama según el área
|
||||||
if (camaId) {
|
if (camaId) {
|
||||||
if (esFueraDeArea) {
|
if (esFueraDeGrupo) {
|
||||||
// Eliminar la cama si es "Fuera de área"
|
// Eliminar la cama si es "Fuera de área"
|
||||||
await apiCall('DELETE', `/camas/${camaId}`);
|
await apiCall('DELETE', `/camas/${camaId}`);
|
||||||
} else {
|
} else {
|
||||||
@@ -411,7 +411,7 @@ const finalizarInternacion = useCallback(async (internacionId: string, datos: {
|
|||||||
? { ...i, ...datos, activa: false }
|
? { ...i, ...datos, activa: false }
|
||||||
: i
|
: i
|
||||||
),
|
),
|
||||||
cams: esFueraDeArea
|
cams: 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
|
||||||
@@ -449,11 +449,11 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
|
|
||||||
if (cambioDeCama && !canChangeBed(internacionId)) {
|
if (cambioDeCama && !canChangeBed(internacionId)) {
|
||||||
console.warn('No tiene permisos para cambiar la cama de esta internación');
|
console.warn('No tiene permisos para cambiar la cama de esta internación');
|
||||||
checkAreaPermission(null); // triggers toast
|
checkGrupoPermission(null); // triggers toast
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cambioDeCama && !checkAreaPermission(internacion.areaId)) {
|
if (!cambioDeCama && !checkGrupoPermission(internacion.grupoId)) {
|
||||||
console.warn('No tiene permisos para actualizar esta internación');
|
console.warn('No tiene permisos para actualizar esta internación');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -497,13 +497,13 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
// Acciones de evoluciones
|
// Acciones de evoluciones
|
||||||
const agregarEvolucion = useCallback(async (evolucion: Omit<Evolucion, 'id'>) => {
|
const agregarEvolucion = useCallback(async (evolucion: Omit<Evolucion, 'id'>) => {
|
||||||
const internacion = state.internaciones.find(i => i.id === evolucion.internacionId);
|
const internacion = state.internaciones.find(i => i.id === evolucion.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para agregar evolución en esta área');
|
console.warn('No tiene permisos para agregar evolución en esta área');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -523,14 +523,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!evolucion) return;
|
if (!evolucion) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === evolucion.internacionId);
|
const internacion = state.internaciones.find(i => i.id === evolucion.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para eliminar evolución en esta área');
|
console.warn('No tiene permisos para eliminar evolución en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -545,14 +545,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!evolucion) return;
|
if (!evolucion) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === evolucion.internacionId);
|
const internacion = state.internaciones.find(i => i.id === evolucion.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para actualizar evolución en esta área');
|
console.warn('No tiene permisos para actualizar evolución en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -567,13 +567,13 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
// Acciones de laboratorios
|
// Acciones de laboratorios
|
||||||
const agregarLaboratorio = useCallback(async (laboratorio: Omit<Laboratorio, 'id'>) => {
|
const agregarLaboratorio = useCallback(async (laboratorio: Omit<Laboratorio, 'id'>) => {
|
||||||
const internacion = state.internaciones.find(i => i.id === laboratorio.internacionId);
|
const internacion = state.internaciones.find(i => i.id === laboratorio.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para agregar laboratorio en esta área');
|
console.warn('No tiene permisos para agregar laboratorio en esta área');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -592,14 +592,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!laboratorio) return;
|
if (!laboratorio) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === laboratorio.internacionId);
|
const internacion = state.internaciones.find(i => i.id === laboratorio.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para eliminar laboratorio en esta área');
|
console.warn('No tiene permisos para eliminar laboratorio en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -613,14 +613,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!laboratorio) return;
|
if (!laboratorio) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === laboratorio.internacionId);
|
const internacion = state.internaciones.find(i => i.id === laboratorio.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para actualizar laboratorio en esta área');
|
console.warn('No tiene permisos para actualizar laboratorio en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -634,13 +634,13 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
// Acciones de glucemias
|
// Acciones de glucemias
|
||||||
const agregarGlucemia = useCallback(async (glucemia: Omit<Glucemia, 'id'>) => {
|
const agregarGlucemia = useCallback(async (glucemia: Omit<Glucemia, 'id'>) => {
|
||||||
const internacion = state.internaciones.find(i => i.id === glucemia.internacionId);
|
const internacion = state.internaciones.find(i => i.id === glucemia.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para agregar glucemia en esta área');
|
console.warn('No tiene permisos para agregar glucemia en esta área');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -659,14 +659,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!glucemia) return;
|
if (!glucemia) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === glucemia.internacionId);
|
const internacion = state.internaciones.find(i => i.id === glucemia.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para eliminar glucemia en esta área');
|
console.warn('No tiene permisos para eliminar glucemia en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -680,14 +680,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!glucemia) return;
|
if (!glucemia) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === glucemia.internacionId);
|
const internacion = state.internaciones.find(i => i.id === glucemia.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para actualizar glucemia en esta área');
|
console.warn('No tiene permisos para actualizar glucemia en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -701,13 +701,13 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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'>) => {
|
||||||
const internacion = state.internaciones.find(i => i.id === acidoBase.internacionId);
|
const internacion = state.internaciones.find(i => i.id === acidoBase.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para agregar ácido-base en esta área');
|
console.warn('No tiene permisos para agregar ácido-base en esta área');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -726,14 +726,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!acidoBase) return;
|
if (!acidoBase) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === acidoBase.internacionId);
|
const internacion = state.internaciones.find(i => i.id === acidoBase.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para actualizar ácido-base en esta área');
|
console.warn('No tiene permisos para actualizar ácido-base en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -747,14 +747,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!acidoBase) return;
|
if (!acidoBase) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === acidoBase.internacionId);
|
const internacion = state.internaciones.find(i => i.id === acidoBase.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para eliminar ácido-base en esta área');
|
console.warn('No tiene permisos para eliminar ácido-base en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -768,13 +768,13 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
// Acciones de cultivos
|
// Acciones de cultivos
|
||||||
const agregarCultivo = useCallback(async (cultivo: Omit<Cultivo, 'id'>) => {
|
const agregarCultivo = useCallback(async (cultivo: Omit<Cultivo, 'id'>) => {
|
||||||
const internacion = state.internaciones.find(i => i.id === cultivo.internacionId);
|
const internacion = state.internaciones.find(i => i.id === cultivo.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para agregar cultivo en esta área');
|
console.warn('No tiene permisos para agregar cultivo en esta área');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -793,14 +793,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!cultivo) return;
|
if (!cultivo) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === cultivo.internacionId);
|
const internacion = state.internaciones.find(i => i.id === cultivo.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para actualizar cultivo en esta área');
|
console.warn('No tiene permisos para actualizar cultivo en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -814,14 +814,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!cultivo) return;
|
if (!cultivo) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === cultivo.internacionId);
|
const internacion = state.internaciones.find(i => i.id === cultivo.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para eliminar cultivo en esta área');
|
console.warn('No tiene permisos para eliminar cultivo en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -835,13 +835,13 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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'>) => {
|
||||||
const internacion = state.internaciones.find(i => i.id === estudio.internacionId);
|
const internacion = state.internaciones.find(i => i.id === estudio.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para agregar estudio complementario en esta área');
|
console.warn('No tiene permisos para agregar estudio complementario en esta área');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -860,14 +860,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!estudio) return;
|
if (!estudio) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === estudio.internacionId);
|
const internacion = state.internaciones.find(i => i.id === estudio.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para actualizar estudio complementario en esta área');
|
console.warn('No tiene permisos para actualizar estudio complementario en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -881,14 +881,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!estudio) return;
|
if (!estudio) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === estudio.internacionId);
|
const internacion = state.internaciones.find(i => i.id === estudio.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para eliminar estudio complementario en esta área');
|
console.warn('No tiene permisos para eliminar estudio complementario en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -902,13 +902,13 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
// Acciones de interconsultas
|
// Acciones de interconsultas
|
||||||
const agregarInterconsulta = useCallback(async (interconsulta: Omit<Interconsulta, 'id'>) => {
|
const agregarInterconsulta = useCallback(async (interconsulta: Omit<Interconsulta, 'id'>) => {
|
||||||
const internacion = state.internaciones.find(i => i.id === interconsulta.internacionId);
|
const internacion = state.internaciones.find(i => i.id === interconsulta.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para agregar interconsulta en esta área');
|
console.warn('No tiene permisos para agregar interconsulta en esta área');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -924,14 +924,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!interconsulta) return;
|
if (!interconsulta) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === interconsulta.internacionId);
|
const internacion = state.internaciones.find(i => i.id === interconsulta.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para actualizar interconsulta en esta área');
|
console.warn('No tiene permisos para actualizar interconsulta en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -945,14 +945,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!interconsulta) return;
|
if (!interconsulta) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === interconsulta.internacionId);
|
const internacion = state.internaciones.find(i => i.id === interconsulta.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para eliminar interconsulta en esta área');
|
console.warn('No tiene permisos para eliminar interconsulta en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -966,12 +966,12 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para agregar ATB en esta área');
|
console.warn('No tiene permisos para agregar ATB en esta área');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -987,14 +987,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!atb) return;
|
if (!atb) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === atb.internacionId);
|
const internacion = state.internaciones.find(i => i.id === atb.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para actualizar ATB en esta área');
|
console.warn('No tiene permisos para actualizar ATB en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1008,14 +1008,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
if (!atb) return;
|
if (!atb) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === atb.internacionId);
|
const internacion = state.internaciones.find(i => i.id === atb.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para eliminar ATB en esta área');
|
console.warn('No tiene permisos para eliminar ATB en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1029,12 +1029,12 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, 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);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para agregar indicación en esta área');
|
console.warn('No tiene permisos para agregar indicación en esta área');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -1050,14 +1050,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state.internaciones, canAccessGrupo, 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);
|
||||||
if (!indicacion) return;
|
if (!indicacion) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === indicacion.internacionId);
|
const internacion = state.internaciones.find(i => i.id === indicacion.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para actualizar indicación en esta área');
|
console.warn('No tiene permisos para actualizar indicación en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1071,14 +1071,14 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state.indicaciones, state.internaciones, canAccessGrupo, 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);
|
||||||
if (!indicacion) return;
|
if (!indicacion) return;
|
||||||
const internacion = state.internaciones.find(i => i.id === indicacion.internacionId);
|
const internacion = state.internaciones.find(i => i.id === indicacion.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para eliminar indicación en esta área');
|
console.warn('No tiene permisos para eliminar indicación en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1092,12 +1092,12 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state.indicaciones, state.internaciones, canAccessGrupo, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const agregarMovimientoIndicacion = useCallback(async (movimiento: any) => {
|
const agregarMovimientoIndicacion = useCallback(async (movimiento: any) => {
|
||||||
const internacion = state.internaciones.find(i => i.id === movimiento.internacionId);
|
const internacion = state.internaciones.find(i => i.id === movimiento.internacionId);
|
||||||
const areaId = internacion?.areaId || null;
|
const grupoId = internacion?.grupoId || null;
|
||||||
if (!checkAreaPermission(areaId)) {
|
if (!checkGrupoPermission(grupoId)) {
|
||||||
console.warn('No tiene permisos para agregar movimiento de indicación en esta área');
|
console.warn('No tiene permisos para agregar movimiento de indicación en esta área');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1112,7 +1112,7 @@ 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, canAccessArea, checkAreaPermission, apiCall]);
|
}, [state, canAccessGrupo, checkGrupoPermission, apiCall]);
|
||||||
|
|
||||||
const getMovimientosByInternacion = useCallback((internacionId: string) => {
|
const getMovimientosByInternacion = useCallback((internacionId: string) => {
|
||||||
return (state.movimientosIndicaciones || [])
|
return (state.movimientosIndicaciones || [])
|
||||||
@@ -1120,28 +1120,28 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
.sort((a: any, b: any) => new Date(b.fecha).getTime() - new Date(a.fecha).getTime());
|
.sort((a: any, b: any) => new Date(b.fecha).getTime() - new Date(a.fecha).getTime());
|
||||||
}, [state.movimientosIndicaciones]);
|
}, [state.movimientosIndicaciones]);
|
||||||
|
|
||||||
// Acciones de areas
|
// Acciones de grupos
|
||||||
const agregarArea = useCallback(async (area: Omit<Area, 'id'>) => {
|
const agregarGrupo = useCallback(async (grupo: Omit<Grupo, 'id'>) => {
|
||||||
const nuevaArea: Area = { ...area, id: generateUUID() };
|
const nuevaGrupo: Grupo = { ...grupo, id: generateUUID() };
|
||||||
try {
|
try {
|
||||||
await apiCall('POST', '/areas', nuevaArea);
|
await apiCall('POST', '/grupos', nuevaGrupo);
|
||||||
setState(prev => ({
|
setState(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
areas: [...prev.areas, nuevaArea],
|
grupos: [...prev.grupos, nuevaGrupo],
|
||||||
}));
|
}));
|
||||||
return nuevaArea.id;
|
return nuevaGrupo.id;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error al agregar área:', err);
|
console.error('Error al agregar área:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}, [apiCall]);
|
}, [apiCall]);
|
||||||
|
|
||||||
const actualizarArea = useCallback(async (id: string, datos: Partial<Area>) => {
|
const actualizarGrupo = useCallback(async (id: string, datos: Partial<Grupo>) => {
|
||||||
try {
|
try {
|
||||||
await apiCall('PUT', `/areas/${id}`, datos);
|
await apiCall('PUT', `/grupos/${id}`, datos);
|
||||||
setState(prev => ({
|
setState(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
areas: prev.areas.map(a => a.id === id ? { ...a, ...datos } : a),
|
grupos: prev.grupos.map(a => a.id === id ? { ...a, ...datos } : a),
|
||||||
}));
|
}));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error al actualizar área:', err);
|
console.error('Error al actualizar área:', err);
|
||||||
@@ -1149,13 +1149,13 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
}
|
}
|
||||||
}, [apiCall]);
|
}, [apiCall]);
|
||||||
|
|
||||||
const eliminarArea = useCallback(async (id: string) => {
|
const eliminarGrupo = useCallback(async (id: string) => {
|
||||||
try {
|
try {
|
||||||
await apiCall('DELETE', `/areas/${id}`);
|
await apiCall('DELETE', `/grupos/${id}`);
|
||||||
setState(prev => ({
|
setState(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
areas: prev.areas.filter(a => a.id !== id),
|
grupos: prev.grupos.filter(a => a.id !== id),
|
||||||
camas: prev.camas.map(c => c.areaId === id ? { ...c, areaId: undefined } : c),
|
camas: prev.camas.map(c => c.grupoId === id ? { ...c, grupoId: undefined } : c),
|
||||||
}));
|
}));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error al eliminar área:', err);
|
console.error('Error al eliminar área:', err);
|
||||||
@@ -1211,11 +1211,11 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
}, [state.cultivos]);
|
}, [state.cultivos]);
|
||||||
|
|
||||||
const getEstadisticas = useCallback(() => {
|
const getEstadisticas = useCallback(() => {
|
||||||
const fueraDeAreaList = state.camas.filter(c => isCamaFueraDeArea(c, state.areas));
|
const fueraDeGrupoList = state.camas.filter(c => isCamaFueraDeGrupo(c, state.grupos));
|
||||||
const camasActivas = state.camas.filter(c => !isCamaFueraDeArea(c, state.areas));
|
const camasActivas = state.camas.filter(c => !isCamaFueraDeGrupo(c, state.grupos));
|
||||||
const camaPrincipal = state.camas.filter(c => !isCamaFueraDeArea(c, state.areas));
|
const camaPrincipal = state.camas.filter(c => !isCamaFueraDeGrupo(c, state.grupos));
|
||||||
const camaOcupadas = state.camas.filter(c => c.estado === 'Ocupada' && !isCamaFueraDeArea(c, state.areas)).length;
|
const camaOcupadas = state.camas.filter(c => c.estado === 'Ocupada' && !isCamaFueraDeGrupo(c, state.grupos)).length;
|
||||||
const camasDisponibles = state.camas.filter(c => c.estado === 'Disponible' && !isCamaFueraDeArea(c, state.areas)).length;
|
const camasDisponibles = state.camas.filter(c => c.estado === 'Disponible' && !isCamaFueraDeGrupo(c, state.grupos)).length;
|
||||||
const camasMantenimiento = state.camas.filter(c => c.estado === 'Reparacion').length;
|
const camasMantenimiento = state.camas.filter(c => c.estado === 'Reparacion').length;
|
||||||
const internacionesActivas = state.internaciones.filter(i => i.activa).length;
|
const internacionesActivas = state.internaciones.filter(i => i.activa).length;
|
||||||
const totalPacientes = state.pacientes.length;
|
const totalPacientes = state.pacientes.length;
|
||||||
@@ -1228,7 +1228,7 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
camasMantenimiento,
|
camasMantenimiento,
|
||||||
totalCamas: state.camas.length,
|
totalCamas: state.camas.length,
|
||||||
totalCamasActivas: camasActivas.length,
|
totalCamasActivas: camasActivas.length,
|
||||||
camasFueraDeArea: fueraDeAreaList.length,
|
camasFueraDeGrupo: fueraDeGrupoList.length,
|
||||||
internacionesActivas,
|
internacionesActivas,
|
||||||
totalPacientes,
|
totalPacientes,
|
||||||
cultivosPendientes,
|
cultivosPendientes,
|
||||||
@@ -1338,9 +1338,9 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
eliminarIndicacion,
|
eliminarIndicacion,
|
||||||
agregarMovimientoIndicacion,
|
agregarMovimientoIndicacion,
|
||||||
getMovimientosByInternacion,
|
getMovimientosByInternacion,
|
||||||
agregarArea,
|
agregarGrupo,
|
||||||
actualizarArea,
|
actualizarGrupo,
|
||||||
eliminarArea,
|
eliminarGrupo,
|
||||||
getPacienteById,
|
getPacienteById,
|
||||||
getCamaById,
|
getCamaById,
|
||||||
getInternacionById,
|
getInternacionById,
|
||||||
@@ -1357,14 +1357,14 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
changePassword,
|
changePassword,
|
||||||
updateEmail,
|
updateEmail,
|
||||||
hasPermission,
|
hasPermission,
|
||||||
canAccessArea,
|
canAccessGrupo,
|
||||||
canChangeBed,
|
canChangeBed,
|
||||||
canEditInternacion,
|
canEditInternacion,
|
||||||
canEditIngreso,
|
canEditIngreso,
|
||||||
canEditCama,
|
canEditCama,
|
||||||
canEditPaciente,
|
canEditPaciente,
|
||||||
getCamaAreaId,
|
getCamaGrupoId,
|
||||||
getInternacionAreaId,
|
getInternacionGrupoId,
|
||||||
getPacienteAreaId,
|
getPacienteGrupoId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-9
@@ -38,20 +38,23 @@ export function calcularEdad(fechaNacimiento?: string): string | number {
|
|||||||
return edad;
|
return edad;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isCamaFueraDeArea(
|
export function isCamaFueraDeGrupo(
|
||||||
cama: { numero: string; areaId?: string },
|
cama: { numero: string; grupoId?: string; areaId?: string },
|
||||||
areas?: { id: string; nombre: string }[]
|
gruposOrAreas?: { id: string; nombre: string }[]
|
||||||
): boolean {
|
): boolean {
|
||||||
if (cama.areaId === 'Fuera de Area') {
|
if (cama.grupoId === 'Fuera de Area' || cama.areaId === 'Fuera de Area') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (areas && cama.areaId) {
|
if (gruposOrAreas) {
|
||||||
const area = areas.find(a => (a.nombre || '').toLowerCase().trim() === 'fuera de area');
|
const targetId = cama.grupoId || cama.areaId;
|
||||||
if (area && cama.areaId === area.id) {
|
if (targetId) {
|
||||||
|
const g = gruposOrAreas.find(a => (a.nombre || '').toLowerCase().trim() === 'fuera de area');
|
||||||
|
if (g && targetId === g.id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const numero = cama.numero;
|
const numero = cama.numero;
|
||||||
if (!numero) return false;
|
if (!numero) return false;
|
||||||
@@ -61,12 +64,12 @@ export function isCamaFueraDeArea(
|
|||||||
const salaNum = parseInt(salaStr, 10);
|
const salaNum = parseInt(salaStr, 10);
|
||||||
if (isNaN(salaNum)) return false;
|
if (isNaN(salaNum)) return false;
|
||||||
|
|
||||||
// Formato 3XX que sean impares
|
// Formato 3XX que sean impares (301, 303, 305, etc.)
|
||||||
if (salaNum >= 300 && salaNum < 400 && salaNum % 2 !== 0) {
|
if (salaNum >= 300 && salaNum < 400 && salaNum % 2 !== 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todas las 4XX (sean pares o impares)
|
// Formato 4XX (todas las 4XX, pares o impares)
|
||||||
if (salaNum >= 400 && salaNum < 500) {
|
if (salaNum >= 400 && salaNum < 500) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ export function Dashboard({
|
|||||||
<span className="text-3xl font-bold">{estadisticas.camasFueraDeArea}</span>
|
<span className="text-3xl font-bold">{estadisticas.camasFueraDeArea}</span>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-xs text-gray-400 dark:text-gray-400 mt-1">
|
<p className="text-xs text-gray-400 dark:text-gray-400 mt-1">
|
||||||
Camas Fuera de Area
|
Camas Fuera de Grupo
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { Label } from '@/components/ui/label';
|
|||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import type { Paciente, Cama, Area, Internacion } from '@/types';
|
import type { Paciente, Cama, Grupo, Internacion } from '@/types';
|
||||||
import { getNombreProfesional, calcularEdad } from '@/lib/utils';
|
import { getNombreProfesional, calcularEdad } from '@/lib/utils';
|
||||||
import { useHospitalStore } from '@/hooks/useHospitalStore';
|
import { useHospitalStore } from '@/hooks/useHospitalStore';
|
||||||
|
|
||||||
@@ -17,18 +17,18 @@ interface EditIngresoProps {
|
|||||||
cama?: Cama;
|
cama?: Cama;
|
||||||
pacientes: Paciente[];
|
pacientes: Paciente[];
|
||||||
camas: Cama[];
|
camas: Cama[];
|
||||||
areas: Area[];
|
grupos: Grupo[];
|
||||||
onActualizarInternacion: (id: string, datos: Partial<Internacion>) => Promise<void> | void;
|
onActualizarInternacion: (id: string, datos: Partial<Internacion>) => Promise<void> | void;
|
||||||
onAgregarCama?: (cama: Omit<Cama, 'id'>) => Promise<string>;
|
onAgregarCama?: (cama: Omit<Cama, 'id'>) => Promise<string>;
|
||||||
onVolver: () => void;
|
onVolver: () => void;
|
||||||
getAreaName: (areaId: string | undefined) => string;
|
getGrupoName: (grupoId: string | undefined) => string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function EditIngreso({
|
export function EditIngreso({
|
||||||
internacion,
|
internacion,
|
||||||
pacientes,
|
pacientes,
|
||||||
camas,
|
camas,
|
||||||
areas,
|
grupos,
|
||||||
onActualizarInternacion,
|
onActualizarInternacion,
|
||||||
onAgregarCama,
|
onAgregarCama,
|
||||||
onVolver,
|
onVolver,
|
||||||
@@ -36,7 +36,7 @@ export function EditIngreso({
|
|||||||
const { currentUser } = useHospitalStore();
|
const { currentUser } = useHospitalStore();
|
||||||
const [pacienteSeleccionado] = useState(internacion.pacienteId);
|
const [pacienteSeleccionado] = useState(internacion.pacienteId);
|
||||||
const [camaSeleccionada] = useState(internacion.camaId);
|
const [camaSeleccionada] = useState(internacion.camaId);
|
||||||
const [areaSeleccionada] = useState(internacion.areaId);
|
const [grupoSeleccionada] = useState(internacion.grupoId);
|
||||||
const [camaInput, setCamaInput] = useState('');
|
const [camaInput, setCamaInput] = useState('');
|
||||||
const [modoCama, setModoCama] = useState<'seleccionar' | 'escribir'>('seleccionar');
|
const [modoCama, setModoCama] = useState<'seleccionar' | 'escribir'>('seleccionar');
|
||||||
const effectiveMedico = getNombreProfesional(currentUser);
|
const effectiveMedico = getNombreProfesional(currentUser);
|
||||||
@@ -52,8 +52,8 @@ export function EditIngreso({
|
|||||||
|
|
||||||
const selectedPaciente = pacientes.find(p => p.id === pacienteSeleccionado);
|
const selectedPaciente = pacientes.find(p => p.id === pacienteSeleccionado);
|
||||||
const normalizeStr = (str?: string) => (str || '').normalize('NFD').replace(/[\u0300-\u036f]/g, '').trim().toLowerCase();
|
const normalizeStr = (str?: string) => (str || '').normalize('NFD').replace(/[\u0300-\u036f]/g, '').trim().toLowerCase();
|
||||||
const areaFueraDeArea = areas.find(a => normalizeStr(a.nombre) === 'fuera de area');
|
const grupoFueraDeGrupo = grupos.find(a => normalizeStr(a.nombre) === 'fuera de grupo');
|
||||||
const areaFueraDeAreaId = areaFueraDeArea?.id || areas[0]?.id || 'fuera-de-area';
|
const grupoFueraDeGrupoId = grupoFueraDeGrupo?.id || grupos[0]?.id || 'fuera-de-grupo';
|
||||||
|
|
||||||
const parseBedNumber = (numero: string) => {
|
const parseBedNumber = (numero: string) => {
|
||||||
const match = numero.match(/^(\d{3})-(\d+)$/);
|
const match = numero.match(/^(\d{3})-(\d+)$/);
|
||||||
@@ -123,7 +123,7 @@ export function EditIngreso({
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
let camaId = '';
|
let camaId = '';
|
||||||
let newAreaId = '';
|
let newGrupoId = '';
|
||||||
|
|
||||||
if (modoCama === 'escribir') {
|
if (modoCama === 'escribir') {
|
||||||
if (!camaInput.trim()) {
|
if (!camaInput.trim()) {
|
||||||
@@ -135,15 +135,15 @@ export function EditIngreso({
|
|||||||
const camaExistente = camas.find(c => c.numero === numeroCama);
|
const camaExistente = camas.find(c => c.numero === numeroCama);
|
||||||
if (camaExistente) {
|
if (camaExistente) {
|
||||||
camaId = camaExistente.id;
|
camaId = camaExistente.id;
|
||||||
newAreaId = camaExistente.areaId || areaFueraDeAreaId;
|
newGrupoId = camaExistente.grupoId || grupoFueraDeGrupoId;
|
||||||
} else if (onAgregarCama) {
|
} else if (onAgregarCama) {
|
||||||
camaId = await onAgregarCama({
|
camaId = await onAgregarCama({
|
||||||
numero: numeroCama,
|
numero: numeroCama,
|
||||||
areaId: areaFueraDeAreaId,
|
grupoId: grupoFueraDeGrupoId,
|
||||||
tipo: 'General',
|
tipo: 'General',
|
||||||
estado: 'Ocupada'
|
estado: 'Ocupada'
|
||||||
});
|
});
|
||||||
newAreaId = areaFueraDeAreaId;
|
newGrupoId = grupoFueraDeGrupoId;
|
||||||
} else {
|
} else {
|
||||||
toast.error('No se puede crear la cama');
|
toast.error('No se puede crear la cama');
|
||||||
setIsSubmitting(false);
|
setIsSubmitting(false);
|
||||||
@@ -157,10 +157,10 @@ export function EditIngreso({
|
|||||||
setIsSubmitting(false);
|
setIsSubmitting(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
newAreaId = camaElegida.areaId || areaFueraDeAreaId;
|
newGrupoId = camaElegida.grupoId || grupoFueraDeGrupoId;
|
||||||
camaId = camaSeleccionada;
|
camaId = camaSeleccionada;
|
||||||
} else {
|
} else {
|
||||||
newAreaId = areaSeleccionada || internacion.areaId || areaFueraDeAreaId;
|
newGrupoId = grupoSeleccionada || internacion.grupoId || grupoFueraDeGrupoId;
|
||||||
camaId = internacion.camaId;
|
camaId = internacion.camaId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,7 +168,7 @@ export function EditIngreso({
|
|||||||
await onActualizarInternacion(internacion.id, {
|
await onActualizarInternacion(internacion.id, {
|
||||||
pacienteId: pacienteSeleccionado,
|
pacienteId: pacienteSeleccionado,
|
||||||
camaId: camaId,
|
camaId: camaId,
|
||||||
areaId: newAreaId,
|
grupoId: newGrupoId,
|
||||||
medicoIngresante: effectiveMedico.trim(),
|
medicoIngresante: effectiveMedico.trim(),
|
||||||
diagnosticoIngreso: diagnosticoIngreso.trim(),
|
diagnosticoIngreso: diagnosticoIngreso.trim(),
|
||||||
motivoConsulta: motivoConsulta.trim() || undefined,
|
motivoConsulta: motivoConsulta.trim() || undefined,
|
||||||
@@ -290,13 +290,13 @@ export function EditIngreso({
|
|||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Columna 2: Cama y Área */}
|
{/* Columna 2: Cama y Grupo */}
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<Card className="min-h-[200px]">
|
<Card className="min-h-[200px]">
|
||||||
<CardContent className="pt-6 space-y-4">
|
<CardContent className="pt-6 space-y-4">
|
||||||
<h3 className="font-semibold text-gray-900 dark:text-white flex items-center gap-2">
|
<h3 className="font-semibold text-gray-900 dark:text-white flex items-center gap-2">
|
||||||
<Bed className="h-4 w-4" />
|
<Bed className="h-4 w-4" />
|
||||||
Asignación de Cama y Área
|
Asignación de Cama y Grupo
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div className="flex gap-2 mb-4">
|
<div className="flex gap-2 mb-4">
|
||||||
@@ -325,7 +325,7 @@ export function EditIngreso({
|
|||||||
<SelectContent>
|
<SelectContent>
|
||||||
{sortedCamas.map(c => (
|
{sortedCamas.map(c => (
|
||||||
<SelectItem key={c.id} value={c.id}>
|
<SelectItem key={c.id} value={c.id}>
|
||||||
{c.numero} - {getAreaName(c.areaId)}
|
{c.numero} - {getGrupoName(c.grupoId)}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { useHospitalStore } from '@/hooks/useHospitalStore';
|
import { useHospitalStore } from '@/hooks/useHospitalStore';
|
||||||
import type { Usuario, RolUsuario, Area } from '@/types';
|
import type { Usuario, RolUsuario, Grupo } from '@/types';
|
||||||
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';
|
||||||
@@ -16,7 +16,7 @@ const API_BASE = import.meta.env.VITE_API_URL || '/api';
|
|||||||
export function GestionUsuarios() {
|
export function GestionUsuarios() {
|
||||||
const { currentUser } = useHospitalStore();
|
const { currentUser } = useHospitalStore();
|
||||||
const [usuarios, setUsuarios] = useState<Usuario[]>([]);
|
const [usuarios, setUsuarios] = useState<Usuario[]>([]);
|
||||||
const [areas, setAreas] = useState<Area[]>([]);
|
const [grupos, setGrupos] = useState<Grupo[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [dialogOpen, setDialogOpen] = useState(false);
|
const [dialogOpen, setDialogOpen] = useState(false);
|
||||||
const [editUsuario, setEditUsuario] = useState<Usuario | null>(null);
|
const [editUsuario, setEditUsuario] = useState<Usuario | null>(null);
|
||||||
@@ -30,12 +30,12 @@ export function GestionUsuarios() {
|
|||||||
rol: 'medico' as RolUsuario,
|
rol: 'medico' as RolUsuario,
|
||||||
matriculaProfesional: '',
|
matriculaProfesional: '',
|
||||||
password: '',
|
password: '',
|
||||||
areaId: '',
|
grupoId: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchUsuarios();
|
fetchUsuarios();
|
||||||
fetchAreas();
|
fetchGrupos();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const fetchUsuarios = async () => {
|
const fetchUsuarios = async () => {
|
||||||
@@ -50,11 +50,11 @@ export function GestionUsuarios() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchAreas = async () => {
|
const fetchGrupos = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${API_BASE}/areas`);
|
const res = await fetch(`${API_BASE}/grupos`);
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
setAreas(data);
|
setGrupos(data);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ export function GestionUsuarios() {
|
|||||||
rol: 'medico',
|
rol: 'medico',
|
||||||
matriculaProfesional: '',
|
matriculaProfesional: '',
|
||||||
password: '',
|
password: '',
|
||||||
areaId: '',
|
grupoId: '',
|
||||||
});
|
});
|
||||||
setEditUsuario(null);
|
setEditUsuario(null);
|
||||||
};
|
};
|
||||||
@@ -86,7 +86,7 @@ export function GestionUsuarios() {
|
|||||||
rol: usu.rol,
|
rol: usu.rol,
|
||||||
matriculaProfesional: usu.matriculaProfesional || '',
|
matriculaProfesional: usu.matriculaProfesional || '',
|
||||||
password: '',
|
password: '',
|
||||||
areaId: usu.areaId || '',
|
grupoId: usu.grupoId || '',
|
||||||
});
|
});
|
||||||
setDialogOpen(true);
|
setDialogOpen(true);
|
||||||
};
|
};
|
||||||
@@ -152,9 +152,9 @@ export function GestionUsuarios() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAreaName = (areaId?: string) => {
|
const getGrupoName = (grupoId?: string) => {
|
||||||
if (!areaId) return '-';
|
if (!grupoId) return '-';
|
||||||
return areas.find(a => a.id === areaId)?.nombre || '-';
|
return grupos.find(a => a.id === grupoId)?.nombre || '-';
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!currentUser || currentUser.rol !== 'admin') {
|
if (!currentUser || currentUser.rol !== 'admin') {
|
||||||
@@ -191,7 +191,7 @@ export function GestionUsuarios() {
|
|||||||
<TableHead>Apellido, Nombre</TableHead>
|
<TableHead>Apellido, Nombre</TableHead>
|
||||||
<TableHead>DNI</TableHead>
|
<TableHead>DNI</TableHead>
|
||||||
<TableHead>Rol</TableHead>
|
<TableHead>Rol</TableHead>
|
||||||
<TableHead>Área</TableHead>
|
<TableHead>Grupo</TableHead>
|
||||||
<TableHead>Email</TableHead>
|
<TableHead>Email</TableHead>
|
||||||
<TableHead>Matrícula</TableHead>
|
<TableHead>Matrícula</TableHead>
|
||||||
<TableHead>Acciones</TableHead>
|
<TableHead>Acciones</TableHead>
|
||||||
@@ -207,7 +207,7 @@ export function GestionUsuarios() {
|
|||||||
{getRolLabel(usu.rol)}
|
{getRolLabel(usu.rol)}
|
||||||
</Badge>
|
</Badge>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>{getAreaName(usu.areaId)}</TableCell>
|
<TableCell>{getGrupoName(usu.grupoId)}</TableCell>
|
||||||
<TableCell>{usu.email || '-'}</TableCell>
|
<TableCell>{usu.email || '-'}</TableCell>
|
||||||
<TableCell>{usu.matriculaProfesional || '-'}</TableCell>
|
<TableCell>{usu.matriculaProfesional || '-'}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
@@ -245,8 +245,8 @@ export function GestionUsuarios() {
|
|||||||
|
|
||||||
<div className="grid grid-cols-2 gap-2 text-sm pt-2 border-t border-gray-100 dark:border-gray-800">
|
<div className="grid grid-cols-2 gap-2 text-sm pt-2 border-t border-gray-100 dark:border-gray-800">
|
||||||
<div>
|
<div>
|
||||||
<span className="text-xs text-gray-400 block">Área</span>
|
<span className="text-xs text-gray-400 block">Grupo</span>
|
||||||
<span className="font-medium text-gray-700 dark:text-gray-300">{getAreaName(usu.areaId)}</span>
|
<span className="font-medium text-gray-700 dark:text-gray-300">{getGrupoName(usu.grupoId)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span className="text-xs text-gray-400 block">Matrícula</span>
|
<span className="text-xs text-gray-400 block">Matrícula</span>
|
||||||
@@ -329,14 +329,14 @@ export function GestionUsuarios() {
|
|||||||
|
|
||||||
{form.rol !== 'admin' && (
|
{form.rol !== 'admin' && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Área Asignada</Label>
|
<Label>Grupo Asignado</Label>
|
||||||
<Select value={form.areaId} onValueChange={(v) => setForm({ ...form, areaId: v })}>
|
<Select value={form.grupoId} onValueChange={(v) => setForm({ ...form, grupoId: v })}>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="Seleccionar área" />
|
<SelectValue placeholder="Seleccionar área" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{areas.map((area) => (
|
{grupos.map((grupo) => (
|
||||||
<SelectItem key={area.id} value={area.id}>{area.nombre}</SelectItem>
|
<SelectItem key={grupo.id} value={grupo.id}>{grupo.nombre}</SelectItem>
|
||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
|
|||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import type { Internacion, Paciente, Cama, Area, Evolucion, Laboratorio, Cultivo } from '@/types';
|
import type { Internacion, Paciente, Cama, Grupo, Evolucion, Laboratorio, Cultivo } from '@/types';
|
||||||
import { formatDateDDMMYYYY, getNombreProfesional } from '@/lib/utils';
|
import { formatDateDDMMYYYY, getNombreProfesional } from '@/lib/utils';
|
||||||
import { useHospitalStore } from '@/hooks/useHospitalStore';
|
import { useHospitalStore } from '@/hooks/useHospitalStore';
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ interface InternacionesProps {
|
|||||||
evoluciones?: Evolucion[];
|
evoluciones?: Evolucion[];
|
||||||
laboratorios?: Laboratorio[];
|
laboratorios?: Laboratorio[];
|
||||||
cultivos?: Cultivo[];
|
cultivos?: Cultivo[];
|
||||||
areas: Area[];
|
grupos: Grupo[];
|
||||||
onIniciarInternacion: (internacion: Omit<Internacion, 'id' | 'activa'>) => void;
|
onIniciarInternacion: (internacion: Omit<Internacion, 'id' | 'activa'>) => void;
|
||||||
onFinalizarInternacion: (internacionId: string, datos: {
|
onFinalizarInternacion: (internacionId: string, datos: {
|
||||||
fechaEgreso: string;
|
fechaEgreso: string;
|
||||||
@@ -42,7 +42,7 @@ export function Internaciones({
|
|||||||
onFinalizarInternacion,
|
onFinalizarInternacion,
|
||||||
getPacienteById,
|
getPacienteById,
|
||||||
getCamaById,
|
getCamaById,
|
||||||
areas,
|
grupos,
|
||||||
onVerHC,
|
onVerHC,
|
||||||
onNuevoIngreso,
|
onNuevoIngreso,
|
||||||
}: InternacionesProps) {
|
}: InternacionesProps) {
|
||||||
@@ -54,7 +54,7 @@ export function Internaciones({
|
|||||||
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>('');
|
||||||
const [areaSeleccionada, setAreaSeleccionada] = useState<string>('');
|
const [grupoSeleccionada, setGrupoSeleccionada] = useState<string>('');
|
||||||
const [diagnosticoIngreso, setDiagnosticoIngreso] = useState('');
|
const [diagnosticoIngreso, setDiagnosticoIngreso] = useState('');
|
||||||
const [enfermedadActual, setEnfermedadActual] = useState('');
|
const [enfermedadActual, setEnfermedadActual] = useState('');
|
||||||
const [motivoConsulta, setMotivoConsulta] = useState('');
|
const [motivoConsulta, setMotivoConsulta] = useState('');
|
||||||
@@ -69,7 +69,7 @@ export function Internaciones({
|
|||||||
const resetFormularioNueva = () => {
|
const resetFormularioNueva = () => {
|
||||||
setPacienteSeleccionado('');
|
setPacienteSeleccionado('');
|
||||||
setCamaSeleccionada('');
|
setCamaSeleccionada('');
|
||||||
setAreaSeleccionada('');
|
setGrupoSeleccionada('');
|
||||||
setDiagnosticoIngreso('');
|
setDiagnosticoIngreso('');
|
||||||
setEnfermedadActual('');
|
setEnfermedadActual('');
|
||||||
setAntecedentesEnfermedadActual('');
|
setAntecedentesEnfermedadActual('');
|
||||||
@@ -83,12 +83,12 @@ export function Internaciones({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleIniciarInternacion = async () => {
|
const handleIniciarInternacion = async () => {
|
||||||
if (pacienteSeleccionado && camaSeleccionada && areaSeleccionada && (diagnosticoIngreso || motivoConsulta) && enfermedadActual && effectiveMedico) {
|
if (pacienteSeleccionado && camaSeleccionada && grupoSeleccionada && (diagnosticoIngreso || motivoConsulta) && enfermedadActual && effectiveMedico) {
|
||||||
try {
|
try {
|
||||||
await onIniciarInternacion({
|
await onIniciarInternacion({
|
||||||
pacienteId: pacienteSeleccionado,
|
pacienteId: pacienteSeleccionado,
|
||||||
camaId: camaSeleccionada,
|
camaId: camaSeleccionada,
|
||||||
areaId: areaSeleccionada,
|
grupoId: grupoSeleccionada,
|
||||||
diagnosticoIngreso: diagnosticoIngreso || motivoConsulta,
|
diagnosticoIngreso: diagnosticoIngreso || motivoConsulta,
|
||||||
motivoConsulta,
|
motivoConsulta,
|
||||||
enfermedadActual,
|
enfermedadActual,
|
||||||
@@ -166,7 +166,7 @@ export function Internaciones({
|
|||||||
return oa.suborden - ob.suborden;
|
return oa.suborden - ob.suborden;
|
||||||
});
|
});
|
||||||
|
|
||||||
const getAreaName = (areaId?: string) => areas.find(a => a.id === areaId)?.nombre;
|
const getGrupoName = (grupoId?: string) => grupos.find(a => a.id === grupoId)?.nombre;
|
||||||
|
|
||||||
const calcularEdad = (fechaNacimiento?: string) => {
|
const calcularEdad = (fechaNacimiento?: string) => {
|
||||||
if (!fechaNacimiento) return '-';
|
if (!fechaNacimiento) return '-';
|
||||||
@@ -286,13 +286,13 @@ export function Internaciones({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label>Área de Trabajo *</Label>
|
<Label>Grupo de Trabajo *</Label>
|
||||||
<Select value={areaSeleccionada} onValueChange={setAreaSeleccionada}>
|
<Select value={grupoSeleccionada} onValueChange={setGrupoSeleccionada}>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="Seleccionar área" />
|
<SelectValue placeholder="Seleccionar área" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{areas.filter(a => a.nombre !== 'Fuera de area').map(a => (
|
{grupos.filter(a => a.nombre !== 'Fuera de grupo').map(a => (
|
||||||
<SelectItem key={a.id} value={a.id}>
|
<SelectItem key={a.id} value={a.id}>
|
||||||
{a.nombre}
|
{a.nombre}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
@@ -309,7 +309,7 @@ export function Internaciones({
|
|||||||
<SelectContent>
|
<SelectContent>
|
||||||
{sortedCamas.filter(c => c.estado === 'Disponible').map(c => (
|
{sortedCamas.filter(c => c.estado === 'Disponible').map(c => (
|
||||||
<SelectItem key={c.id} value={c.id}>
|
<SelectItem key={c.id} value={c.id}>
|
||||||
{c.numero} - {getAreaName(c.areaId) || 'Sin área'} ({c.tipo})
|
{c.numero} - {getGrupoName(c.grupoId) || 'Sin grupo'} ({c.tipo})
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
|
|||||||
+62
-62
@@ -3,76 +3,76 @@ import { Bed, CheckCircle2, Clock, Wrench, User, Plus, Trash, Edit2, Save, X } f
|
|||||||
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';
|
||||||
import { formatDateDDMMYYYY, getNombreProfesional, isCamaFueraDeArea } from '@/lib/utils';
|
import { formatDateDDMMYYYY, getNombreProfesional, isCamaFueraDeGrupo } from '@/lib/utils';
|
||||||
|
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } 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 { Label } from '@/components/ui/label';
|
import { Label } from '@/components/ui/label';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import type { Cama, Paciente, Internacion, Area } from '@/types';
|
import type { Cama, Paciente, Internacion, Grupo } from '@/types';
|
||||||
import { useHospitalStore } from '@/hooks/useHospitalStore';
|
import { useHospitalStore } from '@/hooks/useHospitalStore';
|
||||||
|
|
||||||
interface MapaCamasProps {
|
interface MapaCamasProps {
|
||||||
camas: Cama[];
|
camas: Cama[];
|
||||||
areas: Area[];
|
grupos: Grupo[];
|
||||||
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'>) => any;
|
||||||
onEliminarCama: (id: string) => void;
|
onEliminarCama: (id: string) => void;
|
||||||
onIniciarInternacion: (internacion: Omit<Internacion, 'id' | 'activa'>) => Promise<string>;
|
onIniciarInternacion: (internacion: Omit<Internacion, 'id' | 'activa'>) => Promise<string>;
|
||||||
onAgregarArea: (area: Omit<Area, 'id'>) => any;
|
onAgregarGrupo: (grupo: Omit<Grupo, 'id'>) => any;
|
||||||
onActualizarArea: (id: string, datos: Partial<Area>) => void;
|
onActualizarGrupo: (id: string, datos: Partial<Grupo>) => void;
|
||||||
onEliminarArea: (id: string) => void;
|
onEliminarGrupo: (id: string) => void;
|
||||||
getPacienteById: (id: string) => Paciente | undefined;
|
getPacienteById: (id: string) => Paciente | undefined;
|
||||||
getInternacionById: (id: string) => Internacion | undefined;
|
getInternacionById: (id: string) => Internacion | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function MapaCamas({
|
export function MapaCamas({
|
||||||
camas,
|
camas,
|
||||||
areas,
|
grupos,
|
||||||
pacientes,
|
pacientes,
|
||||||
internaciones,
|
internaciones,
|
||||||
onActualizarCama,
|
onActualizarCama,
|
||||||
onAgregarCama,
|
onAgregarCama,
|
||||||
onEliminarCama,
|
onEliminarCama,
|
||||||
onIniciarInternacion,
|
onIniciarInternacion,
|
||||||
onAgregarArea,
|
onAgregarGrupo,
|
||||||
onActualizarArea,
|
onActualizarGrupo,
|
||||||
onEliminarArea,
|
onEliminarGrupo,
|
||||||
getPacienteById,
|
getPacienteById,
|
||||||
getInternacionById
|
getInternacionById
|
||||||
}: MapaCamasProps) {
|
}: MapaCamasProps) {
|
||||||
const { canEditCama, canAccessArea, currentUser } = useHospitalStore();
|
const { canEditCama, canAccessGrupo, 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');
|
||||||
const [camaSeleccionada, setCamaSeleccionada] = useState<Cama | null>(null);
|
const [camaSeleccionada, setCamaSeleccionada] = useState<Cama | null>(null);
|
||||||
const [areaSeleccionada, setAreaSeleccionada] = useState<string>('');
|
const [grupoSeleccionada, setGrupoSeleccionada] = useState<string>('');
|
||||||
const [pacienteSeleccionado, setPacienteSeleccionado] = useState<string>('');
|
const [pacienteSeleccionado, setPacienteSeleccionado] = useState<string>('');
|
||||||
const [diagnostico, setDiagnostico] = useState('');
|
const [diagnostico, setDiagnostico] = useState('');
|
||||||
const [enfermedadActual, setEnfermedadActual] = useState('');
|
const [enfermedadActual, setEnfermedadActual] = useState('');
|
||||||
const [antecedentesEnfermedadActual, setAntecedentesEnfermedadActual] = useState('');
|
const [antecedentesEnfermedadActual, setAntecedentesEnfermedadActual] = useState('');
|
||||||
const effectiveMedico = getNombreProfesional(currentUser);
|
const effectiveMedico = getNombreProfesional(currentUser);
|
||||||
const [dialogoAbierto, setDialogoAbierto] = useState(false);
|
const [dialogoAbierto, setDialogoAbierto] = useState(false);
|
||||||
// Area dialog state
|
// Grupo dialog state
|
||||||
const [areaDialogOpen, setAreaDialogOpen] = useState(false);
|
const [grupoDialogOpen, setGrupoDialogOpen] = useState(false);
|
||||||
const [areaNombre, setAreaNombre] = useState('');
|
const [grupoNombre, setGrupoNombre] = useState('');
|
||||||
const [editingAreaId, setEditingAreaId] = useState<string | null>(null);
|
const [editingGrupoId, setEditingGrupoId] = useState<string | null>(null);
|
||||||
|
|
||||||
// Cama dialog state
|
// Cama dialog state
|
||||||
const [bedDialogOpen, setBedDialogOpen] = useState(false);
|
const [bedDialogOpen, setBedDialogOpen] = useState(false);
|
||||||
const [editingBed, setEditingBed] = useState<Cama | null>(null);
|
const [editingBed, setEditingBed] = useState<Cama | null>(null);
|
||||||
const [bedNumero, setBedNumero] = useState('');
|
const [bedNumero, setBedNumero] = useState('');
|
||||||
const [bedTipo, setBedTipo] = useState<Cama['tipo']>('General');
|
const [bedTipo, setBedTipo] = useState<Cama['tipo']>('General');
|
||||||
const [bedAreaId, setBedAreaId] = useState<string | undefined>(undefined);
|
const [bedGrupoId, setBedGrupoId] = useState<string | undefined>(undefined);
|
||||||
|
|
||||||
const salas = Array.from(new Set(camas.map(c => c.areaId).filter(Boolean))) as string[];
|
const salas = Array.from(new Set(camas.map(c => c.grupoId).filter(Boolean))) as string[];
|
||||||
const areaById = Object.fromEntries(areas.map(a => [a.id, a.nombre]));
|
const grupoById = Object.fromEntries(grupos.map(a => [a.id, a.nombre]));
|
||||||
const tipos = Array.from(new Set(camas.map(c => c.tipo)));
|
const tipos = Array.from(new Set(camas.map(c => c.tipo)));
|
||||||
|
|
||||||
const camasFiltradas = camas.filter(cama => {
|
const camasFiltradas = camas.filter(cama => {
|
||||||
if (filtroSala !== 'todas' && cama.areaId !== filtroSala) return false;
|
if (filtroSala !== 'todas' && cama.grupoId !== filtroSala) return false;
|
||||||
if (filtroTipo !== 'todos' && cama.tipo !== filtroTipo) return false;
|
if (filtroTipo !== 'todos' && cama.tipo !== filtroTipo) return false;
|
||||||
if (filtroEstado !== 'todos' && cama.estado !== filtroEstado) return false;
|
if (filtroEstado !== 'todos' && cama.estado !== filtroEstado) return false;
|
||||||
return true;
|
return true;
|
||||||
@@ -149,11 +149,11 @@ export function MapaCamas({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleOcuparCama = () => {
|
const handleOcuparCama = () => {
|
||||||
if (camaSeleccionada && areaSeleccionada && pacienteSeleccionado && diagnostico && enfermedadActual && effectiveMedico) {
|
if (camaSeleccionada && grupoSeleccionada && pacienteSeleccionado && diagnostico && enfermedadActual && effectiveMedico) {
|
||||||
onIniciarInternacion({
|
onIniciarInternacion({
|
||||||
pacienteId: pacienteSeleccionado,
|
pacienteId: pacienteSeleccionado,
|
||||||
camaId: camaSeleccionada.id,
|
camaId: camaSeleccionada.id,
|
||||||
areaId: areaSeleccionada,
|
grupoId: grupoSeleccionada,
|
||||||
diagnosticoIngreso: diagnostico,
|
diagnosticoIngreso: diagnostico,
|
||||||
enfermedadActual,
|
enfermedadActual,
|
||||||
antecedentesEnfermedadActual: antecedentesEnfermedadActual || undefined,
|
antecedentesEnfermedadActual: antecedentesEnfermedadActual || undefined,
|
||||||
@@ -161,7 +161,7 @@ export function MapaCamas({
|
|||||||
});
|
});
|
||||||
setDialogoAbierto(false);
|
setDialogoAbierto(false);
|
||||||
setCamaSeleccionada(null);
|
setCamaSeleccionada(null);
|
||||||
setAreaSeleccionada('');
|
setGrupoSeleccionada('');
|
||||||
setPacienteSeleccionado('');
|
setPacienteSeleccionado('');
|
||||||
setDiagnostico('');
|
setDiagnostico('');
|
||||||
setEnfermedadActual('');
|
setEnfermedadActual('');
|
||||||
@@ -187,24 +187,24 @@ export function MapaCamas({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Badge variant="outline" className="bg-green-50 text-green-700 dark:bg-green-900 dark:text-green-300 dark:border-green-700">
|
<Badge variant="outline" className="bg-green-50 text-green-700 dark:bg-green-900 dark:text-green-300 dark:border-green-700">
|
||||||
{camas.filter(c => c.estado === 'Disponible' && !isCamaFueraDeArea(c, areas)).length} Disponibles
|
{camas.filter(c => c.estado === 'Disponible' && !isCamaFueraDeGrupo(c, grupos)).length} Disponibles
|
||||||
</Badge>
|
</Badge>
|
||||||
<Badge variant="outline" className="bg-red-50 text-red-700 dark:bg-red-900 dark:text-red-300 dark:border-red-700">
|
<Badge variant="outline" className="bg-red-50 text-red-700 dark:bg-red-900 dark:text-red-300 dark:border-red-700">
|
||||||
{camas.filter(c => c.estado === 'Ocupada' && !isCamaFueraDeArea(c, areas)).length} Ocupadas
|
{camas.filter(c => c.estado === 'Ocupada' && !isCamaFueraDeGrupo(c, grupos)).length} Ocupadas
|
||||||
</Badge>
|
</Badge>
|
||||||
<div className="ml-4 flex items-center gap-2 flex-wrap sm:flex-nowrap">
|
<div className="ml-4 flex items-center gap-2 flex-wrap sm:flex-nowrap">
|
||||||
<Button variant="outline" onClick={() => {
|
<Button variant="outline" onClick={() => {
|
||||||
setEditingAreaId(null);
|
setEditingGrupoId(null);
|
||||||
setAreaNombre('');
|
setGrupoNombre('');
|
||||||
setAreaDialogOpen(true);
|
setGrupoDialogOpen(true);
|
||||||
}} className="text-xs px-2 py-1 sm:text-sm sm:px-4 sm:py-2">
|
}} className="text-xs px-2 py-1 sm:text-sm sm:px-4 sm:py-2">
|
||||||
Administrar Áreas
|
Administrar Grupos
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline" onClick={() => {
|
<Button variant="outline" onClick={() => {
|
||||||
setEditingBed(null);
|
setEditingBed(null);
|
||||||
setBedNumero('');
|
setBedNumero('');
|
||||||
setBedTipo('General');
|
setBedTipo('General');
|
||||||
setBedAreaId(areas?.[0]?.id);
|
setBedGrupoId(grupos?.[0]?.id);
|
||||||
setBedDialogOpen(true);
|
setBedDialogOpen(true);
|
||||||
}} className="text-xs px-2 py-1 sm:text-sm sm:px-4 sm:py-2">
|
}} className="text-xs px-2 py-1 sm:text-sm sm:px-4 sm:py-2">
|
||||||
<Plus className="h-3 w-3 sm:h-4 sm:w-4 sm:mr-1" />
|
<Plus className="h-3 w-3 sm:h-4 sm:w-4 sm:mr-1" />
|
||||||
@@ -219,15 +219,15 @@ export function MapaCamas({
|
|||||||
<CardContent className="p-4">
|
<CardContent className="p-4">
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-xs text-gray-500 mb-1 block">Área</Label>
|
<Label className="text-xs text-gray-500 mb-1 block">Grupo / Área</Label>
|
||||||
<Select value={filtroSala} onValueChange={setFiltroSala}>
|
<Select value={filtroSala} onValueChange={setFiltroSala}>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="Todas las áreas" />
|
<SelectValue placeholder="Todos los grupos" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="todas">Todas las áreas</SelectItem>
|
<SelectItem value="todas">Todos los grupos</SelectItem>
|
||||||
{salas.map(sala => (
|
{salas.map(sala => (
|
||||||
<SelectItem key={sala} value={sala}>{areaById[sala] ?? sala}</SelectItem>
|
<SelectItem key={sala} value={sala}>{grupoById[sala] ?? sala}</SelectItem>
|
||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
@@ -284,7 +284,7 @@ export function MapaCamas({
|
|||||||
{getEstadoIcono(cama)}
|
{getEstadoIcono(cama)}
|
||||||
</div>
|
</div>
|
||||||
<p className="font-bold text-sm sm:text-lg">{cama.numero}</p>
|
<p className="font-bold text-sm sm:text-lg">{cama.numero}</p>
|
||||||
<p className="text-xs opacity-75 truncate">{cama.areaId ? areaById[cama.areaId] ?? 'Área desconocida' : 'Sin área'}</p>
|
<p className="text-xs opacity-75 truncate">{cama.grupoId ? grupoById[cama.grupoId] ?? 'Grupo desconocido' : 'Sin grupo'}</p>
|
||||||
<Badge variant="outline" className="mt-1 sm:mt-2 text-xs bg-white/50 dark:bg-gray-800 dark:text-gray-300">
|
<Badge variant="outline" className="mt-1 sm:mt-2 text-xs bg-white/50 dark:bg-gray-800 dark:text-gray-300">
|
||||||
{cama.tipo}
|
{cama.tipo}
|
||||||
</Badge>
|
</Badge>
|
||||||
@@ -305,7 +305,7 @@ export function MapaCamas({
|
|||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="flex items-center gap-2">
|
<DialogTitle className="flex items-center gap-2">
|
||||||
<Bed className="h-5 w-5" />
|
<Bed className="h-5 w-5" />
|
||||||
Cama {cama.numero} - {cama.areaId ? areaById[cama.areaId] ?? 'Área desconocida' : 'Sin área'}
|
Cama {cama.numero} - {cama.grupoId ? grupoById[cama.grupoId] ?? 'Grupo desconocido' : 'Sin grupo'}
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
@@ -365,13 +365,13 @@ export function MapaCamas({
|
|||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label>Área de Trabajo *</Label>
|
<Label>Grupo de Trabajo *</Label>
|
||||||
<Select value={areaSeleccionada} onValueChange={setAreaSeleccionada}>
|
<Select value={grupoSeleccionada} onValueChange={setGrupoSeleccionada}>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="Seleccionar área" />
|
<SelectValue placeholder="Seleccionar área" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{areas.filter(a => a.nombre !== 'Fuera de area').map(a => (
|
{grupos.filter(a => a.nombre !== 'Fuera de grupo').map(a => (
|
||||||
<SelectItem key={a.id} value={a.id}>
|
<SelectItem key={a.id} value={a.id}>
|
||||||
{a.nombre}
|
{a.nombre}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
@@ -471,7 +471,7 @@ export function MapaCamas({
|
|||||||
setEditingBed(cama);
|
setEditingBed(cama);
|
||||||
setBedNumero(cama.numero);
|
setBedNumero(cama.numero);
|
||||||
setBedTipo(cama.tipo);
|
setBedTipo(cama.tipo);
|
||||||
setBedAreaId(cama.areaId);
|
setBedGrupoId(cama.grupoId);
|
||||||
setBedDialogOpen(true);
|
setBedDialogOpen(true);
|
||||||
}}>
|
}}>
|
||||||
<Edit2 className="h-4 w-4 mr-1" />Editar
|
<Edit2 className="h-4 w-4 mr-1" />Editar
|
||||||
@@ -496,46 +496,46 @@ export function MapaCamas({
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Area dialog */}
|
{/* Grupo dialog */}
|
||||||
<Dialog open={areaDialogOpen} onOpenChange={setAreaDialogOpen}>
|
<Dialog open={grupoDialogOpen} onOpenChange={setGrupoDialogOpen}>
|
||||||
<DialogContent className="sm:max-w-md">
|
<DialogContent className="sm:max-w-md">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>{editingAreaId ? 'Editar Área' : 'Nueva Área'}</DialogTitle>
|
<DialogTitle>{editingGrupoId ? 'Editar Grupo' : 'Nuevo Grupo'}</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<Label>Nombre</Label>
|
<Label>Nombre</Label>
|
||||||
<Input value={areaNombre} onChange={(e) => setAreaNombre(e.target.value)} />
|
<Input value={grupoNombre} onChange={(e) => setGrupoNombre(e.target.value)} />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-2 justify-end">
|
<div className="flex gap-2 justify-end">
|
||||||
{editingAreaId && (
|
{editingGrupoId && (
|
||||||
<Button size="sm" variant="destructive" onClick={() => { if (confirm('Eliminar área?')) { onEliminarArea(editingAreaId); setAreaDialogOpen(false); } }}>
|
<Button size="sm" variant="destructive" onClick={() => { if (confirm('Eliminar grupo?')) { onEliminarGrupo(editingGrupoId); setGrupoDialogOpen(false); } }}>
|
||||||
<Trash className="h-4 w-4" />
|
<Trash className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<Button size="sm" variant="outline" onClick={() => setAreaDialogOpen(false)}>
|
<Button size="sm" variant="outline" onClick={() => setGrupoDialogOpen(false)}>
|
||||||
<X className="h-4 w-4" />
|
<X className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button size="sm" variant="outline" onClick={() => {
|
<Button size="sm" variant="outline" onClick={() => {
|
||||||
if (!areaNombre.trim()) return alert('Nombre requerido');
|
if (!grupoNombre.trim()) return alert('Nombre requerido');
|
||||||
if (editingAreaId) onActualizarArea(editingAreaId, { nombre: areaNombre });
|
if (editingGrupoId) onActualizarGrupo(editingGrupoId, { nombre: grupoNombre });
|
||||||
else onAgregarArea({ nombre: areaNombre });
|
else onAgregarGrupo({ nombre: grupoNombre });
|
||||||
setAreaDialogOpen(false);
|
setGrupoDialogOpen(false);
|
||||||
}}>
|
}}>
|
||||||
<Save className="h-4 w-4" />
|
<Save className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-medium">Áreas existentes</p>
|
<p className="text-sm font-medium">Grupos existentes</p>
|
||||||
<div className="mt-2 space-y-2">
|
<div className="mt-2 space-y-2">
|
||||||
{areas.map(a => (
|
{grupos.map(a => (
|
||||||
<div key={a.id} className="flex items-center justify-between">
|
<div key={a.id} className="flex items-center justify-between">
|
||||||
<div>{a.nombre}</div>
|
<div>{a.nombre}</div>
|
||||||
<div className="flex gap-1">
|
<div className="flex gap-1">
|
||||||
<Button size="sm" variant="outline" onClick={() => { setEditingAreaId(a.id); setAreaNombre(a.nombre); }}>
|
<Button size="sm" variant="outline" onClick={() => { setEditingGrupoId(a.id); setGrupoNombre(a.nombre); }}>
|
||||||
<Edit2 className="h-4 w-4" />
|
<Edit2 className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button size="sm" variant="outline" className="text-red-600" onClick={() => { if (confirm('Eliminar área?')) onEliminarArea(a.id); }}>
|
<Button size="sm" variant="outline" className="text-red-600" onClick={() => { if (confirm('Eliminar grupo?')) onEliminarGrupo(a.id); }}>
|
||||||
<Trash className="h-4 w-4" />
|
<Trash className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -574,14 +574,14 @@ export function MapaCamas({
|
|||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label>Área</Label>
|
<Label>Grupo / Área</Label>
|
||||||
<Select value={bedAreaId ?? '__none'} onValueChange={(v) => setBedAreaId(v === '__none' ? undefined : v)}>
|
<Select value={bedGrupoId ?? '__none'} onValueChange={(v) => setBedGrupoId(v === '__none' ? undefined : v)}>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="Seleccione área" />
|
<SelectValue placeholder="Seleccione grupo" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="__none">Sin área</SelectItem>
|
<SelectItem value="__none">Sin grupo</SelectItem>
|
||||||
{areas.map(a => (
|
{grupos.map(a => (
|
||||||
<SelectItem key={a.id} value={a.id}>{a.nombre}</SelectItem>
|
<SelectItem key={a.id} value={a.id}>{a.nombre}</SelectItem>
|
||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
@@ -597,9 +597,9 @@ export function MapaCamas({
|
|||||||
<Button variant="outline" onClick={() => {
|
<Button variant="outline" onClick={() => {
|
||||||
if (!bedNumero.trim()) return alert('Número requerido');
|
if (!bedNumero.trim()) return alert('Número requerido');
|
||||||
if (editingBed) {
|
if (editingBed) {
|
||||||
onActualizarCama(editingBed.id, { numero: bedNumero, tipo: bedTipo, areaId: bedAreaId });
|
onActualizarCama(editingBed.id, { numero: bedNumero, tipo: bedTipo, grupoId: bedGrupoId });
|
||||||
} else {
|
} else {
|
||||||
onAgregarCama({ numero: bedNumero, tipo: bedTipo, estado: 'Disponible', areaId: bedAreaId });
|
onAgregarCama({ numero: bedNumero, tipo: bedTipo, estado: 'Disponible', grupoId: bedGrupoId });
|
||||||
}
|
}
|
||||||
setBedDialogOpen(false);
|
setBedDialogOpen(false);
|
||||||
}}>Guardar</Button>
|
}}>Guardar</Button>
|
||||||
|
|||||||
@@ -7,23 +7,23 @@ import { Label } from '@/components/ui/label';
|
|||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import type { Paciente, Cama, Area, Internacion } from '@/types';
|
import type { Paciente, Cama, Grupo, Internacion } from '@/types';
|
||||||
import { getNombreProfesional } from '@/lib/utils';
|
import { getNombreProfesional } from '@/lib/utils';
|
||||||
import { useHospitalStore } from '@/hooks/useHospitalStore';
|
import { useHospitalStore } from '@/hooks/useHospitalStore';
|
||||||
|
|
||||||
interface NuevoIngresoProps {
|
interface NuevoIngresoProps {
|
||||||
pacientes: Paciente[];
|
pacientes: Paciente[];
|
||||||
camas: Cama[];
|
camas: Cama[];
|
||||||
areas: Area[];
|
grupos: Grupo[];
|
||||||
onIniciarInternacion: (internacion: Omit<Internacion, 'id' | 'activa'>) => Promise<string>;
|
onIniciarInternacion: (internacion: Omit<Internacion, 'id' | 'activa'>) => Promise<string>;
|
||||||
onAgregarCama?: (cama: Omit<Cama, 'id'>) => Promise<string>;
|
onAgregarCama?: (cama: Omit<Cama, 'id'>) => Promise<string>;
|
||||||
onAgregarPaciente?: (paciente: Omit<Paciente, 'id'>) => void;
|
onAgregarPaciente?: (paciente: Omit<Paciente, 'id'>) => void;
|
||||||
onActualizarPaciente?: (id: string, datos: Partial<Paciente>) => void;
|
onActualizarPaciente?: (id: string, datos: Partial<Paciente>) => void;
|
||||||
onVolver: () => void;
|
onVolver: () => void;
|
||||||
getAreaName: (areaId: string | undefined) => string;
|
getGrupoName: (grupoId: string | undefined) => string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NuevoIngreso({ pacientes, camas, areas, onIniciarInternacion, onAgregarCama, onVolver, getAreaName }: NuevoIngresoProps) {
|
export function NuevoIngreso({ pacientes, camas, grupos, onIniciarInternacion, onAgregarCama, onVolver, getGrupoName }: 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('');
|
||||||
@@ -58,8 +58,8 @@ export function NuevoIngreso({ pacientes, camas, areas, onIniciarInternacion, on
|
|||||||
|
|
||||||
const normalizeStr = (str?: string) => (str || '').normalize('NFD').replace(/[\u0300-\u036f]/g, '').trim().toLowerCase();
|
const normalizeStr = (str?: string) => (str || '').normalize('NFD').replace(/[\u0300-\u036f]/g, '').trim().toLowerCase();
|
||||||
|
|
||||||
const areaFueraDeArea = areas.find(a => normalizeStr(a.nombre) === 'fuera de area');
|
const grupoFueraDeGrupo = grupos.find(a => normalizeStr(a.nombre) === 'fuera de grupo');
|
||||||
const areaFueraDeAreaId = areaFueraDeArea?.id || areas[0]?.id || 'fuera-de-area';
|
const grupoFueraDeGrupoId = grupoFueraDeGrupo?.id || grupos[0]?.id || 'fuera-de-grupo';
|
||||||
|
|
||||||
const pacientesSinInternar = pacientes;
|
const pacientesSinInternar = pacientes;
|
||||||
|
|
||||||
@@ -142,22 +142,22 @@ export function NuevoIngreso({ pacientes, camas, areas, onIniciarInternacion, on
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
let camaId = '';
|
let camaId = '';
|
||||||
let newAreaId = '';
|
let newGrupoId = '';
|
||||||
|
|
||||||
if (modoCama === 'escribir') {
|
if (modoCama === 'escribir') {
|
||||||
const numeroCama = camaInput.trim();
|
const numeroCama = camaInput.trim();
|
||||||
const camaExistente = camas.find(c => c.numero === numeroCama);
|
const camaExistente = camas.find(c => c.numero === numeroCama);
|
||||||
if (camaExistente) {
|
if (camaExistente) {
|
||||||
camaId = camaExistente.id;
|
camaId = camaExistente.id;
|
||||||
newAreaId = camaExistente.areaId || areaFueraDeAreaId;
|
newGrupoId = camaExistente.grupoId || grupoFueraDeGrupoId;
|
||||||
} else if (onAgregarCama) {
|
} else if (onAgregarCama) {
|
||||||
camaId = await onAgregarCama({
|
camaId = await onAgregarCama({
|
||||||
numero: numeroCama,
|
numero: numeroCama,
|
||||||
areaId: areaFueraDeAreaId,
|
grupoId: grupoFueraDeGrupoId,
|
||||||
tipo: 'General',
|
tipo: 'General',
|
||||||
estado: 'Ocupada'
|
estado: 'Ocupada'
|
||||||
});
|
});
|
||||||
newAreaId = areaFueraDeAreaId;
|
newGrupoId = grupoFueraDeGrupoId;
|
||||||
} else {
|
} else {
|
||||||
toast.error('No se puede crear la cama');
|
toast.error('No se puede crear la cama');
|
||||||
setIsSubmitting(false);
|
setIsSubmitting(false);
|
||||||
@@ -171,13 +171,13 @@ export function NuevoIngreso({ pacientes, camas, areas, onIniciarInternacion, on
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
camaId = camaSeleccionada;
|
camaId = camaSeleccionada;
|
||||||
newAreaId = camaElegida.areaId || areaFueraDeAreaId;
|
newGrupoId = camaElegida.grupoId || grupoFueraDeGrupoId;
|
||||||
}
|
}
|
||||||
|
|
||||||
await onIniciarInternacion({
|
await onIniciarInternacion({
|
||||||
pacienteId: pacienteSeleccionado,
|
pacienteId: pacienteSeleccionado,
|
||||||
camaId: camaId,
|
camaId: camaId,
|
||||||
areaId: newAreaId,
|
grupoId: newGrupoId,
|
||||||
medicoIngresante: effectiveMedico.trim(),
|
medicoIngresante: effectiveMedico.trim(),
|
||||||
diagnosticoIngreso: diagnosticoIngreso.trim(),
|
diagnosticoIngreso: diagnosticoIngreso.trim(),
|
||||||
motivoConsulta: motivoConsulta.trim() || undefined,
|
motivoConsulta: motivoConsulta.trim() || undefined,
|
||||||
@@ -293,13 +293,13 @@ export function NuevoIngreso({ pacientes, camas, areas, onIniciarInternacion, on
|
|||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Columna 2: Cama y Área */}
|
{/* Columna 2: Cama y Grupo */}
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<Card className="min-h-[200px]">
|
<Card className="min-h-[200px]">
|
||||||
<CardContent className="pt-6 space-y-4">
|
<CardContent className="pt-6 space-y-4">
|
||||||
<h3 className="font-semibold text-gray-900 dark:text-white flex items-center gap-2">
|
<h3 className="font-semibold text-gray-900 dark:text-white flex items-center gap-2">
|
||||||
<Bed className="h-4 w-4" />
|
<Bed className="h-4 w-4" />
|
||||||
Asignación de Cama y Área
|
Asignación de Cama y Grupo
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div className="flex flex-col sm:flex-row gap-2 mb-4">
|
<div className="flex flex-col sm:flex-row gap-2 mb-4">
|
||||||
@@ -330,7 +330,7 @@ export function NuevoIngreso({ pacientes, camas, areas, onIniciarInternacion, on
|
|||||||
<SelectContent>
|
<SelectContent>
|
||||||
{sortedCamas.map(c => (
|
{sortedCamas.map(c => (
|
||||||
<SelectItem key={c.id} value={c.id}>
|
<SelectItem key={c.id} value={c.id}>
|
||||||
{c.numero} - {getAreaName(c.areaId)}
|
{c.numero} - {getGrupoName(c.grupoId)}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
|
|||||||
+11
-6
@@ -21,9 +21,17 @@ export interface Paciente {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface Grupo {
|
||||||
|
id: string;
|
||||||
|
nombre: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Area = Grupo;
|
||||||
|
|
||||||
export interface Cama {
|
export interface Cama {
|
||||||
id: string;
|
id: string;
|
||||||
numero: string;
|
numero: string;
|
||||||
|
grupoId?: string;
|
||||||
areaId?: string;
|
areaId?: string;
|
||||||
tipo: 'General' | 'Aislamiento KPC' | 'Aislamiento COVID' | 'Aislamiento Clostridium' | 'Aislamiento Neutropenico';
|
tipo: 'General' | 'Aislamiento KPC' | 'Aislamiento COVID' | 'Aislamiento Clostridium' | 'Aislamiento Neutropenico';
|
||||||
estado: 'Disponible' | 'Ocupada' | 'Reparacion' | 'Reservada';
|
estado: 'Disponible' | 'Ocupada' | 'Reparacion' | 'Reservada';
|
||||||
@@ -31,16 +39,12 @@ export interface Cama {
|
|||||||
internacionId?: string;
|
internacionId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Area {
|
|
||||||
id: string;
|
|
||||||
nombre: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Internacion {
|
export interface Internacion {
|
||||||
id: string;
|
id: string;
|
||||||
pacienteId: string;
|
pacienteId: string;
|
||||||
camaId: string;
|
camaId: string;
|
||||||
areaId: string;
|
grupoId?: string;
|
||||||
|
areaId?: string;
|
||||||
fechaIngresoHospital?: string;
|
fechaIngresoHospital?: string;
|
||||||
fechaIngresoClinica?: string;
|
fechaIngresoClinica?: string;
|
||||||
fechaEgreso?: string;
|
fechaEgreso?: string;
|
||||||
@@ -229,6 +233,7 @@ export interface Usuario {
|
|||||||
rol: RolUsuario;
|
rol: RolUsuario;
|
||||||
matriculaProfesional?: string;
|
matriculaProfesional?: string;
|
||||||
passwordHash: string;
|
passwordHash: string;
|
||||||
|
grupoId?: string;
|
||||||
areaId?: string;
|
areaId?: string;
|
||||||
fechaCreacion: string;
|
fechaCreacion: string;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user