Fix: Organizacion de Editar Ingreso igual a Nuevo Ingreso, corregido formato de fecha
This commit is contained in:
+7
-4
@@ -47,7 +47,8 @@ db.exec(`
|
|||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
pacienteId TEXT NOT NULL,
|
pacienteId TEXT NOT NULL,
|
||||||
camaId TEXT,
|
camaId TEXT,
|
||||||
fechaIngreso TEXT NOT NULL,
|
fechaIngresoHospital TEXT,
|
||||||
|
fechaIngresoClinica TEXT,
|
||||||
fechaEgreso TEXT,
|
fechaEgreso TEXT,
|
||||||
diagnosticoIngreso TEXT,
|
diagnosticoIngreso TEXT,
|
||||||
motivoConsulta TEXT,
|
motivoConsulta TEXT,
|
||||||
@@ -56,7 +57,9 @@ db.exec(`
|
|||||||
diagnosticoEgreso TEXT,
|
diagnosticoEgreso TEXT,
|
||||||
medicoIngresante TEXT,
|
medicoIngresante TEXT,
|
||||||
motivoEgreso TEXT,
|
motivoEgreso TEXT,
|
||||||
activa INTEGER DEFAULT 1
|
activa INTEGER DEFAULT 1,
|
||||||
|
apache TEXT,
|
||||||
|
derivacion TEXT
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS evoluciones (
|
CREATE TABLE IF NOT EXISTS evoluciones (
|
||||||
@@ -200,9 +203,9 @@ app.put('/api/state', (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state.internaciones?.length) {
|
if (state.internaciones?.length) {
|
||||||
const stmt = db.prepare('INSERT INTO internaciones (id, pacienteId, camaId, fechaIngreso, fechaEgreso, diagnosticoIngreso, motivoConsulta, enfermedadActual, antecedentesEnfermedadActual, diagnosticoEgreso, medicoIngresante, motivoEgreso, activa) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
const stmt = db.prepare('INSERT INTO internaciones (id, pacienteId, camaId, 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.fechaIngreso, 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);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+40
-2
@@ -8,6 +8,8 @@ import { Evoluciones } from '@/sections/Evoluciones';
|
|||||||
import { AcidoBaseSection } from '@/sections/AcidoBase';
|
import { AcidoBaseSection } from '@/sections/AcidoBase';
|
||||||
import { Cultivos } from '@/sections/Cultivos';
|
import { Cultivos } from '@/sections/Cultivos';
|
||||||
import { HistoriaClinica } from '@/sections/HistoriaClinica';
|
import { HistoriaClinica } from '@/sections/HistoriaClinica';
|
||||||
|
import { NuevoIngreso } from '@/sections/NuevoIngreso';
|
||||||
|
import { EditIngreso } from '@/sections/EditIngreso';
|
||||||
import { Spinner } from '@/components/ui/spinner';
|
import { Spinner } from '@/components/ui/spinner';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
|
|
||||||
@@ -77,6 +79,7 @@ function App() {
|
|||||||
getPacienteById={store.getPacienteById}
|
getPacienteById={store.getPacienteById}
|
||||||
getCamaById={store.getCamaById}
|
getCamaById={store.getCamaById}
|
||||||
onVerHC={(id) => { store.setCurrentInternacion(id); store.setVista('historiaclinica'); }}
|
onVerHC={(id) => { store.setCurrentInternacion(id); store.setVista('historiaclinica'); }}
|
||||||
|
onNuevoIngreso={() => store.setVista('nuevoingreso')}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 'evoluciones':
|
case 'evoluciones':
|
||||||
@@ -152,12 +155,47 @@ function App() {
|
|||||||
onActualizarInternacion={store.actualizarInternacion}
|
onActualizarInternacion={store.actualizarInternacion}
|
||||||
onActualizarCama={store.actualizarCama}
|
onActualizarCama={store.actualizarCama}
|
||||||
onVolver={() => store.setVista('internaciones')}
|
onVolver={() => store.setVista('internaciones')}
|
||||||
|
onEditarIngreso={() => { store.setVista('editaringreso'); }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
case 'nuevoingreso':
|
||||||
|
return (
|
||||||
|
<NuevoIngreso
|
||||||
|
pacientes={store.pacientes}
|
||||||
|
camas={store.camas}
|
||||||
|
areas={store.areas}
|
||||||
|
onIniciarInternacion={store.iniciarInternacion}
|
||||||
|
onVolver={() => store.setVista('internaciones')}
|
||||||
|
getAreaName={(areaId) => store.areas.find(a => a.id === areaId)?.nombre || ''}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case 'editaringreso': {
|
||||||
default:
|
const internacion = store.getInternacionById(store.currentInternacionId || '');
|
||||||
|
const paciente = internacion ? store.getPacienteById(internacion.pacienteId) : undefined;
|
||||||
|
if (!internacion || !paciente) {
|
||||||
|
return (
|
||||||
|
<div className="p-4 text-center">
|
||||||
|
<p className="text-gray-500">Internación no encontrada</p>
|
||||||
|
<Button onClick={() => store.setVista('internaciones')}>Volver a Internaciones</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<EditIngreso
|
||||||
|
internacion={internacion}
|
||||||
|
paciente={paciente}
|
||||||
|
cama={store.getCamaById(internacion.camaId)}
|
||||||
|
pacientes={store.pacientes}
|
||||||
|
camas={store.camas}
|
||||||
|
areas={store.areas}
|
||||||
|
onActualizarInternacion={store.actualizarInternacion}
|
||||||
|
onVolver={() => store.setVista('historiaclinica')}
|
||||||
|
getAreaName={(areaId) => store.areas.find(a => a.id === areaId)?.nombre || ''}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -157,11 +157,10 @@ export function useHospitalStore() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Acciones de internaciones
|
// Acciones de internaciones
|
||||||
const iniciarInternacion = useCallback((internacion: Omit<Internacion, 'id' | 'fechaIngreso' | 'activa'>) => {
|
const iniciarInternacion = useCallback((internacion: Omit<Internacion, 'id' | 'activa'>) => {
|
||||||
const nuevaInternacion: Internacion = {
|
const nuevaInternacion: Internacion = {
|
||||||
...internacion,
|
...internacion,
|
||||||
id: generateUUID(),
|
id: generateUUID(),
|
||||||
fechaIngreso: new Date().toISOString().split('T')[0],
|
|
||||||
activa: true,
|
activa: true,
|
||||||
};
|
};
|
||||||
setState(prev => ({
|
setState(prev => ({
|
||||||
|
|||||||
+3
-5
@@ -7,10 +7,8 @@ export function cn(...inputs: ClassValue[]) {
|
|||||||
|
|
||||||
export function formatDateDDMMYYYY(dateString: string): string {
|
export function formatDateDDMMYYYY(dateString: string): string {
|
||||||
if (!dateString) return '';
|
if (!dateString) return '';
|
||||||
const date = new Date(dateString);
|
const parts = dateString.split('-');
|
||||||
if (isNaN(date.getTime())) return dateString;
|
if (parts.length !== 3) return dateString;
|
||||||
const day = String(date.getDate()).padStart(2, '0');
|
const [year, month, day] = parts;
|
||||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
||||||
const year = date.getFullYear();
|
|
||||||
return `${day}-${month}-${year}`;
|
return `${day}-${month}-${year}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ export function Dashboard({
|
|||||||
{paciente ? `${paciente.apellido}, ${paciente.nombre}` : 'Paciente no encontrado'}
|
{paciente ? `${paciente.apellido}, ${paciente.nombre}` : 'Paciente no encontrado'}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
Ingreso: {formatDateDDMMYYYY(internacion.fechaIngreso)}
|
Ingreso: {internacion.fechaIngresoClinica ? formatDateDDMMYYYY(internacion.fechaIngresoClinica) : 'N/A'}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Badge variant="outline" className="bg-purple-50 text-purple-700">
|
<Badge variant="outline" className="bg-purple-50 text-purple-700">
|
||||||
|
|||||||
@@ -0,0 +1,323 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import { ArrowLeft, Save, X, Bed, Calendar, Stethoscope, User, ClipboardList } from 'lucide-react';
|
||||||
|
import { Card, CardContent } from '@/components/ui/card';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { Input } from '@/components/ui/input';
|
||||||
|
import { Label } from '@/components/ui/label';
|
||||||
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||||
|
import { Badge } from '@/components/ui/badge';
|
||||||
|
import type { Paciente, Cama, Area, Internacion } from '@/types';
|
||||||
|
|
||||||
|
interface EditIngresoProps {
|
||||||
|
internacion: Internacion;
|
||||||
|
paciente: Paciente;
|
||||||
|
cama: Cama | undefined;
|
||||||
|
pacientes: Paciente[];
|
||||||
|
camas: Cama[];
|
||||||
|
areas: Area[];
|
||||||
|
onActualizarInternacion: (id: string, datos: Partial<Internacion>) => void;
|
||||||
|
onVolver: () => void;
|
||||||
|
getAreaName: (areaId: string | undefined) => string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function EditIngreso({
|
||||||
|
internacion,
|
||||||
|
paciente: pacienteOriginal,
|
||||||
|
cama: camaOriginal,
|
||||||
|
pacientes,
|
||||||
|
camas,
|
||||||
|
areas,
|
||||||
|
onActualizarInternacion,
|
||||||
|
onVolver,
|
||||||
|
getAreaName
|
||||||
|
}: EditIngresoProps) {
|
||||||
|
const [pacienteSeleccionado, setPacienteSeleccionado] = useState(internacion.pacienteId);
|
||||||
|
const [busqueda, setBusqueda] = useState('');
|
||||||
|
const [camaSeleccionada, setCamaSeleccionada] = useState(internacion.camaId);
|
||||||
|
const [medico, setMedico] = useState(internacion.medicoIngresante);
|
||||||
|
const [fechaIngresoHospital, setFechaIngresoHospital] = useState(internacion.fechaIngresoHospital || '');
|
||||||
|
const [fechaIngresoClinica, setFechaIngresoClinica] = useState(internacion.fechaIngresoClinica || '');
|
||||||
|
const [motivoConsulta, setMotivoConsulta] = useState(internacion.motivoConsulta || '');
|
||||||
|
const [diagnosticoIngreso, setDiagnosticoIngreso] = useState(internacion.diagnosticoIngreso);
|
||||||
|
const [enfermedadActual, setEnfermedadActual] = useState(internacion.enfermedadActual);
|
||||||
|
const [antecedentesEnfermedadActual, setAntecedentesEnfermedadActual] = useState(internacion.antecedentesEnfermedadActual || '');
|
||||||
|
const [apache, setApache] = useState(internacion.apache || '');
|
||||||
|
const [derivacion, setDerivacion] = useState(internacion.derivacion || '');
|
||||||
|
|
||||||
|
const selectedPaciente = pacientes.find(p => p.id === pacienteSeleccionado);
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (!pacienteSeleccionado || !camaSeleccionada || !medico || !diagnosticoIngreso || !enfermedadActual) {
|
||||||
|
alert('Por favor complete los campos obligatorios');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
onActualizarInternacion(internacion.id, {
|
||||||
|
pacienteId: pacienteSeleccionado,
|
||||||
|
camaId: camaSeleccionada,
|
||||||
|
medicoIngresante: medico,
|
||||||
|
diagnosticoIngreso,
|
||||||
|
motivoConsulta: motivoConsulta || undefined,
|
||||||
|
enfermedadActual,
|
||||||
|
antecedentesEnfermedadActual: antecedentesEnfermedadActual || undefined,
|
||||||
|
fechaIngresoHospital: fechaIngresoHospital || undefined,
|
||||||
|
fechaIngresoClinica: fechaIngresoClinica || undefined,
|
||||||
|
apache: apache || undefined,
|
||||||
|
derivacion: derivacion || undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
onVolver();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-6">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<Button variant="ghost" size="icon" onClick={onVolver}>
|
||||||
|
<ArrowLeft className="h-5 w-5" />
|
||||||
|
</Button>
|
||||||
|
<div>
|
||||||
|
<h1 className="text-2xl font-bold text-gray-900 flex items-center gap-2">
|
||||||
|
<User className="h-6 w-6 text-blue-600" />
|
||||||
|
Editar Ingreso
|
||||||
|
</h1>
|
||||||
|
<p className="text-gray-500">Modificar datos de internación</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Button variant="outline" onClick={() => onVolver()}>
|
||||||
|
<X className="h-4 w-4 mr-2" />
|
||||||
|
Cancelar
|
||||||
|
</Button>
|
||||||
|
<Button className="bg-blue-600 hover:bg-blue-700" onClick={handleSubmit}>
|
||||||
|
<Save className="h-4 w-4 mr-2" />
|
||||||
|
Guardar Cambios
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||||
|
{/* Columna 1: Datos del Paciente, Cama y Datos Adicionales */}
|
||||||
|
<div className="space-y-6">
|
||||||
|
<Card>
|
||||||
|
<CardContent className="pt-6 space-y-4">
|
||||||
|
<h3 className="font-semibold text-gray-900 flex items-center gap-2">
|
||||||
|
<User className="h-4 w-4" />
|
||||||
|
Datos del Paciente
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
{selectedPaciente ? (
|
||||||
|
<div className="flex items-center gap-2 flex-wrap">
|
||||||
|
<Badge className="bg-blue-100 text-blue-800">
|
||||||
|
{selectedPaciente?.apellido}, {selectedPaciente?.nombre}
|
||||||
|
</Badge>
|
||||||
|
<Badge variant="outline">DNI: {selectedPaciente?.dni}</Badge>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Label>Buscar Paciente *</Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Apellido, nombre o DNI"
|
||||||
|
value={busqueda}
|
||||||
|
onChange={(e) => setBusqueda(e.target.value)}
|
||||||
|
/>
|
||||||
|
<div className="max-h-48 overflow-auto border rounded-md">
|
||||||
|
{(() => {
|
||||||
|
const q = busqueda.trim().toLowerCase();
|
||||||
|
if (!q) {
|
||||||
|
return <div className="p-2 text-sm text-gray-500">Escriba para buscar</div>;
|
||||||
|
}
|
||||||
|
const matches = pacientes.filter(p =>
|
||||||
|
p.apellido.toLowerCase().includes(q) ||
|
||||||
|
p.nombre.toLowerCase().includes(q) ||
|
||||||
|
p.dni.includes(q)
|
||||||
|
);
|
||||||
|
if (matches.length === 0) {
|
||||||
|
return <div className="p-2 text-sm text-gray-500">Sin resultados</div>;
|
||||||
|
}
|
||||||
|
return matches.map(p => (
|
||||||
|
<button
|
||||||
|
key={p.id}
|
||||||
|
type="button"
|
||||||
|
onClick={() => setPacienteSeleccionado(p.id)}
|
||||||
|
className="w-full text-left p-2 hover:bg-gray-50 text-sm"
|
||||||
|
>
|
||||||
|
{p.apellido}, {p.nombre} — DNI: {p.dni}
|
||||||
|
</button>
|
||||||
|
));
|
||||||
|
})()}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<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
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Cama *</Label>
|
||||||
|
<Select value={camaSeleccionada} onValueChange={setCamaSeleccionada}>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Seleccionar cama" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{camas.map(c => (
|
||||||
|
<SelectItem key={c.id} value={c.id}>
|
||||||
|
{c.numero} - {getAreaName(c.areaId)} ({c.tipo})
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<CardContent className="pt-6 space-y-4">
|
||||||
|
<h3 className="font-semibold text-gray-900 flex items-center gap-2">
|
||||||
|
<ClipboardList className="h-4 w-4" />
|
||||||
|
Datos Adicionales
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Apache / Mortalidad</Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Valor Apache o riesgo"
|
||||||
|
value={apache}
|
||||||
|
onChange={(e) => setApache(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label>Derivado de</Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Hospital o clínica de derivación"
|
||||||
|
value={derivacion}
|
||||||
|
onChange={(e) => setDerivacion(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Columna 2: Datos de Ingreso */}
|
||||||
|
<div className="space-y-6">
|
||||||
|
<Card>
|
||||||
|
<CardContent className="pt-6 space-y-4">
|
||||||
|
<h3 className="font-semibold text-gray-900 flex items-center gap-2">
|
||||||
|
<ClipboardList className="h-4 w-4" />
|
||||||
|
Datos de Ingreso
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Fecha Ingreso al Hospital</Label>
|
||||||
|
<Input
|
||||||
|
type="date"
|
||||||
|
value={fechaIngresoHospital}
|
||||||
|
onChange={(e) => setFechaIngresoHospital(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label>Fecha Ingreso a Clínica Médica</Label>
|
||||||
|
<Input
|
||||||
|
type="date"
|
||||||
|
value={fechaIngresoClinica}
|
||||||
|
onChange={(e) => setFechaIngresoClinica(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label>Apache / Mortalidad</Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Valor Apache o riesgo"
|
||||||
|
value={apache}
|
||||||
|
onChange={(e) => setApache(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label>Derivado de</Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Hospital o clínica de derivación"
|
||||||
|
value={derivacion}
|
||||||
|
onChange={(e) => setDerivacion(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<CardContent className="pt-6 space-y-4">
|
||||||
|
<h3 className="font-semibold text-gray-900 flex items-center gap-2">
|
||||||
|
<Stethoscope className="h-4 w-4" />
|
||||||
|
Médico Ingresante
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Médico Ingresante *</Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Nombre del médico"
|
||||||
|
value={medico}
|
||||||
|
onChange={(e) => setMedico(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Columna 3: Datos Clínicos */}
|
||||||
|
<div className="space-y-6">
|
||||||
|
<Card>
|
||||||
|
<CardContent className="pt-6 space-y-4">
|
||||||
|
<h3 className="font-semibold text-gray-900">
|
||||||
|
Datos Clínicos
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Motivo de Consulta *</Label>
|
||||||
|
<textarea
|
||||||
|
className="w-full p-2 border rounded-md text-sm min-h-[80px]"
|
||||||
|
placeholder="Motivo por el cual consulta"
|
||||||
|
value={motivoConsulta}
|
||||||
|
onChange={(e) => setMotivoConsulta(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Diagnóstico de Ingreso *</Label>
|
||||||
|
<textarea
|
||||||
|
className="w-full p-2 border rounded-md text-sm min-h-[80px]"
|
||||||
|
placeholder="Diagnóstico principal"
|
||||||
|
value={diagnosticoIngreso}
|
||||||
|
onChange={(e) => setDiagnosticoIngreso(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Enfermedad Actual *</Label>
|
||||||
|
<textarea
|
||||||
|
className="w-full p-2 border rounded-md text-sm min-h-[100px]"
|
||||||
|
placeholder="Descripción de la enfermedad actual"
|
||||||
|
value={enfermedadActual}
|
||||||
|
onChange={(e) => setEnfermedadActual(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Antecedentes de la Enfermedad Actual</Label>
|
||||||
|
<textarea
|
||||||
|
className="w-full p-2 border rounded-md text-sm min-h-[80px]"
|
||||||
|
placeholder="Antecedentes relevantes"
|
||||||
|
value={antecedentesEnfermedadActual}
|
||||||
|
onChange={(e) => setAntecedentesEnfermedadActual(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -58,6 +58,7 @@ interface HistoriaClinicaProps {
|
|||||||
onActualizarInternacion: (id: string, datos: Partial<Internacion>) => void;
|
onActualizarInternacion: (id: string, datos: Partial<Internacion>) => void;
|
||||||
onActualizarCama: (id: string, datos: Partial<Cama>) => void;
|
onActualizarCama: (id: string, datos: Partial<Cama>) => void;
|
||||||
onVolver: () => void;
|
onVolver: () => void;
|
||||||
|
onEditarIngreso?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PARAMETROS_COMUNES: Record<string, { unidad: string; referencia: string }> = {
|
const PARAMETROS_COMUNES: Record<string, { unidad: string; referencia: string }> = {
|
||||||
@@ -154,11 +155,12 @@ export function HistoriaClinica({
|
|||||||
onActualizarInternacion,
|
onActualizarInternacion,
|
||||||
onActualizarCama,
|
onActualizarCama,
|
||||||
onVolver,
|
onVolver,
|
||||||
|
onEditarIngreso,
|
||||||
}: HistoriaClinicaProps) {
|
}: HistoriaClinicaProps) {
|
||||||
const [tabActivo, setTabActivo] = useState('evoluciones');
|
const [tabActivo, setTabActivo] = useState('evoluciones');
|
||||||
const [detalleExpandido, setDetalleExpandido] = useState(false);
|
const [detalleExpandido, setDetalleExpandido] = useState(false);
|
||||||
const [editIngresoDialog, setEditIngresoDialog] = useState(false);
|
const [editIngresoDialog, setEditIngresoDialog] = useState(false);
|
||||||
const [editFechaIngreso, setEditFechaIngreso] = useState(internacion.fechaIngreso);
|
const [editFechaIngreso, setEditFechaIngreso] = useState(internacion.fechaIngresoClinica);
|
||||||
const [editMotivoConsulta, setEditMotivoConsulta] = useState(internacion.motivoConsulta || '');
|
const [editMotivoConsulta, setEditMotivoConsulta] = useState(internacion.motivoConsulta || '');
|
||||||
const [editDiagnostico, setEditDiagnostico] = useState(internacion.diagnosticoIngreso || '');
|
const [editDiagnostico, setEditDiagnostico] = useState(internacion.diagnosticoIngreso || '');
|
||||||
const [editEnfermedadActual, setEditEnfermedadActual] = useState(internacion.enfermedadActual || '');
|
const [editEnfermedadActual, setEditEnfermedadActual] = useState(internacion.enfermedadActual || '');
|
||||||
@@ -192,7 +194,7 @@ export function HistoriaClinica({
|
|||||||
onActualizarCama(editCamaId, { estado: 'Ocupada', pacienteId: paciente.id, internacionId: internacion.id });
|
onActualizarCama(editCamaId, { estado: 'Ocupada', pacienteId: paciente.id, internacionId: internacion.id });
|
||||||
}
|
}
|
||||||
onActualizarInternacion(internacion.id, {
|
onActualizarInternacion(internacion.id, {
|
||||||
fechaIngreso: editFechaIngreso,
|
fechaIngresoClinica: editFechaIngreso,
|
||||||
motivoConsulta: editMotivoConsulta,
|
motivoConsulta: editMotivoConsulta,
|
||||||
diagnosticoIngreso: editDiagnostico,
|
diagnosticoIngreso: editDiagnostico,
|
||||||
enfermedadActual: editEnfermedadActual,
|
enfermedadActual: editEnfermedadActual,
|
||||||
@@ -222,7 +224,7 @@ export function HistoriaClinica({
|
|||||||
<ArrowLeft className="h-4 w-4 mr-2" />
|
<ArrowLeft className="h-4 w-4 mr-2" />
|
||||||
Volver
|
Volver
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline" onClick={() => setEditIngresoDialog(true)}>
|
<Button variant="outline" onClick={onEditarIngreso}>
|
||||||
<Pencil className="h-4 w-4 mr-2" />
|
<Pencil className="h-4 w-4 mr-2" />
|
||||||
Editar Ingreso
|
Editar Ingreso
|
||||||
</Button>
|
</Button>
|
||||||
@@ -292,12 +294,12 @@ export function HistoriaClinica({
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p className="text-gray-500">Antecedentes</p>
|
<p className="text-gray-500">Antecedentes</p>
|
||||||
<p className="font-medium truncate">{paciente.antecedentes || 'Sin registrados'}</p>
|
<p className="font-medium truncate">{paciente.antecedentes || 'No constan'}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p className="text-gray-500">Fecha de Ingreso</p>
|
<p className="text-gray-500">Fecha de Ingreso</p>
|
||||||
<p className="font-medium">{formatDateDDMMYYYY(internacion.fechaIngreso)}</p>
|
<p className="font-medium">{internacion.fechaIngresoClinica ? formatDateDDMMYYYY(internacion.fechaIngresoClinica) : 'N/A'}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-gray-500">Diagnóstico de Ingreso</p>
|
<p className="text-gray-500">Diagnóstico de Ingreso</p>
|
||||||
@@ -305,8 +307,8 @@ export function HistoriaClinica({
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-gray-500">Días de Internación</p>
|
<p className="text-gray-500">Días de Internación</p>
|
||||||
<Badge className={calcularDiasInternado(internacion.fechaIngreso) > 7 ? 'bg-red-100 text-red-800' : 'bg-blue-100 text-blue-800'}>
|
<Badge className={internacion.fechaIngresoClinica && calcularDiasInternado(internacion.fechaIngresoClinica) > 7 ? 'bg-red-100 text-red-800' : 'bg-blue-100 text-blue-800'}>
|
||||||
{calcularDiasInternado(internacion.fechaIngreso)} días
|
{internacion.fechaIngresoClinica ? calcularDiasInternado(internacion.fechaIngresoClinica) : 0} días
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -344,7 +346,7 @@ export function HistoriaClinica({
|
|||||||
const colorLightGray = rgb(0.92, 0.92, 0.92);
|
const colorLightGray = rgb(0.92, 0.92, 0.92);
|
||||||
|
|
||||||
const edad = paciente.fechaNacimiento ? calcularEdad(paciente.fechaNacimiento) : '';
|
const edad = paciente.fechaNacimiento ? calcularEdad(paciente.fechaNacimiento) : '';
|
||||||
const fechaFormateada = formatDateDDMMYYYY(internacion.fechaIngreso);
|
const fechaFormateada = internacion.fechaIngresoClinica ? formatDateDDMMYYYY(internacion.fechaIngresoClinica) : 'N/A';
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
page.drawRectangle({ x: 0, y: height - 80, width, height: 80, color: colorPrimary });
|
page.drawRectangle({ x: 0, y: height - 80, width, height: 80, color: colorPrimary });
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ interface InternacionesProps {
|
|||||||
laboratorios?: Laboratorio[];
|
laboratorios?: Laboratorio[];
|
||||||
cultivos?: Cultivo[];
|
cultivos?: Cultivo[];
|
||||||
areas: Area[];
|
areas: Area[];
|
||||||
onIniciarInternacion: (internacion: Omit<Internacion, 'id' | 'fechaIngreso' | 'activa'>) => void;
|
onIniciarInternacion: (internacion: Omit<Internacion, 'id' | 'activa'>) => void;
|
||||||
onFinalizarInternacion: (internacionId: string, datos: {
|
onFinalizarInternacion: (internacionId: string, datos: {
|
||||||
fechaEgreso: string;
|
fechaEgreso: string;
|
||||||
diagnosticoEgreso: string;
|
diagnosticoEgreso: string;
|
||||||
@@ -27,6 +27,7 @@ interface InternacionesProps {
|
|||||||
getPacienteById: (id: string) => Paciente | undefined;
|
getPacienteById: (id: string) => Paciente | undefined;
|
||||||
getCamaById: (id: string) => Cama | undefined;
|
getCamaById: (id: string) => Cama | undefined;
|
||||||
onVerHC?: (internacionId: string) => void;
|
onVerHC?: (internacionId: string) => void;
|
||||||
|
onNuevoIngreso?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Internaciones({
|
export function Internaciones({
|
||||||
@@ -39,6 +40,7 @@ export function Internaciones({
|
|||||||
getCamaById,
|
getCamaById,
|
||||||
areas,
|
areas,
|
||||||
onVerHC,
|
onVerHC,
|
||||||
|
onNuevoIngreso,
|
||||||
}: InternacionesProps) {
|
}: InternacionesProps) {
|
||||||
const [filtroEstado, setFiltroEstado] = useState<'todas' | 'activas' | 'finalizadas'>('todas');
|
const [filtroEstado, setFiltroEstado] = useState<'todas' | 'activas' | 'finalizadas'>('todas');
|
||||||
const [dialogoNuevaAbierto, setDialogoNuevaAbierto] = useState(false);
|
const [dialogoNuevaAbierto, setDialogoNuevaAbierto] = useState(false);
|
||||||
@@ -116,7 +118,7 @@ export function Internaciones({
|
|||||||
(filtroEstado === 'finalizadas' && !i.activa);
|
(filtroEstado === 'finalizadas' && !i.activa);
|
||||||
|
|
||||||
return cumpleBusqueda && cumpleEstado;
|
return cumpleBusqueda && cumpleEstado;
|
||||||
}).sort((a, b) => new Date(b.fechaIngreso).getTime() - new Date(a.fechaIngreso).getTime());
|
}).sort((a, b) => new Date(b.fechaIngresoClinica || '').getTime() - new Date(a.fechaIngresoClinica || '').getTime());
|
||||||
|
|
||||||
const pacientesSinInternar = pacientes.filter(p => {
|
const pacientesSinInternar = pacientes.filter(p => {
|
||||||
const internacionActiva = internaciones.find(i => i.pacienteId === p.id && i.activa);
|
const internacionActiva = internaciones.find(i => i.pacienteId === p.id && i.activa);
|
||||||
@@ -143,7 +145,7 @@ export function Internaciones({
|
|||||||
</div>
|
</div>
|
||||||
<Dialog open={dialogoNuevaAbierto} onOpenChange={setDialogoNuevaAbierto}>
|
<Dialog open={dialogoNuevaAbierto} onOpenChange={setDialogoNuevaAbierto}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button onClick={resetFormularioNueva}>
|
<Button onClick={() => onNuevoIngreso ? onNuevoIngreso() : setDialogoNuevaAbierto(true)}>
|
||||||
<Plus className="h-4 w-4 mr-2" />
|
<Plus className="h-4 w-4 mr-2" />
|
||||||
Nuevo Ingreso
|
Nuevo Ingreso
|
||||||
</Button>
|
</Button>
|
||||||
@@ -334,7 +336,7 @@ export function Internaciones({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 text-gray-600">
|
<div className="flex items-center gap-2 text-gray-600">
|
||||||
<Calendar className="h-4 w-4" />
|
<Calendar className="h-4 w-4" />
|
||||||
<span>Ingreso: {formatDateDDMMYYYY(internacion.fechaIngreso)}</span>
|
<span>Ingreso: {internacion.fechaIngresoClinica ? formatDateDDMMYYYY(internacion.fechaIngresoClinica) : 'N/A'}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 text-gray-600">
|
<div className="flex items-center gap-2 text-gray-600">
|
||||||
<Stethoscope className="h-4 w-4" />
|
<Stethoscope className="h-4 w-4" />
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ interface MapaCamasProps {
|
|||||||
onActualizarCama: (id: string, datos: Partial<Cama>) => void;
|
onActualizarCama: (id: string, datos: Partial<Cama>) => void;
|
||||||
onAgregarCama: (cama: Omit<Cama, 'id'>) => string;
|
onAgregarCama: (cama: Omit<Cama, 'id'>) => string;
|
||||||
onEliminarCama: (id: string) => void;
|
onEliminarCama: (id: string) => void;
|
||||||
onIniciarInternacion: (internacion: Omit<Internacion, 'id' | 'fechaIngreso' | 'activa'>) => void;
|
onIniciarInternacion: (internacion: Omit<Internacion, 'id' | 'activa'>) => void;
|
||||||
onAgregarArea: (area: Omit<Area, 'id'>) => string;
|
onAgregarArea: (area: Omit<Area, 'id'>) => string;
|
||||||
onActualizarArea: (id: string, datos: Partial<Area>) => void;
|
onActualizarArea: (id: string, datos: Partial<Area>) => void;
|
||||||
onEliminarArea: (id: string) => void;
|
onEliminarArea: (id: string) => void;
|
||||||
@@ -332,7 +332,7 @@ export function MapaCamas({
|
|||||||
<p className="font-medium">Paciente:</p>
|
<p className="font-medium">Paciente:</p>
|
||||||
<p className="text-lg">{paciente.apellido}, {paciente.nombre}</p>
|
<p className="text-lg">{paciente.apellido}, {paciente.nombre}</p>
|
||||||
<p className="text-sm text-gray-500">DNI: {paciente.dni}</p>
|
<p className="text-sm text-gray-500">DNI: {paciente.dni}</p>
|
||||||
<p className="text-sm text-gray-500">Ingreso: {formatDateDDMMYYYY(internacion.fechaIngreso)}</p>
|
<p className="text-sm text-gray-500">Ingreso: {internacion.fechaIngresoClinica ? formatDateDDMMYYYY(internacion.fechaIngresoClinica) : 'N/A'}</p>
|
||||||
<p className="text-sm text-gray-500">Diagnóstico: {internacion.diagnosticoIngreso}</p>
|
<p className="text-sm text-gray-500">Diagnóstico: {internacion.diagnosticoIngreso}</p>
|
||||||
<p className="text-sm text-gray-500">Médico: {internacion.medicoIngresante}</p>
|
<p className="text-sm text-gray-500">Médico: {internacion.medicoIngresante}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,310 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { ArrowLeft, Save, X, Bed, Calendar, Stethoscope, User, ClipboardList } from 'lucide-react';
|
||||||
|
import { Card, CardContent } from '@/components/ui/card';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { Input } from '@/components/ui/input';
|
||||||
|
import { Label } from '@/components/ui/label';
|
||||||
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||||
|
import { Badge } from '@/components/ui/badge';
|
||||||
|
import type { Paciente, Cama, Area, Internacion } from '@/types';
|
||||||
|
|
||||||
|
interface NuevoIngresoProps {
|
||||||
|
pacientes: Paciente[];
|
||||||
|
camas: Cama[];
|
||||||
|
areas: Area[];
|
||||||
|
onIniciarInternacion: (internacion: Omit<Internacion, 'id' | 'activa'>) => void;
|
||||||
|
onVolver: () => void;
|
||||||
|
getAreaName: (areaId: string | undefined) => string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function NuevoIngreso({ pacientes, camas, areas, onIniciarInternacion, onVolver, getAreaName }: NuevoIngresoProps) {
|
||||||
|
const [pacienteSeleccionado, setPacienteSeleccionado] = useState<string>('');
|
||||||
|
const [busqueda, setBusqueda] = useState('');
|
||||||
|
const [camaSeleccionada, setCamaSeleccionada] = useState('');
|
||||||
|
const [medico, setMedico] = useState('');
|
||||||
|
const [fechaIngresoHospital, setFechaIngresoHospital] = useState('');
|
||||||
|
const [fechaIngresoClinica, setFechaIngresoClinica] = useState('');
|
||||||
|
const [motivoConsulta, setMotivoConsulta] = useState('');
|
||||||
|
const [diagnosticoIngreso, setDiagnosticoIngreso] = useState('');
|
||||||
|
const [enfermedadActual, setEnfermedadActual] = useState('');
|
||||||
|
const [antecedentesEnfermedadActual, setAntecedentesEnfermedadActual] = useState('');
|
||||||
|
const [apache, setApache] = useState('');
|
||||||
|
const [derivacion, setDerivacion] = useState('');
|
||||||
|
|
||||||
|
const resetFormulario = () => {
|
||||||
|
setPacienteSeleccionado('');
|
||||||
|
setBusqueda('');
|
||||||
|
setCamaSeleccionada('');
|
||||||
|
setMedico('');
|
||||||
|
setFechaIngresoHospital('');
|
||||||
|
setFechaIngresoClinica('');
|
||||||
|
setMotivoConsulta('');
|
||||||
|
setDiagnosticoIngreso('');
|
||||||
|
setEnfermedadActual('');
|
||||||
|
setAntecedentesEnfermedadActual('');
|
||||||
|
setApache('');
|
||||||
|
setDerivacion('');
|
||||||
|
};
|
||||||
|
|
||||||
|
const pacientesSinInternar = pacientes;
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (!pacienteSeleccionado || !camaSeleccionada || !medico || !diagnosticoIngreso || !enfermedadActual) {
|
||||||
|
alert('Por favor complete los campos obligatorios');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
onIniciarInternacion({
|
||||||
|
pacienteId: pacienteSeleccionado,
|
||||||
|
camaId: camaSeleccionada,
|
||||||
|
medicoIngresante: medico,
|
||||||
|
diagnosticoIngreso,
|
||||||
|
motivoConsulta: motivoConsulta || undefined,
|
||||||
|
enfermedadActual,
|
||||||
|
antecedentesEnfermedadActual: antecedentesEnfermedadActual || undefined,
|
||||||
|
fechaIngresoHospital: fechaIngresoHospital || undefined,
|
||||||
|
fechaIngresoClinica: fechaIngresoClinica || undefined,
|
||||||
|
apache: apache || undefined,
|
||||||
|
derivacion: derivacion || undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
resetFormulario();
|
||||||
|
onVolver();
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectedPaciente = pacientes.find(p => p.id === pacienteSeleccionado);
|
||||||
|
const camasDisponibles = camaSeleccionada
|
||||||
|
? []
|
||||||
|
: camas.filter(c => c.estado === 'Disponible' && !c.pacienteId);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-6">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<Button variant="ghost" size="icon" onClick={onVolver}>
|
||||||
|
<ArrowLeft className="h-5 w-5" />
|
||||||
|
</Button>
|
||||||
|
<div>
|
||||||
|
<h1 className="text-2xl font-bold text-gray-900 flex items-center gap-2">
|
||||||
|
<User className="h-6 w-6 text-blue-600" />
|
||||||
|
Nuevo Ingreso
|
||||||
|
</h1>
|
||||||
|
<p className="text-gray-500">Formulario de internación</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Button variant="outline" onClick={() => { resetFormulario(); onVolver(); }}>
|
||||||
|
<X className="h-4 w-4 mr-2" />
|
||||||
|
Cancelar
|
||||||
|
</Button>
|
||||||
|
<Button className="bg-blue-600 hover:bg-blue-700" onClick={handleSubmit}>
|
||||||
|
<Save className="h-4 w-4 mr-2" />
|
||||||
|
Guardar Ingreso
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||||
|
{/* Columna 1: Datos del Paciente, Cama y Datos Adicionales */}
|
||||||
|
<div className="space-y-6">
|
||||||
|
<Card>
|
||||||
|
<CardContent className="pt-6 space-y-4">
|
||||||
|
<h3 className="font-semibold text-gray-900 flex items-center gap-2">
|
||||||
|
<User className="h-4 w-4" />
|
||||||
|
Datos del Paciente
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
{!pacienteSeleccionado ? (
|
||||||
|
<>
|
||||||
|
<Label>Buscar Paciente *</Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Apellido, nombre o DNI"
|
||||||
|
value={busqueda}
|
||||||
|
onChange={(e) => setBusqueda(e.target.value)}
|
||||||
|
/>
|
||||||
|
<div className="max-h-48 overflow-auto border rounded-md">
|
||||||
|
{(() => {
|
||||||
|
const q = busqueda.trim().toLowerCase();
|
||||||
|
if (!q) {
|
||||||
|
return <div className="p-2 text-sm text-gray-500">Escriba para buscar</div>;
|
||||||
|
}
|
||||||
|
const matches = pacientesSinInternar.filter(p =>
|
||||||
|
p.apellido.toLowerCase().includes(q) ||
|
||||||
|
p.nombre.toLowerCase().includes(q) ||
|
||||||
|
p.dni.includes(q)
|
||||||
|
);
|
||||||
|
if (matches.length === 0) {
|
||||||
|
return <div className="p-2 text-sm text-gray-500">Sin resultados</div>;
|
||||||
|
}
|
||||||
|
return matches.map(p => (
|
||||||
|
<button
|
||||||
|
key={p.id}
|
||||||
|
type="button"
|
||||||
|
onClick={() => setPacienteSeleccionado(p.id)}
|
||||||
|
className="w-full text-left p-2 hover:bg-gray-50 text-sm"
|
||||||
|
>
|
||||||
|
{p.apellido}, {p.nombre} — DNI: {p.dni}
|
||||||
|
</button>
|
||||||
|
));
|
||||||
|
})()}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div className="flex items-center gap-2 flex-wrap">
|
||||||
|
<Badge className="bg-blue-100 text-blue-800">
|
||||||
|
{selectedPaciente?.apellido}, {selectedPaciente?.nombre}
|
||||||
|
</Badge>
|
||||||
|
<Badge variant="outline">DNI: {selectedPaciente?.dni}</Badge>
|
||||||
|
<Button size="sm" variant="ghost" onClick={() => { setPacienteSeleccionado(''); setBusqueda(''); }}>
|
||||||
|
Cambiar
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<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
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Cama *</Label>
|
||||||
|
<Select value={camaSeleccionada} onValueChange={setCamaSeleccionada}>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Seleccionar cama" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{camas.map(c => (
|
||||||
|
<SelectItem key={c.id} value={c.id}>
|
||||||
|
{c.numero} - {getAreaName(c.areaId)} ({c.tipo})
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Columna 2: Fechas y Médico */}
|
||||||
|
<div className="space-y-6">
|
||||||
|
<Card>
|
||||||
|
<CardContent className="pt-6 space-y-4">
|
||||||
|
<h3 className="font-semibold text-gray-900 flex items-center gap-2">
|
||||||
|
<Calendar className="h-4 w-4" />
|
||||||
|
Datos de Ingreso
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Fecha Ingreso al Hospital</Label>
|
||||||
|
<Input
|
||||||
|
type="date"
|
||||||
|
value={fechaIngresoHospital}
|
||||||
|
onChange={(e) => setFechaIngresoHospital(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label>Fecha Ingreso a Clínica Médica</Label>
|
||||||
|
<Input
|
||||||
|
type="date"
|
||||||
|
value={fechaIngresoClinica}
|
||||||
|
onChange={(e) => setFechaIngresoClinica(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label>Apache / Mortalidad</Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Valor Apache o riesgo"
|
||||||
|
value={apache}
|
||||||
|
onChange={(e) => setApache(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label>Derivado de</Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Hospital o clínica de derivación"
|
||||||
|
value={derivacion}
|
||||||
|
onChange={(e) => setDerivacion(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<CardContent className="pt-6 space-y-4">
|
||||||
|
<h3 className="font-semibold text-gray-900 flex items-center gap-2">
|
||||||
|
<Stethoscope className="h-4 w-4" />
|
||||||
|
Médico Ingresante
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Médico Ingresante *</Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Nombre del médico"
|
||||||
|
value={medico}
|
||||||
|
onChange={(e) => setMedico(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Columna 3: Datos Clínicos */}
|
||||||
|
<div className="space-y-6">
|
||||||
|
<Card>
|
||||||
|
<CardContent className="pt-6 space-y-4">
|
||||||
|
<h3 className="font-semibold text-gray-900">
|
||||||
|
Datos Clínicos
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Motivo de Consulta *</Label>
|
||||||
|
<textarea
|
||||||
|
className="w-full p-2 border rounded-md text-sm min-h-[80px]"
|
||||||
|
placeholder="Motivo por el cual consulta"
|
||||||
|
value={motivoConsulta}
|
||||||
|
onChange={(e) => setMotivoConsulta(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Diagnóstico de Ingreso *</Label>
|
||||||
|
<textarea
|
||||||
|
className="w-full p-2 border rounded-md text-sm min-h-[80px]"
|
||||||
|
placeholder="Diagnóstico principal"
|
||||||
|
value={diagnosticoIngreso}
|
||||||
|
onChange={(e) => setDiagnosticoIngreso(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Enfermedad Actual *</Label>
|
||||||
|
<textarea
|
||||||
|
className="w-full p-2 border rounded-md text-sm min-h-[100px]"
|
||||||
|
placeholder="Descripción de la enfermedad actual"
|
||||||
|
value={enfermedadActual}
|
||||||
|
onChange={(e) => setEnfermedadActual(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label>Antecedentes de la Enfermedad Actual</Label>
|
||||||
|
<textarea
|
||||||
|
className="w-full p-2 border rounded-md text-sm min-h-[80px]"
|
||||||
|
placeholder="Antecedentes relevantes"
|
||||||
|
value={antecedentesEnfermedadActual}
|
||||||
|
onChange={(e) => setAntecedentesEnfermedadActual(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
+5
-2
@@ -35,7 +35,8 @@ export interface Internacion {
|
|||||||
id: string;
|
id: string;
|
||||||
pacienteId: string;
|
pacienteId: string;
|
||||||
camaId: string;
|
camaId: string;
|
||||||
fechaIngreso: string;
|
fechaIngresoHospital?: string;
|
||||||
|
fechaIngresoClinica?: string;
|
||||||
fechaEgreso?: string;
|
fechaEgreso?: string;
|
||||||
diagnosticoIngreso: string;
|
diagnosticoIngreso: string;
|
||||||
motivoConsulta?: string;
|
motivoConsulta?: string;
|
||||||
@@ -45,6 +46,8 @@ export interface Internacion {
|
|||||||
medicoIngresante: string;
|
medicoIngresante: string;
|
||||||
motivoEgreso?: 'Alta médica' | 'Alta voluntaria' | 'Derivación' | 'Fallecimiento' | 'Otro';
|
motivoEgreso?: 'Alta médica' | 'Alta voluntaria' | 'Derivación' | 'Fallecimiento' | 'Otro';
|
||||||
activa: boolean;
|
activa: boolean;
|
||||||
|
apache?: string;
|
||||||
|
derivacion?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExamenFisico {
|
export interface ExamenFisico {
|
||||||
@@ -133,4 +136,4 @@ export interface Cultivo {
|
|||||||
observaciones?: string;
|
observaciones?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Vista = 'dashboard' | 'camas' | 'pacientes' | 'internaciones' | 'evoluciones' | 'laboratorios' | 'acidobase' | 'cultivos' | 'historiaclinica';
|
export type Vista = 'dashboard' | 'camas' | 'pacientes' | 'internaciones' | 'evoluciones' | 'laboratorios' | 'acidobase' | 'cultivos' | 'historiaclinica' | 'nuevoingreso' | 'editaringreso';
|
||||||
|
|||||||
Reference in New Issue
Block a user