import { MODES, PK_MODELS, CLINICAL_THRESHOLDS, generateSimulationData } from '/pkCore.js'; import { adjustChartYScale } from './chartManager.js'; import { initCalculatorUI } from './calculator.js'; import { generatePDFReport } from './pdfExport.js'; import { initI18n, getCurrentLang, t } from './i18n.js'; let currentMode = MODES.ESKETAMINE; let pkChart = null; const timelineInputs = Array.from({ length: 61 }, (_, i) => ({ time: i * 5, bolusMg: 0, perfRateMgKgH: 0 })); document.addEventListener('DOMContentLoaded', async () => { await initI18n(); const selectLang = document.getElementById('selectLang'); if (selectLang) { selectLang.value = getCurrentLang(); selectLang.addEventListener('change', async (e) => { await initI18n(e.target.value); renderTimelineGrid(); updateSimulation(); }); } initChart(); renderTimelineGrid(); initCalculatorUI(); setupEventListeners(); updateSimulation(); }); function initChart() { const ctx = document.getElementById('pkChart').getContext('2d'); pkChart = new Chart(ctx, { type: 'line', data: { labels: timelineInputs.map(d => `${d.time}'`), datasets: [] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true, max: CLINICAL_THRESHOLDS[currentMode].maxScale, title: { display: true, text: 'Cp (ng/mL)', color: '#94a3b8' }, grid: { color: 'rgba(51, 65, 85, 0.4)' } }, x: { title: { display: true, text: 'Temps (minutes)', color: '#94a3b8' }, grid: { color: 'rgba(51, 65, 85, 0.4)' } } }, plugins: { legend: { labels: { color: '#f8fafc' } }, annotation: { annotations: {} } } } }); } function updateSimulation() { const weight = parseFloat(document.getElementById('inputWeight').value) || 70; const datasets = []; if (document.getElementById('chkDomino').checked) { datasets.push({ label: PK_MODELS.DOMINO.name, data: generateSimulationData({ model: PK_MODELS.DOMINO, weightKg: weight, timelineInputs }), borderColor: PK_MODELS.DOMINO.color, borderWidth: 3, tension: 0.2 }); } if (document.getElementById('chkClements').checked) { datasets.push({ label: PK_MODELS.CLEMENTS.name, data: generateSimulationData({ model: PK_MODELS.CLEMENTS, weightKg: weight, timelineInputs }), borderColor: PK_MODELS.CLEMENTS.color, borderWidth: 3, tension: 0.2 }); } if (document.getElementById('chkKamp').checked) { datasets.push({ label: PK_MODELS.KAMP.name, data: generateSimulationData({ model: PK_MODELS.KAMP, weightKg: weight, timelineInputs }), borderColor: PK_MODELS.KAMP.color, borderWidth: 3, tension: 0.2 }); } pkChart.data.datasets = datasets; adjustChartYScale(pkChart, currentMode, datasets); pkChart.update(); } function renderTimelineGrid() { const container = document.getElementById('timelineGrid'); container.innerHTML = ''; timelineInputs.forEach((item, idx) => { const col = document.createElement('div'); col.className = 'flex-1 bg-slate-900 border border-slate-700/60 rounded-xl p-2 text-center text-xs flex flex-col gap-1.5 min-w-[85px]'; col.innerHTML = `
${item.time} min
${t('timeline.bolus')}
${t('timeline.perf')}
`; container.appendChild(col); }); } function setupEventListeners() { document.getElementById('timelineGrid').addEventListener('input', (e) => { const idx = e.target.dataset.idx; const field = e.target.dataset.field; if (idx !== undefined && field) { timelineInputs[idx][field] = parseFloat(e.target.value) || 0; updateSimulation(); } }); document.getElementById('btnEsk').addEventListener('click', () => setMode(MODES.ESKETAMINE)); document.getElementById('btnRac').addEventListener('click', () => setMode(MODES.RACEMIQUE)); ['inputWeight', 'chkDomino', 'chkClements', 'chkKamp'].forEach(id => { document.getElementById(id).addEventListener('change', updateSimulation); }); document.getElementById('btnRaz').addEventListener('click', () => { timelineInputs.forEach(item => { item.bolusMg = 0; item.perfRateMgKgH = 0; }); renderTimelineGrid(); updateSimulation(); }); document.getElementById('btnExportPdf').addEventListener('click', () => { const patientData = { weight: document.getElementById('inputWeight').value || 70, age: document.getElementById('inputAge').value || 50, height: document.getElementById('inputHeight').value || 170 }; generatePDFReport(pkChart, patientData, currentMode); }); } function setMode(mode) { currentMode = mode; const btnEsk = document.getElementById('btnEsk'); const btnRac = document.getElementById('btnRac'); const concInput = document.getElementById('inputConc'); if (mode === MODES.ESKETAMINE) { btnEsk.className = 'px-4 py-1.5 rounded-lg text-xs font-bold bg-amber-500 text-slate-950 shadow-md shadow-amber-500/30'; btnRac.className = 'px-4 py-1.5 rounded-lg text-xs font-bold text-slate-400 hover:text-slate-200'; concInput.value = CLINICAL_THRESHOLDS[MODES.ESKETAMINE].defaultConcentration; } else { btnRac.className = 'px-4 py-1.5 rounded-lg text-xs font-bold bg-fuchsia-500 text-slate-950 shadow-md shadow-fuchsia-500/30'; btnEsk.className = 'px-4 py-1.5 rounded-lg text-xs font-bold text-slate-400 hover:text-slate-200'; concInput.value = CLINICAL_THRESHOLDS[MODES.RACEMIQUE].defaultConcentration; } updateSimulation(); }