FarmaUrgen / index.html
aarnal80's picture
Update index.html
eac1c27 verified
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Calculadora de Urgencias Médicas</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
<style>
body {
background-color: #f8fafc;
font-family: "Montserrat", sans-serif;
}
/* Estilos para las pestañas */
.tab-btn {
transition: background-color 0.2s, color 0.2s;
}
.tab-btn.active {
background-color: #0d9488; /* teal-600 */
color: white;
border-color: #0d9488;
}
.input-field {
width: 100%;
padding: 0.5rem 0.75rem;
border-radius: 0.375rem;
border: 1px solid #d1d5db;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
font-size: 0.875rem;
line-height: 1.25rem;
}
.input-field:focus {
outline: none;
border-color: #3b82f6;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25);
}
.result-card {
background-color: white;
border: 1px solid #e5e7eb;
border-radius: 0.5rem;
padding: 1.5rem;
margin-top: 1rem;
min-height: 300px;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.drug-calculation span {
font-weight: 600;
color: #c026d3; /* fuchsia-700 */
}
</style>
</head>
<body class="min-h-screen bg-gray-50 p-4 sm:p-6">
<div class="mx-auto max-w-3xl p-6 my-8 bg-white rounded-xl shadow-lg">
<div class="text-center mb-6">
<h1 class="text-2xl font-bold text-teal-700 flex items-center justify-center">
<i class="fas fa-calculator mr-3"></i>Calculadora de Urgencias
</h1>
<p class="text-gray-600 mt-2 text-sm leading-relaxed">
Herramienta rápida para Secuencia de Intubación y Bombas de Perfusión.
</p>
</div>
<div class="bg-red-50 text-red-800 p-3 rounded-lg text-xs text-center mb-6 border border-red-200">
<i class="fas fa-exclamation-triangle mr-2"></i>
<strong>Atención:</strong> Esta es una herramienta de ayuda y no reemplaza el juicio clínico. Verifique siempre los cálculos.
</div>
<div class="flex border-b border-gray-200 mb-6">
<button id="tab-sri" class="tab-btn active flex-1 py-2 px-4 text-sm font-semibold text-gray-600 border-b-2 border-transparent hover:bg-teal-50">
<i class="fas fa-lungs mr-2"></i>Secuencia Rápida Intubación
</button>
<button id="tab-bombas" class="tab-btn flex-1 py-2 px-4 text-sm font-semibold text-gray-600 border-b-2 border-transparent hover:bg-teal-50">
<i class="fas fa-syringe mr-2"></i>Bombas de Perfusión
</button>
</div>
<div class="bg-teal-50 p-4 rounded-lg border border-teal-100 shadow-inner space-y-4 mb-6">
<div>
<label for="patientWeight" class="block text-sm font-medium text-gray-700 mb-2">
<i class="fas fa-weight-scale mr-2"></i>Peso del paciente (kg)
</label>
<input type="number" id="patientWeight" class="input-field" placeholder="Ej: 70" value="70">
</div>
</div>
<main>
<div id="content-sri" class="result-card">
</div>
<div id="content-bombas" class="hidden">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<label for="drugSelector" class="block text-xs font-medium text-gray-600 mb-1">Fármaco</label>
<select id="drugSelector" class="input-field appearance-none pr-8 bg-no-repeat" style="background-image: url(&quot;data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e&quot;); background-position: right 0.5rem center; background-size: 1.5em 1.5em;">
<option value="noradrenalina">Noradrenalina</option>
<option value="dopamina">Dopamina</option>
<option value="dobutamina">Dobutamina</option>
</select>
</div>
<div>
<label for="doseInput" class="block text-xs font-medium text-gray-600 mb-1">Dosis deseada (<span id="doseUnit">mcg/kg/min</span>)</label>
<input type="number" id="doseInput" class="input-field" value="0.1" step="0.01">
</div>
</div>
<div id="pump-results" class="result-card">
</div>
</div>
</main>
</div>
<script type="module">
// --- DATOS MÉDICOS (ACTUALIZADOS) ---
const rsiDrugs = {
premedicacion: [
{ name: 'Fentanilo', dose: '1-3 mcg/kg', presentation: { value: 50, unit: 'mcg/ml' } },
{ name: 'Lidocaína', dose: '1.5 mg/kg', presentation: { value: 20, unit: 'mg/ml' } }
],
induccion: [
{ name: 'Propofol', dose: '1-2 mg/kg', presentation: { value: 10, unit: 'mg/ml' } },
{ name: 'Etomidato', dose: '0.2-0.3 mg/kg', presentation: { value: 2, unit: 'mg/ml' } },
{ name: 'Ketamina', dose: '1-2 mg/kg', presentation: { value: 50, unit: 'mg/ml' } },
{ name: 'Midazolam', dose: '0.1-0.3 mg/kg', presentation: { value: 5, unit: 'mg/ml' } }
],
paralisis: [
{ name: 'Rocuronio', dose: '1-1.2 mg/kg', presentation: { value: 10, unit: 'mg/ml' } },
{ name: 'Succinilcolina', dose: '1-1.5 mg/kg', presentation: { value: 50, unit: 'mg/ml' } }
]
};
const perfusionDrugs = {
noradrenalina: {
name: 'Noradrenalina',
preparation: 'Añadir <strong>10 mg</strong> (2 ampollas de 5mg/10ml) en <strong>250 ml</strong> de Suero Glucosado 5%.',
totalDrugMg: 10,
totalVolumeMl: 250,
doseUnit: 'mcg/kg/min',
defaultDose: 0.1
},
dopamina: {
name: 'Dopamina',
preparation: 'Añadir <strong>200 mg</strong> (1 ampolla de 200mg/5ml) en <strong>250 ml</strong> de Suero Glucosado 5%.',
totalDrugMg: 200,
totalVolumeMl: 250,
doseUnit: 'mcg/kg/min',
defaultDose: 5
},
dobutamina: {
name: 'Dobutamina',
preparation: 'Añadir <strong>250 mg</strong> (1 vial de 250mg/20ml) en <strong>250 ml</strong> de Suero Glucosado 5%.',
totalDrugMg: 250,
totalVolumeMl: 250,
doseUnit: 'mcg/kg/min',
defaultDose: 5
}
};
// --- REFERENCIAS AL DOM ---
const patientWeightInput = document.getElementById('patientWeight');
const tabSri = document.getElementById('tab-sri');
const tabBombas = document.getElementById('tab-bombas');
const contentSri = document.getElementById('content-sri');
const contentBombas = document.getElementById('content-bombas');
const drugSelector = document.getElementById('drugSelector');
const doseInput = document.getElementById('doseInput');
const doseUnitSpan = document.getElementById('doseUnit');
const pumpResultsDisplay = document.getElementById('pump-results');
// --- LÓGICA DE LA APP ---
function calculateDose(weight, doseString, presentation) {
const doseValues = doseString.match(/[\d.]+/g).map(Number);
const unit = doseString.includes('mcg') ? 'mcg' : 'mg';
let doseRange = [];
if (doseValues.length === 1) {
doseRange.push(weight * doseValues[0]);
} else {
doseRange.push(weight * doseValues[0]);
doseRange.push(weight * doseValues[1]);
}
let doseMg = doseRange.map(d => (unit === 'mcg' ? d / 1000 : d));
let volumeMl = doseMg.map(d => d / presentation.value * (presentation.unit.includes('mcg') ? 1000 : 1));
const format = (arr) => arr.length === 1 ? arr[0].toFixed(1) : `${arr[0].toFixed(1)} - ${arr[1].toFixed(1)}`;
return `Dosis: <span>${format(doseRange)} ${unit}</span> / Total: <span>${format(volumeMl)} ml</span>`;
}
function updateSRI() {
const weight = parseFloat(patientWeightInput.value) || 0;
if (weight <= 0) {
contentSri.innerHTML = `<div class="text-center py-10 text-gray-400"><i class="fas fa-notes-medical text-4xl mb-3"></i><p>Introduzca un peso válido.</p></div>`;
return;
}
let html = `
<h2 class="text-lg font-bold text-teal-700 mb-4"><i class="fas fa-list-ol mr-2"></i>Las 7 P's de la Intubación</h2>
<div class="space-y-4 text-sm">
<p><strong>1. Preparación:</strong> Monitorización, material listo (tubos, laringo, aspirador), fármacos cargados.</p>
<p><strong>2. Preoxigenación:</strong> FiO₂ 100% durante 3-5 minutos con mascarilla reservorio o VMNI.</p>
<div>
<p><strong>3. Premedicación:</strong> (Atenuar respuesta simpática)</p>
<ul class="list-disc ml-6 mt-1 space-y-1">
${rsiDrugs.premedicacion.map(drug => `<li class="drug-calculation"><strong>${drug.name}</strong> (${drug.presentation.value} ${drug.presentation.unit}): ${calculateDose(weight, drug.dose, drug.presentation)}</li>`).join('')}
</ul>
</div>
<div>
<p><strong>4. Parálisis con Inducción:</strong> Administrar inductor seguido inmediatamente del paralizante.</p>
<p class="text-xs text-gray-500 mt-1"><u>Inductores:</u></p>
<ul class="list-disc ml-6 mt-1 space-y-1">
${rsiDrugs.induccion.map(drug => `<li class="drug-calculation"><strong>${drug.name}</strong> (${drug.presentation.value} ${drug.presentation.unit}): ${calculateDose(weight, drug.dose, drug.presentation)}</li>`).join('')}
</ul>
<p class="text-xs text-gray-500 mt-2"><u>Paralizantes:</u></p>
<ul class="list-disc ml-6 mt-1 space-y-1">
${rsiDrugs.paralisis.map(drug => `<li class="drug-calculation"><strong>${drug.name}</strong> (${drug.presentation.value} ${drug.presentation.unit}): ${calculateDose(weight, drug.dose, drug.presentation)}</li>`).join('')}
</ul>
</div>
<p><strong>5. Posicionamiento:</strong> Alineación de ejes oral, faríngeo y laríngeo (posición de olfateo).</p>
<p><strong>6. Progresión del tubo:</strong> Laringoscopia, visualización de cuerdas vocales e inserción del tubo.</p>
<p><strong>7. Post-intubación:</strong> Comprobación (capnografía, auscultación), fijación del tubo, conexión a ventilador e inicio de sedoanalgesia.</p>
</div>
`;
contentSri.innerHTML = html;
}
function updatePumps() {
const weight = parseFloat(patientWeightInput.value) || 0;
const selectedDrugKey = drugSelector.value;
const desiredDose = parseFloat(doseInput.value) || 0;
const drug = perfusionDrugs[selectedDrugKey];
if (weight <= 0 || !drug) {
pumpResultsDisplay.innerHTML = `<div class="text-center py-10 text-gray-400"><i class="fas fa-notes-medical text-4xl mb-3"></i><p>Introduzca un peso y dosis válidos.</p></div>`;
return;
}
const totalDrugMcg = drug.totalDrugMg * 1000;
const concentrationMcgMl = totalDrugMcg / drug.totalVolumeMl;
const doseMcgMin = desiredDose * weight;
const doseMcgHour = doseMcgMin * 60;
const infusionRateMlH = doseMcgHour / concentrationMcgMl;
let html = `
<h3 class="text-base font-bold mb-3 text-teal-700"><i class="fas fa-prescription-bottle-alt mr-2"></i>Cálculo para ${drug.name}</h3>
<div class="space-y-3 text-sm">
<div>
<p class="font-semibold text-gray-600">1. Preparación:</p>
<p class="pl-4">${drug.preparation}</p>
</div>
<div>
<p class="font-semibold text-gray-600">2. Concentración:</p>
<p class="pl-4">La concentración de la mezcla es <strong>${concentrationMcgMl.toFixed(2)} mcg/ml</strong>.</p>
</div>
<div class="mt-4 p-4 bg-teal-50 rounded-lg border border-teal-200">
<p class="font-semibold text-gray-800 text-base">3. Velocidad de Perfusión:</p>
<p class="text-center text-2xl font-bold text-fuchsia-700 my-2">${infusionRateMlH.toFixed(1)} ml/h</p>
<p class="text-xs text-center text-gray-500">Para una dosis de ${desiredDose} ${drug.doseUnit} en un paciente de ${weight} kg.</p>
</div>
</div>
`;
pumpResultsDisplay.innerHTML = html;
doseUnitSpan.textContent = drug.doseUnit;
}
function handleTabClick(activeTab) {
if (activeTab === 'sri') {
tabSri.classList.add('active');
tabBombas.classList.remove('active');
contentSri.classList.remove('hidden');
contentBombas.classList.add('hidden');
} else {
tabBombas.classList.add('active');
tabSri.classList.remove('active');
contentBombas.classList.remove('hidden');
contentSri.classList.add('hidden');
}
updateAllCalculations();
}
function updateAllCalculations() {
updateSRI();
updatePumps();
}
function onDrugSelectionChange() {
const drug = perfusionDrugs[drugSelector.value];
doseInput.value = drug.defaultDose;
updatePumps();
}
// --- EVENT LISTENERS ---
tabSri.addEventListener('click', () => handleTabClick('sri'));
tabBombas.addEventListener('click', () => handleTabClick('bombas'));
patientWeightInput.addEventListener('input', updateAllCalculations);
drugSelector.addEventListener('change', onDrugSelectionChange);
doseInput.addEventListener('input', updatePumps);
// --- INICIALIZACIÓN ---
handleTabClick('sri');
</script>
</body>
</html>