Fix bed management: preserve camaId from frontend to backend
- Use camaId generated in frontend instead of generating new one in backend API - Remove patientId and internacionId from cama table (use internaciones table instead) - Fix discharge: delete cama if fuera de area, mark available otherwise - Fix MapaCamas to find patient via internaciones table
This commit is contained in:
@@ -239,7 +239,10 @@ app.put('/api/camas/:id', async (req, res) => {
|
|||||||
|
|
||||||
app.post('/api/camas', async (req, res) => {
|
app.post('/api/camas', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const cama = { ...req.body, id: generateUUID() };
|
const cama = req.body;
|
||||||
|
if (!cama.id) {
|
||||||
|
cama.id = generateUUID();
|
||||||
|
}
|
||||||
await createCama(cama);
|
await createCama(cama);
|
||||||
res.json(cama);
|
res.json(cama);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
+14
-1
@@ -1,6 +1,18 @@
|
|||||||
import * as mariadb from 'mariadb';
|
import * as mariadb from 'mariadb';
|
||||||
import * as bcrypt from 'bcryptjs';
|
import * as bcrypt from 'bcryptjs';
|
||||||
|
|
||||||
|
// UUID generator
|
||||||
|
export function generateUUID() {
|
||||||
|
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
|
||||||
|
return crypto.randomUUID();
|
||||||
|
}
|
||||||
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
||||||
|
const r = (Math.random() * 16) | 0;
|
||||||
|
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
||||||
|
return v.toString(16);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// MariaDB connection pool
|
// MariaDB connection pool
|
||||||
const pool = mariadb.createPool({
|
const pool = mariadb.createPool({
|
||||||
host: process.env.DB_HOST || '10.9.8.135',
|
host: process.env.DB_HOST || '10.9.8.135',
|
||||||
@@ -350,9 +362,10 @@ export async function getCamaById(id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function createCama(cama) {
|
export async function createCama(cama) {
|
||||||
|
const id = cama.id || generateUUID();
|
||||||
await query(
|
await query(
|
||||||
'INSERT INTO camas (id, numero, areaId, tipo, estado) VALUES (?, ?, ?, ?, ?)',
|
'INSERT INTO camas (id, numero, areaId, tipo, estado) VALUES (?, ?, ?, ?, ?)',
|
||||||
[cama.id, cama.numero, cama.areaId, cama.tipo, cama.estado]
|
[id, cama.numero, cama.areaId, cama.tipo, cama.estado]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ export function useHospitalStore() {
|
|||||||
}
|
}
|
||||||
}, [state.camas, state.currentUser, apiCall]);
|
}, [state.camas, state.currentUser, apiCall]);
|
||||||
|
|
||||||
const agregarCama = useCallback(async (cama: Omit<Cama, 'id'>) => {
|
const agregarCama = useCallback(async (cama: Omit<Cama, 'id'>) => {
|
||||||
const nuevaCama: Cama = {
|
const nuevaCama: Cama = {
|
||||||
...cama,
|
...cama,
|
||||||
id: generateUUID(),
|
id: generateUUID(),
|
||||||
@@ -303,7 +303,7 @@ export function useHospitalStore() {
|
|||||||
}
|
}
|
||||||
}, [apiCall]);
|
}, [apiCall]);
|
||||||
|
|
||||||
// Acciones de internaciones
|
// Acciones de internaciones
|
||||||
const iniciarInternacion = useCallback(async (internacion: Omit<Internacion, 'id' | 'activa'>) => {
|
const iniciarInternacion = useCallback(async (internacion: Omit<Internacion, 'id' | 'activa'>) => {
|
||||||
const nuevaInternacion: Internacion = {
|
const nuevaInternacion: Internacion = {
|
||||||
...internacion,
|
...internacion,
|
||||||
@@ -315,11 +315,9 @@ export function useHospitalStore() {
|
|||||||
// API call inmediata para crear internación
|
// API call inmediata para crear internación
|
||||||
await apiCall('POST', '/internaciones', nuevaInternacion);
|
await apiCall('POST', '/internaciones', nuevaInternacion);
|
||||||
|
|
||||||
// Actualizar estado de la cama en la base de datos
|
// Actualizar estado de la cama en la base de datos (solo estado)
|
||||||
await apiCall('PUT', `/camas/${internacion.camaId}`, {
|
await apiCall('PUT', `/camas/${internacion.camaId}`, {
|
||||||
estado: 'Ocupada',
|
estado: 'Ocupada'
|
||||||
pacienteId: internacion.pacienteId,
|
|
||||||
internacionId: nuevaInternacion.id
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Actualizar estado local después del éxito
|
// Actualizar estado local después del éxito
|
||||||
@@ -328,7 +326,7 @@ export function useHospitalStore() {
|
|||||||
internaciones: [...prev.internaciones, nuevaInternacion],
|
internaciones: [...prev.internaciones, nuevaInternacion],
|
||||||
camas: prev.camas.map(c =>
|
camas: prev.camas.map(c =>
|
||||||
c.id === internacion.camaId
|
c.id === internacion.camaId
|
||||||
? { ...c, estado: 'Ocupada' as const, pacienteId: internacion.pacienteId, internacionId: nuevaInternacion.id }
|
? { ...c, estado: 'Ocupada' as const }
|
||||||
: c
|
: c
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
@@ -348,9 +346,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 || '').trim().toLowerCase() === 'fuera de area');
|
const areaFueraDeArea = state.areas.find(a => (a.nombre || '').toLowerCase().trim() === 'fuera de area');
|
||||||
const areaFueraDeAreaId = areaFueraDeArea?.id;
|
const areaFueraDeAreaId = areaFueraDeArea?.id;
|
||||||
const esFueraDeArea = internacion.areaId === areaFueraDeAreaId;
|
const esFueraDeArea = !internacion.areaId || !areaFueraDeAreaId || internacion.areaId === areaFueraDeAreaId;
|
||||||
const camaId = internacion.camaId;
|
const camaId = internacion.camaId;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -365,9 +363,7 @@ const finalizarInternacion = useCallback(async (internacionId: string, datos: {
|
|||||||
} else {
|
} else {
|
||||||
// Marcar como disponible si es un área normal
|
// Marcar como disponible si es un área normal
|
||||||
await apiCall('PUT', `/camas/${camaId}`, {
|
await apiCall('PUT', `/camas/${camaId}`, {
|
||||||
estado: 'Disponible',
|
estado: 'Disponible'
|
||||||
pacienteId: null,
|
|
||||||
internacionId: null
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -385,7 +381,7 @@ const finalizarInternacion = useCallback(async (internacionId: string, datos: {
|
|||||||
? prev.camas.filter(c => c.id !== camaId)
|
? prev.camas.filter(c => c.id !== camaId)
|
||||||
: prev.camas.map(c =>
|
: prev.camas.map(c =>
|
||||||
c.id === camaId
|
c.id === camaId
|
||||||
? { ...c, estado: 'Disponible' as const, pacienteId: undefined, internacionId: undefined }
|
? { ...c, estado: 'Disponible' as const }
|
||||||
: c
|
: c
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@@ -414,8 +410,6 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pacienteId = datos.pacienteId || internacion.pacienteId;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// API call inmediata
|
// API call inmediata
|
||||||
await apiCall('PUT', `/internaciones/${internacionId}`, datos);
|
await apiCall('PUT', `/internaciones/${internacionId}`, datos);
|
||||||
@@ -423,18 +417,14 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
// Si hay cambio de cama, actualizar estados en la base de datos
|
// Si hay cambio de cama, actualizar estados en la base de datos
|
||||||
if (cambioDeCama && newCamaId && oldCamaId) {
|
if (cambioDeCama && newCamaId && oldCamaId) {
|
||||||
await apiCall('PUT', `/camas/${newCamaId}`, {
|
await apiCall('PUT', `/camas/${newCamaId}`, {
|
||||||
estado: 'Ocupada',
|
estado: 'Ocupada'
|
||||||
pacienteId,
|
|
||||||
internacionId
|
|
||||||
});
|
});
|
||||||
await apiCall('PUT', `/camas/${oldCamaId}`, {
|
await apiCall('PUT', `/camas/${oldCamaId}`, {
|
||||||
estado: 'Disponible',
|
estado: 'Disponible'
|
||||||
pacienteId: null,
|
|
||||||
internacionId: null
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualizar estado local después del éxito
|
// Actualizar estado local después del éxito
|
||||||
setState(prev => {
|
setState(prev => {
|
||||||
const result = {
|
const result = {
|
||||||
...prev,
|
...prev,
|
||||||
@@ -443,12 +433,12 @@ const actualizarInternacion = useCallback(async (internacionId: string, datos: P
|
|||||||
? { ...i, ...datos }
|
? { ...i, ...datos }
|
||||||
: i
|
: i
|
||||||
),
|
),
|
||||||
camas: prev.camas.map(c => {
|
cams: prev.camas.map(c => {
|
||||||
if (c.id === newCamaId && newCamaId !== oldCamaId) {
|
if (c.id === newCamaId && newCamaId !== oldCamaId) {
|
||||||
return { ...c, estado: 'Ocupada' as const, pacienteId, internacionId };
|
return { ...c, estado: 'Ocupada' as const };
|
||||||
}
|
}
|
||||||
if (c.id === oldCamaId && oldCamaId !== newCamaId) {
|
if (c.id === oldCamaId && oldCamaId !== newCamaId) {
|
||||||
return { ...c, estado: 'Disponible' as const, pacienteId: undefined, internacionId: undefined };
|
return { ...c, estado: 'Disponible' as const };
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -265,11 +265,11 @@ export function MapaCamas({
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* Mapa de Camas */}
|
{/* Mapa de Camas */}
|
||||||
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-2 sm:gap-4">
|
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-2 sm:gap-4">
|
||||||
{sortedCamas.map((cama) => {
|
{sortedCamas.map((cama) => {
|
||||||
const paciente = cama.pacienteId ? getPacienteById(cama.pacienteId) : null;
|
const internacion = internaciones.find(i => i.camaId === cama.id && i.activa);
|
||||||
const internacion = cama.internacionId ? getInternacionById(cama.internacionId) : null;
|
const paciente = internacion ? getPacienteById(internacion.pacienteId) : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog key={cama.id}>
|
<Dialog key={cama.id}>
|
||||||
@@ -297,6 +297,7 @@ export function MapaCamas({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
|
|||||||
Reference in New Issue
Block a user