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:
+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]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user