Add area assignment to internaciones and permission controls
- Add areaId field to Internacion type and database schema - Add area selection in NuevoIngreso, EditIngreso, and Internaciones forms - Filter out 'Fuera de area' from area selection dropdowns - Add permission controls for users to only edit internaciones in their area - Add canEdit check to hide 'Editar Ingreso' button in HistoriaClinica - Fix getInternacionAreaId to use new areaId field first, fallback to cama area - Add INSERT OR IGNORE to prevent duplicate errors
This commit is contained in:
+2
-2
@@ -82,8 +82,8 @@ app.put('/api/state', async (req, res) => {
|
||||
if (state.internaciones?.length) {
|
||||
for (const i of state.internaciones) {
|
||||
await db.run(
|
||||
'INSERT INTO internaciones (id, pacienteId, camaId, fechaIngresoHospital, fechaIngresoClinica, fechaEgreso, diagnosticoIngreso, motivoConsulta, enfermedadActual, antecedentesEnfermedadActual, diagnosticoEgreso, medicoIngresante, motivoEgreso, activa, apache, derivacion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
[i.id, i.pacienteId, i.camaId, 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]
|
||||
'INSERT OR IGNORE INTO internaciones (id, pacienteId, camaId, areaId, fechaIngresoHospital, fechaIngresoClinica, fechaEgreso, diagnosticoIngreso, motivoConsulta, enfermedadActual, antecedentesEnfermedadActual, diagnosticoEgreso, medicoIngresante, motivoEgreso, activa, apache, derivacion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
[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]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-4
@@ -16,6 +16,12 @@ if (!existsSync(join(__dirname, 'data'))) {
|
||||
|
||||
const db = new Database(DB_PATH);
|
||||
|
||||
try {
|
||||
db.exec("ALTER TABLE internaciones ADD COLUMN areaId TEXT;");
|
||||
} catch (e) {
|
||||
// Ignore errors - column might already exist or other issues
|
||||
}
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS pacientes (
|
||||
id TEXT PRIMARY KEY,
|
||||
@@ -52,6 +58,7 @@ db.exec(`
|
||||
id TEXT PRIMARY KEY,
|
||||
pacienteId TEXT NOT NULL,
|
||||
camaId TEXT,
|
||||
areaId TEXT,
|
||||
fechaIngresoHospital TEXT,
|
||||
fechaIngresoClinica TEXT,
|
||||
fechaEgreso TEXT,
|
||||
@@ -378,21 +385,21 @@ app.put('/api/state', (req, res) => {
|
||||
}
|
||||
|
||||
if (state.camas?.length) {
|
||||
const stmt = db.prepare('INSERT INTO camas (id, numero, areaId, tipo, estado) VALUES (?, ?, ?, ?, ?)');
|
||||
const stmt = db.prepare('INSERT OR IGNORE INTO camas (id, numero, areaId, tipo, estado) VALUES (?, ?, ?, ?, ?)');
|
||||
for (const c of state.camas) {
|
||||
stmt.run(c.id, c.numero, c.areaId, c.tipo, c.estado);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.internaciones?.length) {
|
||||
const stmt = db.prepare('INSERT INTO internaciones (id, pacienteId, camaId, 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, areaId, fechaIngresoHospital, fechaIngresoClinica, fechaEgreso, diagnosticoIngreso, motivoConsulta, enfermedadActual, antecedentesEnfermedadActual, diagnosticoEgreso, medicoIngresante, motivoEgreso, activa, apache, derivacion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
||||
for (const i of state.internaciones) {
|
||||
stmt.run(i.id, i.pacienteId, i.camaId, 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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.evoluciones?.length) {
|
||||
const stmt = db.prepare('INSERT INTO evoluciones (id, internacionId, fecha, hora, medico, signosVitales, examenFisico, novedades, comentarios, pendientes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
||||
const stmt = db.prepare('INSERT OR IGNORE INTO evoluciones (id, internacionId, fecha, hora, medico, signosVitales, examenFisico, novedades, comentarios, pendientes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
||||
for (const e of state.evoluciones) {
|
||||
stmt.run(e.id, e.internacionId, e.fecha, e.hora || '', e.medico || '', JSON.stringify(e.signosVitales || {}), JSON.stringify(e.examenFisico || {}), e.novedades || '', e.comentario || '', e.pendientes || '');
|
||||
}
|
||||
|
||||
+236
-29
@@ -172,13 +172,21 @@ export function useHospitalStore() {
|
||||
}));
|
||||
}, []);
|
||||
|
||||
// Acciones de camas
|
||||
// Acciones de camas
|
||||
const actualizarCama = useCallback((id: string, datos: Partial<Cama>) => {
|
||||
const cama = state.camas.find(c => c.id === id);
|
||||
if (!cama) return;
|
||||
const user = state.currentUser;
|
||||
const areaId = cama.areaId || null;
|
||||
if (user && user.rol !== 'admin' && areaId && user.areaId !== areaId) {
|
||||
console.warn('No tiene permisos para actualizar cama en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
camas: prev.camas.map(c => c.id === id ? { ...c, ...datos } : c),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.camas, state.currentUser]);
|
||||
|
||||
const agregarCama = useCallback((cama: Omit<Cama, 'id'>) => {
|
||||
const nuevaCama: Cama = {
|
||||
@@ -202,6 +210,12 @@ export function useHospitalStore() {
|
||||
|
||||
// Acciones de internaciones
|
||||
const iniciarInternacion = useCallback((internacion: Omit<Internacion, 'id' | 'activa'>) => {
|
||||
const user = state.currentUser;
|
||||
const areaId = internacion.areaId || null;
|
||||
if (user && user.rol !== 'admin' && areaId && user.areaId !== areaId) {
|
||||
console.warn('No tiene permisos para iniciar internación en esta área');
|
||||
return null;
|
||||
}
|
||||
const nuevaInternacion: Internacion = {
|
||||
...internacion,
|
||||
id: generateUUID(),
|
||||
@@ -217,7 +231,7 @@ export function useHospitalStore() {
|
||||
),
|
||||
}));
|
||||
return nuevaInternacion.id;
|
||||
}, []);
|
||||
}, [state.currentUser]);
|
||||
|
||||
const finalizarInternacion = useCallback((internacionId: string, datos: {
|
||||
fechaEgreso: string;
|
||||
@@ -245,6 +259,14 @@ const finalizarInternacion = useCallback((internacionId: string, datos: {
|
||||
}, []);
|
||||
|
||||
const actualizarInternacion = useCallback((internacionId: string, datos: Partial<Internacion>) => {
|
||||
const internacion = state.internaciones.find(i => i.id === internacionId);
|
||||
if (!internacion) return;
|
||||
const user = state.currentUser;
|
||||
const areaId = internacion.areaId || null;
|
||||
if (user && user.rol !== 'admin' && areaId && user.areaId !== areaId) {
|
||||
console.warn('No tiene permisos para actualizar internación en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
internaciones: prev.internaciones.map(i =>
|
||||
@@ -253,10 +275,16 @@ const finalizarInternacion = useCallback((internacionId: string, datos: {
|
||||
: i
|
||||
),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
// Acciones de evoluciones
|
||||
const agregarEvolucion = useCallback((evolucion: Omit<Evolucion, 'id'>) => {
|
||||
const internacion = state.internaciones.find(i => i.id === evolucion.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para agregar evolución en esta área');
|
||||
return null;
|
||||
}
|
||||
const nuevaEvolucion: Evolucion = {
|
||||
...evolucion,
|
||||
id: generateUUID(),
|
||||
@@ -266,9 +294,17 @@ const finalizarInternacion = useCallback((internacionId: string, datos: {
|
||||
evoluciones: [...prev.evoluciones, nuevaEvolucion],
|
||||
}));
|
||||
return nuevaEvolucion.id;
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const eliminarEvolucion = useCallback((id: string) => {
|
||||
const evolucion = state.evoluciones.find(e => e.id === id);
|
||||
if (!evolucion) return;
|
||||
const internacion = state.internaciones.find(i => i.id === evolucion.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para eliminar evolución en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
evoluciones: prev.evoluciones.filter(e => e.id !== id),
|
||||
@@ -276,14 +312,28 @@ const finalizarInternacion = useCallback((internacionId: string, datos: {
|
||||
}, []);
|
||||
|
||||
const actualizarEvolucion = useCallback((id: string, datos: Partial<Evolucion>) => {
|
||||
const evolucion = state.evoluciones.find(e => e.id === id);
|
||||
if (!evolucion) return;
|
||||
const internacion = state.internaciones.find(i => i.id === evolucion.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para actualizar evolución en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
evoluciones: prev.evoluciones.map(e => e.id === id ? { ...e, ...datos } : e),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
// Acciones de laboratorios
|
||||
const agregarLaboratorio = useCallback((laboratorio: Omit<Laboratorio, 'id'>) => {
|
||||
const internacion = state.internaciones.find(i => i.id === laboratorio.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para agregar laboratorio en esta área');
|
||||
return null;
|
||||
}
|
||||
const nuevoLaboratorio: Laboratorio = {
|
||||
...laboratorio,
|
||||
id: generateUUID(),
|
||||
@@ -293,24 +343,46 @@ const finalizarInternacion = useCallback((internacionId: string, datos: {
|
||||
laboratorios: [...prev.laboratorios, nuevoLaboratorio],
|
||||
}));
|
||||
return nuevoLaboratorio.id;
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const eliminarLaboratorio = useCallback((id: string) => {
|
||||
const eliminarLaboratorio = useCallback((id: string) => {
|
||||
const laboratorio = state.laboratorios.find(l => l.id === id);
|
||||
if (!laboratorio) return;
|
||||
const internacion = state.internaciones.find(i => i.id === laboratorio.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para eliminar laboratorio en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
laboratorios: prev.laboratorios.filter(l => l.id !== id),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const actualizarLaboratorio = useCallback((id: string, datos: Partial<Laboratorio>) => {
|
||||
const laboratorio = state.laboratorios.find(l => l.id === id);
|
||||
if (!laboratorio) return;
|
||||
const internacion = state.internaciones.find(i => i.id === laboratorio.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para actualizar laboratorio en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
laboratorios: prev.laboratorios.map(l => l.id === id ? { ...l, ...datos } : l),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
// Acciones de ácido-base
|
||||
const agregarAcidoBase = useCallback((acidoBase: Omit<AcidoBase, 'id'>) => {
|
||||
const internacion = state.internaciones.find(i => i.id === acidoBase.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para agregar ácido-base en esta área');
|
||||
return null;
|
||||
}
|
||||
const nuevoAcidoBase: AcidoBase = {
|
||||
...acidoBase,
|
||||
id: generateUUID(),
|
||||
@@ -320,24 +392,46 @@ const finalizarInternacion = useCallback((internacionId: string, datos: {
|
||||
acidosBase: [...prev.acidosBase, nuevoAcidoBase],
|
||||
}));
|
||||
return nuevoAcidoBase.id;
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const actualizarAcidoBase = useCallback((id: string, datos: Partial<AcidoBase>) => {
|
||||
const acidoBase = state.acidosBase.find(a => a.id === id);
|
||||
if (!acidoBase) return;
|
||||
const internacion = state.internaciones.find(i => i.id === acidoBase.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para actualizar ácido-base en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
acidosBase: prev.acidosBase.map(a => a.id === id ? { ...a, ...datos } : a),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const eliminarAcidoBase = useCallback((id: string) => {
|
||||
const acidoBase = state.acidosBase.find(a => a.id === id);
|
||||
if (!acidoBase) return;
|
||||
const internacion = state.internaciones.find(i => i.id === acidoBase.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para eliminar ácido-base en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
acidosBase: prev.acidosBase.filter(a => a.id !== id),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
// Acciones de cultivos
|
||||
const agregarCultivo = useCallback((cultivo: Omit<Cultivo, 'id'>) => {
|
||||
const internacion = state.internaciones.find(i => i.id === cultivo.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para agregar cultivo en esta área');
|
||||
return null;
|
||||
}
|
||||
const nuevoCultivo: Cultivo = {
|
||||
...cultivo,
|
||||
id: generateUUID(),
|
||||
@@ -347,24 +441,46 @@ const finalizarInternacion = useCallback((internacionId: string, datos: {
|
||||
cultivos: [...prev.cultivos, nuevoCultivo],
|
||||
}));
|
||||
return nuevoCultivo.id;
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const actualizarCultivo = useCallback((id: string, datos: Partial<Cultivo>) => {
|
||||
const cultivo = state.cultivos.find(c => c.id === id);
|
||||
if (!cultivo) return;
|
||||
const internacion = state.internaciones.find(i => i.id === cultivo.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para actualizar cultivo en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
cultivos: prev.cultivos.map(c => c.id === id ? { ...c, ...datos } : c),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const eliminarCultivo = useCallback((id: string) => {
|
||||
const cultivo = state.cultivos.find(c => c.id === id);
|
||||
if (!cultivo) return;
|
||||
const internacion = state.internaciones.find(i => i.id === cultivo.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para eliminar cultivo en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
cultivos: prev.cultivos.filter(c => c.id !== id),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
// Acciones de estudios complementarios
|
||||
const agregarEstudioComplementario = useCallback((estudio: Omit<EstudioComplementario, 'id'>) => {
|
||||
const internacion = state.internaciones.find(i => i.id === estudio.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para agregar estudio complementario en esta área');
|
||||
return null;
|
||||
}
|
||||
const nuevoEstudio: EstudioComplementario = {
|
||||
...estudio,
|
||||
id: generateUUID(),
|
||||
@@ -374,98 +490,186 @@ const finalizarInternacion = useCallback((internacionId: string, datos: {
|
||||
estudiosComplementarios: [...prev.estudiosComplementarios, nuevoEstudio],
|
||||
}));
|
||||
return nuevoEstudio.id;
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const actualizarEstudioComplementario = useCallback((id: string, datos: Partial<EstudioComplementario>) => {
|
||||
const estudio = state.estudiosComplementarios.find(e => e.id === id);
|
||||
if (!estudio) return;
|
||||
const internacion = state.internaciones.find(i => i.id === estudio.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para actualizar estudio complementario en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
estudiosComplementarios: prev.estudiosComplementarios.map(e => e.id === id ? { ...e, ...datos } : e),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const eliminarEstudioComplementario = useCallback((id: string) => {
|
||||
const estudio = state.estudiosComplementarios.find(e => e.id === id);
|
||||
if (!estudio) return;
|
||||
const internacion = state.internaciones.find(i => i.id === estudio.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para eliminar estudio complementario en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
estudiosComplementarios: prev.estudiosComplementarios.filter(e => e.id !== id),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
// Acciones de interconsultas
|
||||
const agregarInterconsulta = useCallback((interconsulta: Omit<Interconsulta, 'id'>) => {
|
||||
const internacion = state.internaciones.find(i => i.id === interconsulta.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para agregar interconsulta en esta área');
|
||||
return null;
|
||||
}
|
||||
const nuevaInterconsulta: Interconsulta = { ...interconsulta, id: generateUUID() };
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
interconsultas: [...(prev.interconsultas || []), nuevaInterconsulta],
|
||||
}));
|
||||
return nuevaInterconsulta.id;
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const actualizarInterconsulta = useCallback((id: string, datos: Partial<Interconsulta>) => {
|
||||
const interconsulta = (state.interconsultas || []).find(ic => ic.id === id);
|
||||
if (!interconsulta) return;
|
||||
const internacion = state.internaciones.find(i => i.id === interconsulta.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para actualizar interconsulta en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
interconsultas: (prev.interconsultas || []).map(ic => ic.id === id ? { ...ic, ...datos } : ic),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const eliminarInterconsulta = useCallback((id: string) => {
|
||||
const interconsulta = (state.interconsultas || []).find(ic => ic.id === id);
|
||||
if (!interconsulta) return;
|
||||
const internacion = state.internaciones.find(i => i.id === interconsulta.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para eliminar interconsulta en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
interconsultas: (prev.interconsultas || []).filter(ic => ic.id !== id),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const agregarATB = useCallback((atb: Omit<ATB, 'id'>) => {
|
||||
const internacion = state.internaciones.find(i => i.id === atb.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para agregar ATB en esta área');
|
||||
return null;
|
||||
}
|
||||
const nuevoATB: ATB = { ...atb, id: generateUUID() };
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
atb: [...prev.atb, nuevoATB],
|
||||
}));
|
||||
return nuevoATB.id;
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const actualizarATB = useCallback((id: string, datos: Partial<ATB>) => {
|
||||
const atb = state.atb.find(a => a.id === id);
|
||||
if (!atb) return;
|
||||
const internacion = state.internaciones.find(i => i.id === atb.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para actualizar ATB en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
atb: prev.atb.map(a => a.id === id ? { ...a, ...datos } : a),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const eliminarATB = useCallback((id: string) => {
|
||||
const atb = state.atb.find(a => a.id === id);
|
||||
if (!atb) return;
|
||||
const internacion = state.internaciones.find(i => i.id === atb.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para eliminar ATB en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
atb: prev.atb.filter(a => a.id !== id),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const agregarIndicacion = useCallback((indicacion: Omit<Indicacion, 'id'>) => {
|
||||
const internacion = state.internaciones.find(i => i.id === indicacion.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para agregar indicación en esta área');
|
||||
return null;
|
||||
}
|
||||
const nuevaIndicacion: Indicacion = { ...indicacion, id: generateUUID() };
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
indicaciones: [...prev.indicaciones, nuevaIndicacion],
|
||||
}));
|
||||
return nuevaIndicacion.id;
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const actualizarIndicacion = useCallback((id: string, datos: Partial<Indicacion>) => {
|
||||
const indicacion = state.indicaciones.find(i => i.id === id);
|
||||
if (!indicacion) return;
|
||||
const internacion = state.internaciones.find(i => i.id === indicacion.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para actualizar indicación en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
indicaciones: prev.indicaciones.map(i => i.id === id ? { ...i, ...datos } : i),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const eliminarIndicacion = useCallback((id: string) => {
|
||||
const indicacion = state.indicaciones.find(i => i.id === id);
|
||||
if (!indicacion) return;
|
||||
const internacion = state.internaciones.find(i => i.id === indicacion.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para eliminar indicación en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
indicaciones: prev.indicaciones.filter(i => i.id !== id),
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const agregarMovimientoIndicacion = useCallback((movimiento: any) => {
|
||||
const internacion = state.internaciones.find(i => i.id === movimiento.internacionId);
|
||||
const areaId = internacion?.areaId || null;
|
||||
if (!canEditInArea(areaId)) {
|
||||
console.warn('No tiene permisos para agregar movimiento de indicación en esta área');
|
||||
return;
|
||||
}
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
movimientosIndicaciones: [...(prev.movimientosIndicaciones || []), { ...movimiento, id: generateUUID() }],
|
||||
}));
|
||||
}, []);
|
||||
}, [state.internaciones, state.currentUser]);
|
||||
|
||||
const getMovimientosByInternacion = useCallback((internacionId: string) => {
|
||||
return (state.movimientosIndicaciones || [])
|
||||
@@ -662,6 +866,9 @@ const getEstadisticas = useCallback(() => {
|
||||
const getInternacionAreaId = useCallback((internacionId: string): string | null => {
|
||||
const internacion = state.internaciones.find(i => i.id === internacionId);
|
||||
if (!internacion) return null;
|
||||
// Use the new areaId field first
|
||||
if (internacion.areaId) return internacion.areaId;
|
||||
// Fallback to cama's area
|
||||
return getCamaAreaId(internacion.camaId);
|
||||
}, [state.internaciones, getCamaAreaId]);
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ export function EditIngreso({
|
||||
const [pacienteSeleccionado, setPacienteSeleccionado] = useState(internacion.pacienteId);
|
||||
const [busqueda, setBusqueda] = useState('');
|
||||
const [camaSeleccionada, setCamaSeleccionada] = useState(internacion.camaId);
|
||||
const [areaSeleccionada, setAreaSeleccionada] = useState(internacion.areaId);
|
||||
const [medico, setMedico] = useState(internacion.medicoIngresante);
|
||||
const [fechaIngresoHospital, setFechaIngresoHospital] = useState(internacion.fechaIngresoHospital || '');
|
||||
const [fechaIngresoClinica, setFechaIngresoClinica] = useState(internacion.fechaIngresoClinica || '');
|
||||
@@ -56,9 +57,13 @@ export function EditIngreso({
|
||||
};
|
||||
|
||||
const selectedPaciente = pacientes.find(p => p.id === pacienteSeleccionado);
|
||||
const areasDisponibles = areas.filter(a => {
|
||||
const nombre = (a.nombre || '').trim().toLowerCase();
|
||||
return nombre !== 'fuera de area';
|
||||
});
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (!pacienteSeleccionado || !camaSeleccionada || !medico || !diagnosticoIngreso || !enfermedadActual) {
|
||||
if (!pacienteSeleccionado || !camaSeleccionada || !areaSeleccionada || !medico || !diagnosticoIngreso || !enfermedadActual) {
|
||||
alert('Por favor complete los campos obligatorios');
|
||||
return;
|
||||
}
|
||||
@@ -66,6 +71,7 @@ export function EditIngreso({
|
||||
onActualizarInternacion(internacion.id, {
|
||||
pacienteId: pacienteSeleccionado,
|
||||
camaId: camaSeleccionada,
|
||||
areaId: areaSeleccionada,
|
||||
medicoIngresante: medico,
|
||||
diagnosticoIngreso,
|
||||
motivoConsulta: motivoConsulta || undefined,
|
||||
@@ -180,17 +186,33 @@ export function EditIngreso({
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Columna 2: Cama */}
|
||||
{/* Columna 2: Cama y Área */}
|
||||
<div className="space-y-6">
|
||||
<Card className="min-h-[200px]">
|
||||
<CardContent className="pt-6 space-y-4">
|
||||
<h3 className="font-semibold text-gray-900 flex items-center gap-2">
|
||||
<Bed className="h-4 w-4" />
|
||||
Asignación de Cama
|
||||
Asignación de Cama y Área
|
||||
</h3>
|
||||
|
||||
<div>
|
||||
<Label>Área de Trabajo *</Label>
|
||||
<Select value={areaSeleccionada} onValueChange={setAreaSeleccionada}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Seleccionar área" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{areasDisponibles.map(a => (
|
||||
<SelectItem key={a.id} value={a.id}>
|
||||
{a.nombre}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>Cama</Label>
|
||||
<Select value={camaSeleccionada} onValueChange={setCamaSeleccionada}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Seleccionar cama" />
|
||||
|
||||
@@ -266,10 +266,12 @@ export function HistoriaClinica({
|
||||
<ArrowLeft className="h-4 w-4 mr-2" />
|
||||
Volver
|
||||
</Button>
|
||||
{canEdit && onEditarIngreso && (
|
||||
<Button onClick={onEditarIngreso}>
|
||||
<Pencil className="h-4 w-4 mr-2" />
|
||||
Editar Ingreso
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
|
||||
@@ -49,6 +49,7 @@ export function Internaciones({
|
||||
const [busqueda, setBusqueda] = useState('');
|
||||
const [pacienteSeleccionado, setPacienteSeleccionado] = useState<string>('');
|
||||
const [camaSeleccionada, setCamaSeleccionada] = useState<string>('');
|
||||
const [areaSeleccionada, setAreaSeleccionada] = useState<string>('');
|
||||
const [diagnosticoIngreso, setDiagnosticoIngreso] = useState('');
|
||||
const [enfermedadActual, setEnfermedadActual] = useState('');
|
||||
const [motivoConsulta, setMotivoConsulta] = useState('');
|
||||
@@ -63,6 +64,7 @@ export function Internaciones({
|
||||
const resetFormularioNueva = () => {
|
||||
setPacienteSeleccionado('');
|
||||
setCamaSeleccionada('');
|
||||
setAreaSeleccionada('');
|
||||
setDiagnosticoIngreso('');
|
||||
setEnfermedadActual('');
|
||||
setAntecedentesEnfermedadActual('');
|
||||
@@ -77,10 +79,11 @@ export function Internaciones({
|
||||
};
|
||||
|
||||
const handleIniciarInternacion = () => {
|
||||
if (pacienteSeleccionado && camaSeleccionada && motivoConsulta && enfermedadActual && medicoIngresante) {
|
||||
if (pacienteSeleccionado && camaSeleccionada && areaSeleccionada && motivoConsulta && enfermedadActual && medicoIngresante) {
|
||||
onIniciarInternacion({
|
||||
pacienteId: pacienteSeleccionado,
|
||||
camaId: camaSeleccionada,
|
||||
areaId: areaSeleccionada,
|
||||
diagnosticoIngreso: diagnosticoIngreso || motivoConsulta,
|
||||
motivoConsulta,
|
||||
enfermedadActual,
|
||||
@@ -206,6 +209,21 @@ export function Internaciones({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<Label>Área de Trabajo *</Label>
|
||||
<Select value={areaSeleccionada} onValueChange={setAreaSeleccionada}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Seleccionar área" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{areas.filter(a => a.nombre !== 'Fuera de area').map(a => (
|
||||
<SelectItem key={a.id} value={a.id}>
|
||||
{a.nombre}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Cama *</Label>
|
||||
<Select value={camaSeleccionada} onValueChange={setCamaSeleccionada}>
|
||||
|
||||
@@ -47,6 +47,7 @@ export function MapaCamas({
|
||||
const [filtroTipo, setFiltroTipo] = useState<string>('todos');
|
||||
const [filtroEstado, setFiltroEstado] = useState<string>('todos');
|
||||
const [camaSeleccionada, setCamaSeleccionada] = useState<Cama | null>(null);
|
||||
const [areaSeleccionada, setAreaSeleccionada] = useState<string>('');
|
||||
const [pacienteSeleccionado, setPacienteSeleccionado] = useState<string>('');
|
||||
const [diagnostico, setDiagnostico] = useState('');
|
||||
const [enfermedadActual, setEnfermedadActual] = useState('');
|
||||
@@ -147,10 +148,11 @@ export function MapaCamas({
|
||||
});
|
||||
|
||||
const handleOcuparCama = () => {
|
||||
if (camaSeleccionada && pacienteSeleccionado && diagnostico && enfermedadActual && medico) {
|
||||
if (camaSeleccionada && areaSeleccionada && pacienteSeleccionado && diagnostico && enfermedadActual && medico) {
|
||||
onIniciarInternacion({
|
||||
pacienteId: pacienteSeleccionado,
|
||||
camaId: camaSeleccionada.id,
|
||||
areaId: areaSeleccionada,
|
||||
diagnosticoIngreso: diagnostico,
|
||||
enfermedadActual,
|
||||
antecedentesEnfermedadActual: antecedentesEnfermedadActual || undefined,
|
||||
@@ -158,6 +160,7 @@ export function MapaCamas({
|
||||
});
|
||||
setDialogoAbierto(false);
|
||||
setCamaSeleccionada(null);
|
||||
setAreaSeleccionada('');
|
||||
setPacienteSeleccionado('');
|
||||
setDiagnostico('');
|
||||
setEnfermedadActual('');
|
||||
@@ -360,6 +363,21 @@ export function MapaCamas({
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Área de Trabajo *</Label>
|
||||
<Select value={areaSeleccionada} onValueChange={setAreaSeleccionada}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Seleccionar área" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{areas.filter(a => a.nombre !== 'Fuera de area').map(a => (
|
||||
<SelectItem key={a.id} value={a.id}>
|
||||
{a.nombre}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Diagnóstico de Ingreso *</Label>
|
||||
<textarea
|
||||
|
||||
@@ -23,6 +23,7 @@ export function NuevoIngreso({ pacientes, camas, areas, onIniciarInternacion, on
|
||||
const [pacienteSeleccionado, setPacienteSeleccionado] = useState<string>('');
|
||||
const [busqueda, setBusqueda] = useState('');
|
||||
const [camaSeleccionada, setCamaSeleccionada] = useState('');
|
||||
const [areaSeleccionada, setAreaSeleccionada] = useState('');
|
||||
const [medico, setMedico] = useState('');
|
||||
const [fechaIngresoHospital, setFechaIngresoHospital] = useState('');
|
||||
const [fechaIngresoClinica, setFechaIngresoClinica] = useState('');
|
||||
@@ -37,6 +38,7 @@ export function NuevoIngreso({ pacientes, camas, areas, onIniciarInternacion, on
|
||||
setPacienteSeleccionado('');
|
||||
setBusqueda('');
|
||||
setCamaSeleccionada('');
|
||||
setAreaSeleccionada('');
|
||||
setMedico('');
|
||||
setFechaIngresoHospital('');
|
||||
setFechaIngresoClinica('');
|
||||
@@ -48,10 +50,14 @@ export function NuevoIngreso({ pacientes, camas, areas, onIniciarInternacion, on
|
||||
setDerivacion('');
|
||||
};
|
||||
|
||||
const areasDisponibles = areas.filter(a => {
|
||||
const nombre = (a.nombre || '').trim().toLowerCase();
|
||||
return nombre !== 'fuera de area';
|
||||
});
|
||||
const pacientesSinInternar = pacientes;
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (!pacienteSeleccionado || !camaSeleccionada || !medico || !diagnosticoIngreso || !enfermedadActual) {
|
||||
if (!pacienteSeleccionado || !camaSeleccionada || !areaSeleccionada || !medico || !diagnosticoIngreso || !enfermedadActual) {
|
||||
alert('Por favor complete los campos obligatorios');
|
||||
return;
|
||||
}
|
||||
@@ -59,6 +65,7 @@ export function NuevoIngreso({ pacientes, camas, areas, onIniciarInternacion, on
|
||||
onIniciarInternacion({
|
||||
pacienteId: pacienteSeleccionado,
|
||||
camaId: camaSeleccionada,
|
||||
areaId: areaSeleccionada,
|
||||
medicoIngresante: medico,
|
||||
diagnosticoIngreso,
|
||||
motivoConsulta: motivoConsulta || undefined,
|
||||
@@ -163,15 +170,31 @@ export function NuevoIngreso({ pacientes, camas, areas, onIniciarInternacion, on
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Columna 2: Cama */}
|
||||
{/* Columna 2: Cama y Área */}
|
||||
<div className="space-y-6">
|
||||
<Card className="min-h-[200px]">
|
||||
<CardContent className="pt-6 space-y-4">
|
||||
<h3 className="font-semibold text-gray-900 flex items-center gap-2">
|
||||
<Bed className="h-4 w-4" />
|
||||
Asignación de Cama
|
||||
Asignación de Cama y Área
|
||||
</h3>
|
||||
|
||||
<div>
|
||||
<Label>Área de Trabajo *</Label>
|
||||
<Select value={areaSeleccionada} onValueChange={setAreaSeleccionada}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Seleccionar área" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{areasDisponibles.map(a => (
|
||||
<SelectItem key={a.id} value={a.id}>
|
||||
{a.nombre}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>Cama *</Label>
|
||||
<Select value={camaSeleccionada} onValueChange={setCamaSeleccionada}>
|
||||
|
||||
@@ -40,6 +40,7 @@ export interface Internacion {
|
||||
id: string;
|
||||
pacienteId: string;
|
||||
camaId: string;
|
||||
areaId: string;
|
||||
fechaIngresoHospital?: string;
|
||||
fechaIngresoClinica?: string;
|
||||
fechaEgreso?: string;
|
||||
|
||||
Reference in New Issue
Block a user