mirror of
https://github.com/gauvainboiche/ketapk.git
synced 2026-09-02 11:13:11 +02:00
refacto: Adding i18n support with FR and EN as base
This commit is contained in:
+53
-52
@@ -5,106 +5,114 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>KétaPK - Simulation Pharmacocinétique</title>
|
||||
|
||||
<!-- Tailwind CSS CDN -->
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
|
||||
<!-- Chart.js + Plugin Annotation -->
|
||||
<!-- Chart.js + Plugins -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@3.0.1/dist/chartjs-plugin-annotation.min.js"></script>
|
||||
|
||||
<!-- jsPDF pour Exportation PDF -->
|
||||
<!-- jsPDF -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
|
||||
|
||||
<!-- CSS Personnalisé -->
|
||||
<!-- Custom CSS -->
|
||||
<link rel="stylesheet" href="css/styles.css">
|
||||
</head>
|
||||
<body class="h-full flex flex-col font-sans antialiased selection:bg-amber-500 selection:text-slate-950">
|
||||
|
||||
<!-- ==================== HEADER / NAVBAR ==================== -->
|
||||
<!-- NAVBAR -->
|
||||
<header class="bg-slate-800/90 backdrop-blur border-b border-slate-700/80 sticky top-0 z-40 shadow-lg">
|
||||
<div class="max-w-7xl mx-auto px-4 py-3 flex flex-wrap items-center justify-between gap-4">
|
||||
|
||||
<!-- Logo & Titre -->
|
||||
<!-- Logo -->
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="bg-gradient-to-r from-amber-500 to-amber-600 text-slate-950 font-black px-3.5 py-1 rounded-xl text-xl tracking-wider shadow-md shadow-amber-500/20">
|
||||
KétaPK
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-sm font-bold text-slate-200 leading-none">Pharmaco Kinetics</span>
|
||||
<span class="text-[10px] text-slate-400 font-mono">v1.00 • Dr Georges Mion</span>
|
||||
<span data-i18n="app.title" class="text-sm font-bold text-slate-200 leading-none">Pharmaco Kinetics</span>
|
||||
<span data-i18n="app.version" class="text-[10px] text-slate-400 font-mono">v1.00 • Dr Georges Mion</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Selecteur de Mode (Eskétamine / Racémique) -->
|
||||
<!-- Mode Selector -->
|
||||
<div class="flex items-center bg-slate-950/80 p-1 rounded-xl border border-slate-700/80 shadow-inner">
|
||||
<button id="btnEsk" type="button" class="px-4 py-1.5 rounded-lg text-xs font-bold transition-all bg-amber-500 text-slate-950 shadow-md shadow-amber-500/30">
|
||||
<button id="btnEsk" type="button" data-i18n="nav.mode_esk" class="px-4 py-1.5 rounded-lg text-xs font-bold transition-all bg-amber-500 text-slate-950 shadow-md shadow-amber-500/30">
|
||||
ESKETAMINE
|
||||
</button>
|
||||
<button id="btnRac" type="button" class="px-4 py-1.5 rounded-lg text-xs font-bold transition-all text-slate-400 hover:text-slate-200">
|
||||
<button id="btnRac" type="button" data-i18n="nav.mode_rac" class="px-4 py-1.5 rounded-lg text-xs font-bold transition-all text-slate-400 hover:text-slate-200">
|
||||
RACÉMIQUE
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Actions Rapides -->
|
||||
<!-- Actions & Language -->
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex items-center gap-1 bg-slate-900 border border-slate-700/70 rounded-xl px-2 py-1">
|
||||
<span class="text-xs">🌐</span>
|
||||
<select id="selectLang" class="bg-transparent text-xs font-bold text-slate-300 outline-none cursor-pointer">
|
||||
<option value="fr" class="bg-slate-900">FR</option>
|
||||
<option value="en" class="bg-slate-900">EN</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button id="btnOpenCalc" type="button" class="bg-slate-700/80 hover:bg-slate-700 text-slate-200 border border-slate-600/60 px-3 py-1.5 rounded-lg text-xs font-medium transition flex items-center gap-1.5 shadow-sm">
|
||||
<span>🧮</span>
|
||||
<span class="hidden sm:inline">Calculateur</span>
|
||||
<span data-i18n="nav.calculator" class="hidden sm:inline">Calculateur</span>
|
||||
</button>
|
||||
|
||||
<button id="btnExportPdf" type="button" class="bg-indigo-600 hover:bg-indigo-500 text-white border border-indigo-500/50 px-3 py-1.5 rounded-lg text-xs font-semibold transition flex items-center gap-1.5 shadow-md shadow-indigo-600/20">
|
||||
<span>📄</span>
|
||||
<span class="hidden sm:inline">Exporter PDF</span>
|
||||
<span data-i18n="nav.export_pdf" class="hidden sm:inline">Exporter PDF</span>
|
||||
</button>
|
||||
|
||||
<button id="btnRaz" type="button" class="bg-rose-500/10 hover:bg-rose-500/20 text-rose-400 border border-rose-500/30 px-3 py-1.5 rounded-lg text-xs font-medium transition flex items-center gap-1.5">
|
||||
<span>🔄</span>
|
||||
<span class="hidden sm:inline">RAZ</span>
|
||||
<span data-i18n="nav.raz" class="hidden sm:inline">RAZ</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- ==================== CONTENU PRINCIPAL ==================== -->
|
||||
<!-- MAIN -->
|
||||
<main class="flex-1 max-w-7xl w-full mx-auto p-4 grid grid-cols-1 lg:grid-cols-12 gap-6">
|
||||
|
||||
<!-- PANNEAU LATÉRAL (3 colonnes lg) -->
|
||||
<!-- SIDEBAR -->
|
||||
<aside class="lg:col-span-3 space-y-5">
|
||||
|
||||
<!-- Carte : Données Patient -->
|
||||
<!-- Patient Form -->
|
||||
<div class="bg-slate-800/60 border border-slate-700/70 rounded-2xl p-4 shadow-md backdrop-blur-sm">
|
||||
<h2 class="text-xs font-bold text-slate-400 uppercase tracking-wider mb-4 border-b border-slate-700/60 pb-2 flex items-center gap-2">
|
||||
<h2 data-i18n="patient.title" class="text-xs font-bold text-slate-400 uppercase tracking-wider mb-4 border-b border-slate-700/60 pb-2 flex items-center gap-2">
|
||||
<span>👤</span> Caractéristiques Patient
|
||||
</h2>
|
||||
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<label for="inputWeight" class="block text-xs text-slate-300 font-medium mb-1">Poids (kg)</label>
|
||||
<input type="number" id="inputWeight" value="70" min="1" max="250" class="w-full bg-slate-900/90 border border-slate-700 rounded-xl px-3 py-2 text-sm text-white font-semibold focus:ring-2 focus:ring-amber-500 focus:border-amber-500 outline-none transition">
|
||||
<label for="inputWeight" data-i18n="patient.weight" class="block text-xs text-slate-300 font-medium mb-1">Poids (kg)</label>
|
||||
<input type="number" id="inputWeight" value="70" min="1" max="250" class="w-full bg-slate-900/90 border border-slate-700 rounded-xl px-3 py-2 text-sm text-white font-semibold focus:ring-2 focus:ring-amber-500 outline-none">
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<label for="inputAge" class="block text-xs text-slate-300 font-medium mb-1">Âge (ans)</label>
|
||||
<input type="number" id="inputAge" value="50" min="1" max="120" class="w-full bg-slate-900/90 border border-slate-700 rounded-xl px-3 py-2 text-sm text-white font-semibold focus:ring-2 focus:ring-amber-500 outline-none transition">
|
||||
<label for="inputAge" data-i18n="patient.age" class="block text-xs text-slate-300 font-medium mb-1">Âge (ans)</label>
|
||||
<input type="number" id="inputAge" value="50" min="1" max="120" class="w-full bg-slate-900/90 border border-slate-700 rounded-xl px-3 py-2 text-sm text-white font-semibold focus:ring-2 focus:ring-amber-500 outline-none">
|
||||
</div>
|
||||
<div>
|
||||
<label for="inputHeight" class="block text-xs text-slate-300 font-medium mb-1">Taille (cm)</label>
|
||||
<input type="number" id="inputHeight" value="170" min="40" max="230" class="w-full bg-slate-900/90 border border-slate-700 rounded-xl px-3 py-2 text-sm text-white font-semibold focus:ring-2 focus:ring-amber-500 outline-none transition">
|
||||
<label for="inputHeight" data-i18n="patient.height" class="block text-xs text-slate-300 font-medium mb-1">Taille (cm)</label>
|
||||
<input type="number" id="inputHeight" value="170" min="40" max="230" class="w-full bg-slate-900/90 border border-slate-700 rounded-xl px-3 py-2 text-sm text-white font-semibold focus:ring-2 focus:ring-amber-500 outline-none">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="inputConc" class="block text-xs text-slate-300 font-medium mb-1">Concentration Produit (mg/mL)</label>
|
||||
<input type="number" id="inputConc" value="5" step="0.1" class="w-full bg-slate-900/90 border border-slate-700 rounded-xl px-3 py-2 text-sm text-amber-400 font-bold focus:ring-2 focus:ring-amber-500 outline-none transition">
|
||||
<label for="inputConc" data-i18n="patient.concentration" class="block text-xs text-slate-300 font-medium mb-1">Concentration Produit (mg/mL)</label>
|
||||
<input type="number" id="inputConc" value="5" step="0.1" class="w-full bg-slate-900/90 border border-slate-700 rounded-xl px-3 py-2 text-sm text-amber-400 font-bold focus:ring-2 focus:ring-amber-500 outline-none">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Carte : Sélection Modèles PK -->
|
||||
<!-- Models Selection -->
|
||||
<div class="bg-slate-800/60 border border-slate-700/70 rounded-2xl p-4 shadow-md backdrop-blur-sm">
|
||||
<h2 class="text-xs font-bold text-slate-400 uppercase tracking-wider mb-3 border-b border-slate-700/60 pb-2 flex items-center gap-2">
|
||||
<h2 data-i18n="models.title" class="text-xs font-bold text-slate-400 uppercase tracking-wider mb-3 border-b border-slate-700/60 pb-2 flex items-center gap-2">
|
||||
<span>📈</span> Modèles Pharmacocinétiques
|
||||
</h2>
|
||||
|
||||
@@ -128,27 +136,27 @@
|
||||
|
||||
</aside>
|
||||
|
||||
<!-- ZONE PRINCIPALE : GRAPHIQUE & GRILLE TEMPORELLE (9 colonnes lg) -->
|
||||
<!-- CONTENT -->
|
||||
<section class="lg:col-span-9 space-y-5 flex flex-col">
|
||||
|
||||
<!-- Canvas Graphique Interactif -->
|
||||
<!-- Chart -->
|
||||
<div class="bg-slate-800/60 border border-slate-700/70 rounded-2xl p-4 shadow-md backdrop-blur-sm flex flex-col h-[420px] relative">
|
||||
<div class="flex-1 w-full h-full relative">
|
||||
<canvas id="pkChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Grille Temporelle Déroulante (0 à 300 minutes) -->
|
||||
<!-- Timeline Grid -->
|
||||
<div class="bg-slate-800/60 border border-slate-700/70 rounded-2xl p-4 shadow-md backdrop-blur-sm">
|
||||
<div class="flex items-center justify-between mb-3 border-b border-slate-700/60 pb-2">
|
||||
<h2 class="text-xs font-bold text-slate-300 uppercase tracking-wider flex items-center gap-2">
|
||||
<h2 data-i18n="timeline.title" class="text-xs font-bold text-slate-300 uppercase tracking-wider flex items-center gap-2">
|
||||
<span>⏱️</span> Saisie Chronologique Doses & Perfusion (0 - 300 min)
|
||||
</h2>
|
||||
<span class="text-[10px] text-slate-400 italic">Défilement horizontal 👉</span>
|
||||
<span data-i18n="timeline.scroll_hint" class="text-[10px] text-slate-400 italic">Défilement horizontal 👉</span>
|
||||
</div>
|
||||
|
||||
<div id="timelineGrid" class="flex gap-2 overflow-x-auto pb-2 scrollbar-thin scrollbar-thumb-slate-700 scrollbar-track-slate-900">
|
||||
<!-- Les 61 blocs (pas de 5 min) sont injectés dynamiquement par app.js -->
|
||||
<!-- Injected via app.js -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -156,32 +164,28 @@
|
||||
|
||||
</main>
|
||||
|
||||
<!-- ==================== FENÊTRE MODALE : CALCULATEUR ==================== -->
|
||||
<!-- MODAL CALCULATOR -->
|
||||
<div id="modalCalc" class="fixed inset-0 bg-slate-950/80 backdrop-blur-sm z-50 hidden flex items-center justify-center p-4 transition-opacity">
|
||||
<div class="bg-slate-800 border border-slate-700 rounded-2xl w-full max-w-lg p-6 space-y-6 shadow-2xl relative">
|
||||
|
||||
<!-- Modal Header -->
|
||||
<div class="flex justify-between items-center border-b border-slate-700 pb-3">
|
||||
<h3 class="text-base font-bold text-amber-400 flex items-center gap-2">
|
||||
<h3 data-i18n="calculator.title" class="text-base font-bold text-amber-400 flex items-center gap-2">
|
||||
<span>🧮</span> Calculateur & Conversions de Doses
|
||||
</h3>
|
||||
<button id="btnCloseCalc" type="button" class="text-slate-400 hover:text-white font-bold text-xl leading-none transition">×</button>
|
||||
</div>
|
||||
|
||||
<!-- Modal Body -->
|
||||
<div class="space-y-4">
|
||||
|
||||
<!-- Poids / Concentration Références -->
|
||||
<div class="grid grid-cols-2 gap-3 bg-slate-900/80 p-3 rounded-xl border border-slate-700/50">
|
||||
<div>
|
||||
<label for="calcWeight" class="block text-xs text-slate-400 mb-1">Poids du patient</label>
|
||||
<label for="calcWeight" data-i18n="calculator.patient_weight" class="block text-xs text-slate-400 mb-1">Poids du patient</label>
|
||||
<div class="flex items-center gap-1">
|
||||
<input type="number" id="calcWeight" value="70" class="w-full bg-slate-800 border border-slate-700 rounded-lg p-2 text-sm text-white font-bold outline-none">
|
||||
<span class="text-xs text-slate-400">kg</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="calcConc" class="block text-xs text-slate-400 mb-1">Concentration</label>
|
||||
<label for="calcConc" data-i18n="calculator.drug_conc" class="block text-xs text-slate-400 mb-1">Concentration</label>
|
||||
<div class="flex items-center gap-1">
|
||||
<input type="number" id="calcConc" value="10" class="w-full bg-slate-800 border border-slate-700 rounded-lg p-2 text-sm text-amber-400 font-bold outline-none">
|
||||
<span class="text-xs text-slate-400">mg/mL</span>
|
||||
@@ -189,31 +193,29 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Conversions Bolus -->
|
||||
<div>
|
||||
<h4 class="text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2">Conversion Bolus</h4>
|
||||
<h4 data-i18n="calculator.bolus_header" class="text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2">Conversion Bolus</h4>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label for="calcMg" class="block text-[10px] text-slate-500 mb-1">Dose totale (mg)</label>
|
||||
<label for="calcMg" data-i18n="calculator.total_dose" class="block text-[10px] text-slate-500 mb-1">Dose totale (mg)</label>
|
||||
<input type="number" id="calcMg" placeholder="ex: 35" class="w-full bg-slate-900 border border-slate-700 rounded-lg p-2 text-sm text-white focus:ring-1 focus:ring-amber-500 outline-none">
|
||||
</div>
|
||||
<div>
|
||||
<label for="calcMgKg" class="block text-[10px] text-slate-500 mb-1">Dose relative (mg/kg)</label>
|
||||
<label for="calcMgKg" data-i18n="calculator.relative_dose" class="block text-[10px] text-slate-500 mb-1">Dose relative (mg/kg)</label>
|
||||
<input type="number" id="calcMgKg" placeholder="ex: 0.5" class="w-full bg-slate-900 border border-slate-700 rounded-lg p-2 text-sm text-white focus:ring-1 focus:ring-amber-500 outline-none">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Conversions Perfusion -->
|
||||
<div>
|
||||
<h4 class="text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2">Conversion Perfusion</h4>
|
||||
<h4 data-i18n="calculator.infusion_header" class="text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2">Conversion Perfusion</h4>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label for="calcMgKgH" class="block text-[10px] text-slate-500 mb-1">Débit (mg/kg/h)</label>
|
||||
<label for="calcMgKgH" data-i18n="calculator.rate_mgkgh" class="block text-[10px] text-slate-500 mb-1">Débit (mg/kg/h)</label>
|
||||
<input type="number" id="calcMgKgH" placeholder="ex: 0.3" class="w-full bg-slate-900 border border-slate-700 rounded-lg p-2 text-sm text-white focus:ring-1 focus:ring-amber-500 outline-none">
|
||||
</div>
|
||||
<div>
|
||||
<label for="calcUgKgMin" class="block text-[10px] text-slate-500 mb-1">Débit (µg/kg/min)</label>
|
||||
<label for="calcUgKgMin" data-i18n="calculator.rate_ugkgmin" class="block text-[10px] text-slate-500 mb-1">Débit (µg/kg/min)</label>
|
||||
<input type="number" id="calcUgKgMin" placeholder="ex: 5" class="w-full bg-slate-900 border border-slate-700 rounded-lg p-2 text-sm text-white focus:ring-1 focus:ring-amber-500 outline-none">
|
||||
</div>
|
||||
</div>
|
||||
@@ -223,7 +225,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Entrée Application Javascript Principal (Module ES6) -->
|
||||
<script type="module" src="js/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user