Agregar parser de Estado Ácido Base en importar laboratorio

This commit is contained in:
2026-04-16 11:17:49 -03:00
parent 35d0e4eb41
commit d3abb1c3fe
+99 -8
View File
@@ -2,7 +2,6 @@ import { useState } from 'react';
import { PDFDocument } from 'pdf-lib'; import { PDFDocument } from 'pdf-lib';
import { import {
FlaskConical, FlaskConical,
Activity,
Microscope, Microscope,
Plus, Plus,
Calendar, Calendar,
@@ -27,7 +26,8 @@ import {
Edit, Edit,
ClipboardList, ClipboardList,
TrendingUp, TrendingUp,
TypeOutline TypeOutline,
Activity
} from 'lucide-react'; } from 'lucide-react';
import { Card, CardContent } from '@/components/ui/card'; import { Card, CardContent } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
@@ -59,6 +59,7 @@ interface HistoriaClinicaProps {
onAgregarLaboratorio: (laboratorios: Omit<Laboratorio, 'id'>) => void; onAgregarLaboratorio: (laboratorios: Omit<Laboratorio, 'id'>) => void;
onActualizarLaboratorio: (id: string, datos: Partial<Laboratorio>) => void; onActualizarLaboratorio: (id: string, datos: Partial<Laboratorio>) => void;
onEliminarLaboratorio: (id: string) => void; onEliminarLaboratorio: (id: string) => void;
onAgregarLaboratorioConAcidoBase?: (l: Omit<Laboratorio, 'id'>, a?: Omit<AcidoBase, 'id'>) => void;
onAgregarAcidoBase: (acidoBase: Omit<AcidoBase, 'id'>) => void; onAgregarAcidoBase: (acidoBase: Omit<AcidoBase, 'id'>) => void;
onActualizarAcidoBase: (id: string, datos: Partial<AcidoBase>) => void; onActualizarAcidoBase: (id: string, datos: Partial<AcidoBase>) => void;
onEliminarAcidoBase: (id: string) => void; onEliminarAcidoBase: (id: string) => void;
@@ -527,7 +528,7 @@ export function HistoriaClinica({
</TabsList> </TabsList>
<TabsContent value="laboratorios" className="mt-4"> <TabsContent value="laboratorios" className="mt-4">
<SeccionLaboratorios lab={laboratorios} patientId={paciente.id} add={onAgregarLaboratorio} update={onActualizarLaboratorio} del={onEliminarLaboratorio} /> <SeccionLaboratorios lab={laboratorios} patientId={paciente.id} add={onAgregarLaboratorio} update={onActualizarLaboratorio} del={onEliminarLaboratorio} addAcidoBase={onAgregarAcidoBase} />
</TabsContent> </TabsContent>
<TabsContent value="evoluciones" className="mt-4"> <TabsContent value="evoluciones" className="mt-4">
@@ -556,12 +557,13 @@ export function HistoriaClinica({
); );
} }
function SeccionLaboratorios({ lab, patientId, add, update, del }: { function SeccionLaboratorios({ lab, patientId, add, update, del, addAcidoBase }: {
lab: Laboratorio[]; lab: Laboratorio[];
patientId: string; patientId: string;
add: (l: Omit<Laboratorio, 'id'>) => void; add: (l: Omit<Laboratorio, 'id'>) => void;
update: (id: string, data: Partial<Laboratorio>) => void; update: (id: string, data: Partial<Laboratorio>) => void;
del: (id: string) => void; del: (id: string) => void;
addAcidoBase?: (a: Omit<AcidoBase, 'id'>) => void;
}) { }) {
const [dialog, setDialog] = useState(false); const [dialog, setDialog] = useState(false);
const [obsDialog, setObsDialog] = useState(false); const [obsDialog, setObsDialog] = useState(false);
@@ -595,6 +597,7 @@ function SeccionLaboratorios({ lab, patientId, add, update, del }: {
const [importTexto, setImportTexto] = useState(''); const [importTexto, setImportTexto] = useState('');
const [importResultados, setImportResultados] = useState<ResultadoLaboratorio[]>([]); const [importResultados, setImportResultados] = useState<ResultadoLaboratorio[]>([]);
const [importObservaciones, setImportObservaciones] = useState(''); const [importObservaciones, setImportObservaciones] = useState('');
const [importAcidoBase, setImportAcidoBase] = useState<Omit<AcidoBase, 'id'> | null>(null);
const parametrosLaboratorio = [ const parametrosLaboratorio = [
'Hematocrito', 'Hemoglobina', 'Leucocitos', 'Plaquetas', 'Hematocrito', 'Hemoglobina', 'Leucocitos', 'Plaquetas',
@@ -763,14 +766,82 @@ if (!esUnidadSiguiente) {
return { resultados, observaciones: observacionesExtra.join('\n') }; return { resultados, observaciones: observacionesExtra.join('\n') };
}; };
const parseAcidoBaseTexto = (texto: string): Omit<AcidoBase, 'id'> | null => {
const lineas = texto.split('\n');
let ph: number | undefined;
let pco2: number | undefined;
let po2: number | undefined;
let hco3: number | undefined;
let be: number | undefined;
let sato2: number | undefined;
let lactato: number | undefined;
let fio2: number | undefined;
let fecha = importFecha;
for (const linea of lineas) {
const lineaLower = linea.toLowerCase().trim();
const valorMatch = linea.replace(/,/g, '.').match(/(\d+\.?\d*)/);
if (lineaLower.includes('ph') && !lineaLower.includes('pco2') && !lineaLower.includes('pco') && valorMatch) {
ph = parseFloat(valorMatch[1]);
} else if ((lineaLower.includes('pco2') || lineaLower.includes('pco 2') || lineaLower.includes('pco₂')) && valorMatch) {
pco2 = parseFloat(valorMatch[1]);
} else if (lineaLower.includes('po2') || lineaLower.includes('po 2') || lineaLower.includes('po₂')) {
if (valorMatch) po2 = parseFloat(valorMatch[1]);
} else if (lineaLower.includes('hco3') && valorMatch) {
hco3 = parseFloat(valorMatch[1]);
} else if (lineaLower.includes('exceso de base') || lineaLower.includes('exceso de bases') || lineaLower.includes('base excess') || lineaLower.includes('be ') || lineaLower.includes('be,')) {
if (valorMatch) be = parseFloat(valorMatch[1]);
} else if (lineaLower.includes('saturación de oxígeno') || lineaLower.includes('saturación de oxigeno') || lineaLower.includes('sato2') || lineaLower.includes('sat o2')) {
if (valorMatch) sato2 = parseFloat(valorMatch[1]);
} else if (lineaLower.includes('lactato') && valorMatch) {
lactato = parseFloat(valorMatch[1]);
} else if (lineaLower.includes('fio2') || lineaLower.includes('fi o2') || lineaLower.includes('fi o₂')) {
if (valorMatch) fio2 = parseFloat(valorMatch[1]);
} else if (lineaLower.match(/\d{4}-\d{2}-\d{2}/)) {
const fechaMatch = lineaLower.match(/(\d{4}-\d{2}-\d{2})/);
if (fechaMatch) fecha = fechaMatch[1];
}
}
if (ph !== undefined) {
const hora = new Date().toTimeString().slice(0, 5);
return {
pacienteId: patientId,
fecha,
hora,
ph,
pco2: pco2 || 40,
po2: po2 || 85,
hco3: hco3 || 24,
be: be || 0,
sato2: sato2 || 97,
lactato,
fio2,
interpretacion: ''
};
}
return null;
};
const handleProcesarTexto = () => { const handleProcesarTexto = () => {
const { resultados, observaciones } = parseLaboratorioTexto(importTexto); const { resultados, observaciones } = parseLaboratorioTexto(importTexto);
const acidoBase = parseAcidoBaseTexto(importTexto);
setImportResultados(resultados); setImportResultados(resultados);
setImportObservaciones(observaciones); setImportObservaciones(observaciones);
setImportAcidoBase(acidoBase);
}; };
const handleImportarLaboratorio = () => { const handleImportarLaboratorio = () => {
if (importResultados.length === 0 && !importObservaciones) return; if (!addAcidoBase) return;
if (importResultados.length === 0 && !importObservaciones && !importAcidoBase) return;
if (importAcidoBase) {
addAcidoBase(importAcidoBase);
}
add({ add({
pacienteId: patientId, pacienteId: patientId,
@@ -783,6 +854,7 @@ if (!esUnidadSiguiente) {
setImportTexto(''); setImportTexto('');
setImportResultados([]); setImportResultados([]);
setImportObservaciones(''); setImportObservaciones('');
setImportAcidoBase(null);
setImportFecha(new Date().toISOString().split('T')[0]); setImportFecha(new Date().toISOString().split('T')[0]);
}; };
@@ -1013,6 +1085,25 @@ if (!esUnidadSiguiente) {
</div> </div>
)} )}
{importAcidoBase && (
<div className="border rounded-md p-3 bg-green-50">
<p className="text-sm font-medium mb-2 flex items-center gap-2">
<Activity className="h-4 w-4" />
Estado Ácido Base detectado:
</p>
<div className="grid grid-cols-4 gap-2 text-sm">
<div><span className="text-gray-500">pH:</span> <span className="font-medium">{importAcidoBase.ph}</span></div>
<div><span className="text-gray-500">pCO2:</span> <span className="font-medium">{importAcidoBase.pco2}</span></div>
<div><span className="text-gray-500">pO2:</span> <span className="font-medium">{importAcidoBase.po2}</span></div>
<div><span className="text-gray-500">HCO3:</span> <span className="font-medium">{importAcidoBase.hco3}</span></div>
<div><span className="text-gray-500">BE:</span> <span className="font-medium">{importAcidoBase.be}</span></div>
<div><span className="text-gray-500">SatO2:</span> <span className="font-medium">{importAcidoBase.sato2}%</span></div>
{importAcidoBase.lactato && <div><span className="text-gray-500">Lactato:</span> <span className="font-medium">{importAcidoBase.lactato}</span></div>}
{importAcidoBase.fio2 && <div><span className="text-gray-500">FiO2:</span> <span className="font-medium">{importAcidoBase.fio2}</span></div>}
</div>
</div>
)}
{importObservaciones && ( {importObservaciones && (
<div className="border rounded-md p-3 bg-muted/50"> <div className="border rounded-md p-3 bg-muted/50">
<p className="text-sm font-medium mb-1">Valores adicionales en observaciones:</p> <p className="text-sm font-medium mb-1">Valores adicionales en observaciones:</p>
@@ -1020,7 +1111,7 @@ if (!esUnidadSiguiente) {
</div> </div>
)} )}
{importResultados.length === 0 && !importObservaciones && importTexto && ( {importResultados.length === 0 && !importObservaciones && !importAcidoBase && importTexto && (
<div className="text-center py-4 text-gray-500"> <div className="text-center py-4 text-gray-500">
<p>No se detectaron parámetros. Verifique que el texto contenga los nombres correctos.</p> <p>No se detectaron parámetros. Verifique que el texto contenga los nombres correctos.</p>
</div> </div>
@@ -1028,9 +1119,9 @@ if (!esUnidadSiguiente) {
</div> </div>
<div className="flex justify-end gap-2 mt-4"> <div className="flex justify-end gap-2 mt-4">
<Button variant="outline" onClick={() => setImportDialog(false)}>Cancelar</Button> <Button variant="outline" onClick={() => setImportDialog(false)}>Cancelar</Button>
<Button onClick={handleImportarLaboratorio} disabled={importResultados.length === 0 && !importObservaciones}> <Button onClick={handleImportarLaboratorio} disabled={importResultados.length === 0 && !importObservaciones && !importAcidoBase}>
<Save className="h-4 w-4 mr-2" /> <Save className="h-4 w-4 mr-2" />
Guardar Laboratorio {(importAcidoBase ? 'Guardar Gasometría' : 'Guardar Laboratorio')}
</Button> </Button>
</div> </div>
</DialogContent> </DialogContent>