Agregar estudios complementarios en HC
- Agregar tabla estudiosComplementarios en SQLite y API - Agregar interface EstudioComplementario en tipos - Agregar funciones en store para gestionar estudios - Nuevo tab en HistoriaClinica con filtro por internacion/todos - Fix tema dark mode (colores black en lugar de blue)
This commit is contained in:
+24
-1
@@ -121,6 +121,15 @@ db.exec(`
|
||||
estado TEXT DEFAULT 'NAF/Pendiente',
|
||||
observaciones TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS estudiosComplementarios (
|
||||
id TEXT PRIMARY KEY,
|
||||
pacienteId TEXT NOT NULL,
|
||||
internacionId TEXT,
|
||||
fecha TEXT,
|
||||
tipo TEXT,
|
||||
resultado TEXT
|
||||
);
|
||||
`);
|
||||
|
||||
try {
|
||||
@@ -129,6 +138,12 @@ try {
|
||||
// La columna ya existe
|
||||
}
|
||||
|
||||
try {
|
||||
db.exec("ALTER TABLE laboratorios ADD COLUMN internacionId TEXT");
|
||||
} catch (e) {
|
||||
// La columna ya existe
|
||||
}
|
||||
|
||||
const app = express();
|
||||
app.use(cors());
|
||||
app.use(express.json({ limit: '50mb' }));
|
||||
@@ -177,6 +192,7 @@ app.get('/api/state', (req, res) => {
|
||||
laboratorios: queryAll('SELECT * FROM laboratorios').map(l => ({ ...l, resultados: typeof l.resultados === 'string' ? JSON.parse(l.resultados) : l.resultados })),
|
||||
acidosBase: queryAll('SELECT * FROM acidosbase'),
|
||||
cultivos: queryAll('SELECT * FROM cultivos'),
|
||||
estudiosComplementarios: queryAll('SELECT * FROM estudiosComplementarios'),
|
||||
vistaActual: 'dashboard',
|
||||
currentInternacionId: null
|
||||
};
|
||||
@@ -245,12 +261,19 @@ app.put('/api/state', (req, res) => {
|
||||
}
|
||||
|
||||
if (state.cultivos?.length) {
|
||||
const stmt = db.prepare('INSERT INTO cultivos (id, pacienteId, internacionId, fechaToma, protocolo, tipoMuestra, observaciones, estado, fechaResultado, germen, sensible, resistente) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
||||
const stmt = db.prepare('INSERT INTO cultivos (id, pacienteId, internacionId, fechaToma, protocolo, tipoMuestra, observaciones, estado, fechaResultado, germen, culpable, resistente) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
||||
for (const c of state.cultivos) {
|
||||
stmt.run(c.id, c.pacienteId, c.internacionId, c.fechaToma, c.protocolo, c.tipoMuestra, c.observaciones, c.estado, c.fechaResultado, c.germen, c.sensible, c.resistente);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.estudiosComplementarios?.length) {
|
||||
const stmt = db.prepare('INSERT INTO estudiosComplementarios (id, pacienteId, internacionId, fecha, tipo, resultado) VALUES (?, ?, ?, ?, ?, ?)');
|
||||
for (const e of state.estudiosComplementarios) {
|
||||
stmt.run(e.id, e.pacienteId, e.internacionId || null, e.fecha, e.tipo, e.resultado);
|
||||
}
|
||||
}
|
||||
|
||||
res.json({ ok: true });
|
||||
});
|
||||
|
||||
|
||||
@@ -143,6 +143,7 @@ function AppContent() {
|
||||
laboratorios={store.getLaboratoriosByPaciente(paciente.id)}
|
||||
acidosBase={store.getAcidosBaseByPaciente(paciente.id)}
|
||||
cultivos={store.getCultivosByPaciente(paciente.id)}
|
||||
estudiosComplementarios={store.estudiosComplementarios.filter(e => e.pacienteId === paciente.id)}
|
||||
onAgregarEvolucion={store.agregarEvolucion}
|
||||
onActualizarEvolucion={store.actualizarEvolucion}
|
||||
onEliminarEvolucion={store.eliminarEvolucion}
|
||||
@@ -154,6 +155,8 @@ function AppContent() {
|
||||
onAgregarCultivo={(c) => store.agregarCultivo({ ...c, internacionId: internacion.id })}
|
||||
onActualizarCultivo={store.actualizarCultivo}
|
||||
onEliminarCultivo={store.eliminarCultivo}
|
||||
onAgregarEstudioComplementario={(e) => store.agregarEstudioComplementario({ ...e, internacionId: internacion.id })}
|
||||
onEliminarEstudioComplementario={store.eliminarEstudioComplementario}
|
||||
onActualizarInternacion={store.actualizarInternacion}
|
||||
onActualizarCama={store.actualizarCama}
|
||||
onVolver={() => store.setVista('internaciones')}
|
||||
|
||||
@@ -8,6 +8,7 @@ import type {
|
||||
Laboratorio,
|
||||
AcidoBase,
|
||||
Cultivo,
|
||||
EstudioComplementario,
|
||||
Vista
|
||||
} from '@/types';
|
||||
|
||||
@@ -33,6 +34,7 @@ interface HospitalState {
|
||||
laboratorios: Laboratorio[];
|
||||
acidosBase: AcidoBase[];
|
||||
cultivos: Cultivo[];
|
||||
estudiosComplementarios: EstudioComplementario[];
|
||||
vistaActual: Vista;
|
||||
currentInternacionId?: string | null;
|
||||
}
|
||||
@@ -48,6 +50,7 @@ const defaultState = (): HospitalState => ({
|
||||
laboratorios: [],
|
||||
acidosBase: [],
|
||||
cultivos: [],
|
||||
estudiosComplementarios: [],
|
||||
vistaActual: 'dashboard',
|
||||
camas: []
|
||||
});
|
||||
@@ -312,6 +315,33 @@ const finalizarInternacion = useCallback((internacionId: string, datos: {
|
||||
}));
|
||||
}, []);
|
||||
|
||||
// Acciones de estudios complementarios
|
||||
const agregarEstudioComplementario = useCallback((estudio: Omit<EstudioComplementario, 'id'>) => {
|
||||
const nuevoEstudio: EstudioComplementario = {
|
||||
...estudio,
|
||||
id: generateUUID(),
|
||||
};
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
estudiosComplementarios: [...prev.estudiosComplementarios, nuevoEstudio],
|
||||
}));
|
||||
return nuevoEstudio.id;
|
||||
}, []);
|
||||
|
||||
const actualizarEstudioComplementario = useCallback((id: string, datos: Partial<EstudioComplementario>) => {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
estudiosComplementarios: prev.estudiosComplementarios.map(e => e.id === id ? { ...e, ...datos } : e),
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const eliminarEstudioComplementario = useCallback((id: string) => {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
estudiosComplementarios: prev.estudiosComplementarios.filter(e => e.id !== id),
|
||||
}));
|
||||
}, []);
|
||||
|
||||
// Acciones de areas
|
||||
const agregarArea = useCallback((area: Omit<Area, 'id'>) => {
|
||||
const nuevaArea: Area = { ...area, id: generateUUID() };
|
||||
@@ -431,6 +461,9 @@ const getEstadisticas = useCallback(() => {
|
||||
agregarCultivo,
|
||||
actualizarCultivo,
|
||||
eliminarCultivo,
|
||||
agregarEstudioComplementario,
|
||||
actualizarEstudioComplementario,
|
||||
eliminarEstudioComplementario,
|
||||
agregarArea,
|
||||
actualizarArea,
|
||||
eliminarArea,
|
||||
|
||||
+46
-46
@@ -5,62 +5,62 @@
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 240 10% 3.9%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 240 10% 3.9%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 240 10% 3.9%;
|
||||
--primary: 240 5.9% 10%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
--secondary: 240 4.8% 95.9%;
|
||||
--secondary-foreground: 240 5.9% 10%;
|
||||
--muted: 240 4.8% 95.9%;
|
||||
--muted-foreground: 240 3.8% 46.1%;
|
||||
--accent: 240 4.8% 95.9%;
|
||||
--accent-foreground: 240 5.9% 10%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
--primary: 222.2 47.4% 11.2%;
|
||||
--primary-foreground: 210 40% 98%;
|
||||
--secondary: 210 40% 96.1%;
|
||||
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||
--muted: 210 40% 96.1%;
|
||||
--muted-foreground: 215.4 16.3% 46.9%;
|
||||
--accent: 210 40% 96.1%;
|
||||
--accent-foreground: 222.2 47.4% 11.2%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 240 5.9% 90%;
|
||||
--input: 240 5.9% 90%;
|
||||
--ring: 240 5.9% 10%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
--border: 214.3 31.8% 91.4%;
|
||||
--input: 214.3 31.8% 91.4%;
|
||||
--ring: 222.2 84% 4.9%;
|
||||
--radius: 0.625rem;
|
||||
--sidebar-background: 0 0% 98%;
|
||||
--sidebar-foreground: 240 5.3% 26.1%;
|
||||
--sidebar-primary: 240 5.9% 10%;
|
||||
--sidebar-primary-foreground: 0 0% 98%;
|
||||
--sidebar-accent: 240 4.8% 95.9%;
|
||||
--sidebar-accent-foreground: 240 5.9% 10%;
|
||||
--sidebar-border: 220 13% 91%;
|
||||
--sidebar-foreground: 222.2 84% 4.9%;
|
||||
--sidebar-primary: 222.2 47.4% 11.2%;
|
||||
--sidebar-primary-foreground: 210 40% 98%;
|
||||
--sidebar-accent: 210 40% 96.1%;
|
||||
--sidebar-accent-foreground: 222.2 47.4% 11.2%;
|
||||
--sidebar-border: 214.3 31.8% 91.4%;
|
||||
--sidebar-ring: 217.2 91.2% 59.8%;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 240 10% 3.9%;
|
||||
--foreground: 0 0% 98%;
|
||||
--card: 240 10% 3.9%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
--popover: 240 10% 3.9%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
--primary: 0 0% 98%;
|
||||
--primary-foreground: 240 5.9% 10%;
|
||||
--secondary: 240 3.7% 15.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--muted: 240 3.7% 15.9%;
|
||||
--muted-foreground: 240 5% 64.9%;
|
||||
--accent: 240 3.7% 15.9%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
--background: 222.2 84% 4.9%;
|
||||
--foreground: 210 40% 98%;
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
--popover: 222.2 84% 4.9%;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
--primary: 210 40% 98%;
|
||||
--primary-foreground: 222.2 47.4% 11.2%;
|
||||
--secondary: 217.2 32.6% 17.5%;
|
||||
--secondary-foreground: 210 40% 98%;
|
||||
--muted: 217.2 32.6% 17.5%;
|
||||
--muted-foreground: 215 20.2% 65.1%;
|
||||
--accent: 217.2 32.6% 17.5%;
|
||||
--accent-foreground: 210 40% 98%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 240 3.7% 15.9%;
|
||||
--input: 240 3.7% 15.9%;
|
||||
--ring: 240 4.9% 83.9%;
|
||||
--sidebar-background: 240 5.9% 10%;
|
||||
--sidebar-foreground: 240 4.8% 95.9%;
|
||||
--sidebar-primary: 224.3 76.3% 48%;
|
||||
--sidebar-primary-foreground: 0 0% 100%;
|
||||
--sidebar-accent: 240 3.7% 15.9%;
|
||||
--sidebar-accent-foreground: 240 4.8% 95.9%;
|
||||
--sidebar-border: 240 3.7% 15.9%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
--border: 217.2 32.6% 17.5%;
|
||||
--input: 217.2 32.6% 17.5%;
|
||||
--ring: 212.7 26.8% 83.9%;
|
||||
--sidebar-background: 222.2 84% 4.9%;
|
||||
--sidebar-foreground: 210 40% 98%;
|
||||
--sidebar-primary: 210 40% 98%;
|
||||
--sidebar-primary-foreground: 222.2 47.4% 11.2%;
|
||||
--sidebar-accent: 217.2 32.6% 17.5%;
|
||||
--sidebar-accent-foreground: 210 40% 98%;
|
||||
--sidebar-border: 217.2 32.6% 17.5%;
|
||||
--sidebar-ring: 217.2 91.2% 59.8%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
|
||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
||||
import type { Laboratorio, AcidoBase, Cultivo, Paciente, ResultadoLaboratorio, Internacion, Evolucion, Cama } from '@/types';
|
||||
import type { Laboratorio, AcidoBase, Cultivo, Paciente, ResultadoLaboratorio, Internacion, Evolucion, Cama, EstudioComplementario } from '@/types';
|
||||
import { formatDateDDMMYYYY } from '@/lib/utils';
|
||||
|
||||
interface HistoriaClinicaProps {
|
||||
@@ -51,6 +51,7 @@ interface HistoriaClinicaProps {
|
||||
laboratorios: Laboratorio[];
|
||||
acidosBase: AcidoBase[];
|
||||
cultivos: Cultivo[];
|
||||
estudiosComplementarios: EstudioComplementario[];
|
||||
onAgregarEvolucion: (evolucion: Omit<Evolucion, 'id'>) => void;
|
||||
onActualizarEvolucion: (id: string, datos: Partial<Evolucion>) => void;
|
||||
onEliminarEvolucion: (id: string) => void;
|
||||
@@ -62,6 +63,8 @@ interface HistoriaClinicaProps {
|
||||
onAgregarCultivo: (cultivo: Omit<Cultivo, 'id'>) => void;
|
||||
onActualizarCultivo: (id: string, datos: Partial<Cultivo>) => void;
|
||||
onEliminarCultivo: (id: string) => void;
|
||||
onAgregarEstudioComplementario: (estudio: Omit<EstudioComplementario, 'id'>) => void;
|
||||
onEliminarEstudioComplementario: (id: string) => void;
|
||||
onActualizarInternacion: (id: string, datos: Partial<Internacion>) => void;
|
||||
onActualizarCama: (id: string, datos: Partial<Cama>) => void;
|
||||
onVolver: () => void;
|
||||
@@ -148,6 +151,7 @@ export function HistoriaClinica({
|
||||
laboratorios,
|
||||
acidosBase,
|
||||
cultivos,
|
||||
estudiosComplementarios,
|
||||
onAgregarEvolucion,
|
||||
onActualizarEvolucion,
|
||||
onEliminarEvolucion,
|
||||
@@ -159,6 +163,8 @@ export function HistoriaClinica({
|
||||
onAgregarCultivo,
|
||||
onActualizarCultivo,
|
||||
onEliminarCultivo,
|
||||
onAgregarEstudioComplementario,
|
||||
onEliminarEstudioComplementario,
|
||||
onActualizarInternacion,
|
||||
onActualizarCama,
|
||||
onVolver,
|
||||
@@ -509,6 +515,12 @@ export function HistoriaClinica({
|
||||
<span className="sm:hidden">Cult</span>
|
||||
({cultivos.length})
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="estudios" className="flex-shrink-0 flex items-center gap-1 text-xs sm:text-sm">
|
||||
<ClipboardList className="h-3 w-3 sm:h-4 sm:w-4" />
|
||||
<span className="hidden sm:inline">Estudios</span>
|
||||
<span className="sm:hidden">Est</span>
|
||||
({estudiosComplementarios.length})
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="laboratorios" className="mt-4">
|
||||
@@ -526,6 +538,16 @@ export function HistoriaClinica({
|
||||
<TabsContent value="cultivos" className="mt-4">
|
||||
<SeccionCultivos cults={cultivos} patient={paciente} add={onAgregarCultivo} update={onActualizarCultivo} del={onEliminarCultivo} />
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="estudios" className="mt-4">
|
||||
<SeccionEstudiosComplementarios
|
||||
estudios={estudiosComplementarios}
|
||||
internacionId={internacion.id}
|
||||
pacienteId={paciente.id}
|
||||
add={onAgregarEstudioComplementario}
|
||||
del={onEliminarEstudioComplementario}
|
||||
/>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
@@ -1011,10 +1033,13 @@ if (!esUnidadSiguiente) {
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{labs.length === 0 ? <div className="text-center py-8 text-gray-400"><FlaskConical className="h-12 w-12 mx-auto mb-2 opacity-50" /><p>No hay laboratorios</p></div> :
|
||||
<div className="overflow-x-auto min-w-full">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
{labs.length === 0 ? (
|
||||
<div className="text-center py-8 text-gray-400"><FlaskConical className="h-12 w-12 mx-auto mb-2 opacity-50" /><p>No hay laboratorios</p></div>
|
||||
) : (
|
||||
<div className="relative w-full overflow-auto grid grid-cols-1">
|
||||
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Fecha</TableHead>
|
||||
<TableHead>Hto</TableHead>
|
||||
@@ -1085,8 +1110,9 @@ if (!esUnidadSiguiente) {
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1658,3 +1684,129 @@ const resetRes = () => {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SeccionEstudiosComplementarios({ estudios, internacionId, pacienteId, add, del }: {
|
||||
estudios: EstudioComplementario[];
|
||||
internacionId: string;
|
||||
pacienteId: string;
|
||||
add: (e: Omit<EstudioComplementario, 'id'>) => void;
|
||||
del: (id: string) => void;
|
||||
}) {
|
||||
const [dialog, setDialog] = useState(false);
|
||||
const [filtro, setFiltro] = useState<'todos' | 'internacion'>('internacion');
|
||||
const [fecha, setFecha] = useState(new Date().toISOString().split('T')[0]);
|
||||
const [tipo, setTipo] = useState('');
|
||||
const [resultado, setResultado] = useState('');
|
||||
|
||||
const estudiosFiltrados = filtro === 'internacion'
|
||||
? estudios.filter(e => e.internacionId === internacionId)
|
||||
: estudios;
|
||||
|
||||
const reset = () => {
|
||||
setFecha(new Date().toISOString().split('T')[0]);
|
||||
setTipo('');
|
||||
setResultado('');
|
||||
};
|
||||
|
||||
const handleGuardar = () => {
|
||||
if (!tipo || !resultado) return;
|
||||
add({
|
||||
pacienteId,
|
||||
internacionId,
|
||||
fecha,
|
||||
tipo,
|
||||
resultado,
|
||||
});
|
||||
setDialog(false);
|
||||
reset();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
|
||||
<div className="flex gap-2">
|
||||
<Button variant="outline" onClick={() => { reset(); setDialog(true); }}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Nuevo Estudio
|
||||
</Button>
|
||||
</div>
|
||||
<Select value={filtro} onValueChange={(v: 'todos' | 'internacion') => setFiltro(v)}>
|
||||
<SelectTrigger className="w-[180px]">
|
||||
<SelectValue placeholder="Filtrar" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="internacion">Solo esta internación</SelectItem>
|
||||
<SelectItem value="todos">Todos los estudios</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<Dialog open={dialog} onOpenChange={setDialog}>
|
||||
<DialogContent className="sm:max-w-lg">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Nuevo Estudio Complementario</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Label>Fecha</Label>
|
||||
<Input type="date" value={fecha} onChange={e => setFecha(e.target.value)} />
|
||||
</div>
|
||||
<div>
|
||||
<Label>Tipo de Estudio</Label>
|
||||
<Input
|
||||
value={tipo}
|
||||
onChange={e => setTipo(e.target.value)}
|
||||
placeholder="Ej: Radiografía de tórax, ECG, Tomografía, etc."
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Resultado</Label>
|
||||
<textarea
|
||||
className="w-full p-2 border rounded-md text-sm min-h-[100px]"
|
||||
value={resultado}
|
||||
onChange={e => setResultado(e.target.value)}
|
||||
placeholder="Ingrese el resultado del estudio..."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-end gap-2 mt-4">
|
||||
<Button variant="outline" onClick={() => setDialog(false)}>Cancelar</Button>
|
||||
<Button onClick={handleGuardar} disabled={!tipo || !resultado}>
|
||||
<Save className="h-4 w-4 mr-2" />
|
||||
Guardar
|
||||
</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{estudiosFiltrados.length === 0 ? (
|
||||
<div className="text-center py-8 text-gray-400">
|
||||
<ClipboardList className="h-12 w-12 mx-auto mb-2 opacity-50" />
|
||||
<p>No hay estudios complementarios</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-3">
|
||||
{estudiosFiltrados.sort((a, b) => new Date(b.fecha).getTime() - new Date(a.fecha).getTime()).map(e => (
|
||||
<Card key={e.id} className="hover:shadow-md transition-shadow">
|
||||
<CardContent className="p-4">
|
||||
<div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3">
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Calendar className="h-4 w-4 text-gray-500" />
|
||||
<span className="text-sm font-medium">{e.fecha}</span>
|
||||
</div>
|
||||
<h4 className="font-semibold text-gray-900 dark:text-white">{e.tipo}</h4>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300 mt-1 whitespace-pre-wrap">{e.resultado}</p>
|
||||
</div>
|
||||
<Button size="sm" variant="outline" className="text-red-600 self-start" onClick={() => del(e.id)}>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -141,4 +141,13 @@ export interface Cultivo {
|
||||
observaciones?: string;
|
||||
}
|
||||
|
||||
export interface EstudioComplementario {
|
||||
id: string;
|
||||
pacienteId: string;
|
||||
internacionId?: string;
|
||||
fecha: string;
|
||||
tipo: string;
|
||||
resultado: string;
|
||||
}
|
||||
|
||||
export type Vista = 'dashboard' | 'camas' | 'pacientes' | 'internaciones' | 'evoluciones' | 'laboratorios' | 'acidobase' | 'cultivos' | 'historiaclinica' | 'nuevoingreso' | 'editaringreso';
|
||||
|
||||
Reference in New Issue
Block a user