Agregar parser de Estado Ácido Base en importar laboratorio
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user