/** * ───────────────────────────────────────────────────────────────────────────── * Écran Traitements (portage de `ui/screens/TreatmentsScreen.kt`). * * Cartes (nom, voie, dose, chips ester·modèle / Tmax / ×scale / ⏰ rappel, * badge inactif) → tap = éditeur. ⚠️ Le chip modèle passe par modelLabelKey * (fix #59 : un ternaire à 2 branches affichait « Estrannaise » pour WHSAH). * * v1.11.0 (demande utilisatrice, miroir Android) : les ACTIFS d'abord, les * INACTIFS regroupés TOUT EN BAS sous un en-tête de section, cartes * ATTÉNUÉES (opacity 0.55) en plus du badge — « peu discernables ». * ───────────────────────────────────────────────────────────────────────────── */ import { store } from '../data/store.js'; import { modelLabelKey, routeLabelKey, treatmentFlags, treatmentsForDisplay } from '../data/models.js'; import { t } from '../util/i18n.js'; import { formatDose } from '../util/format.js'; import { el, assistChip, fab } from './components.js'; /** * Rend l'écran Traitements. * @param {HTMLElement} container * @param {object} ctx { openEditor: (id:number)=>void, openNew: ()=>void } */ export function renderTreatments(container, ctx) { // v1.11.0 : actifs d'abord, inactifs regroupés en bas (cf treatmentsForDisplay) const treatments = treatmentsForDisplay(store.getTreatments()); const active = treatments.filter((tr) => tr.isActive); const inactive = treatments.filter((tr) => !tr.isActive); const col = el('div', {}); container.appendChild(col); if (treatments.length === 0) { col.appendChild(el('p', {}, t('no_data'))); } /** * Rend UNE carte traitement. @param {object} tr @param {boolean} dimmed * carte inactive → opacité réduite (second signal visuel au-delà du * badge ; reste lisible et cliquable). */ const renderCard = (tr, dimmed) => { const flags = treatmentFlags(tr); // miroir des getters Kotlin const card = el('div', { class: 'card', style: `cursor:pointer;${dimmed ? 'opacity:0.55;' : ''}`, onclick: () => ctx.openEditor(tr.id), }); const titleRow = el('div', { class: 'row' }); titleRow.appendChild(el('span', { style: 'font-weight:600;flex:1;' }, tr.name)); if (!tr.isActive) titleRow.appendChild(el('span', { class: 'small' }, t('inactive'))); card.appendChild(titleRow); card.appendChild(el('div', { class: 'sub' }, `${t(routeLabelKey(tr.route))} · ${formatDose(tr.doseAmount)} ${tr.doseUnit}`)); const chipRow = el('div', { class: 'chip-row wrap', style: 'margin-top:6px;' }); if (flags.usesProfileModel) { // v1.4.7 (fix #59) : label via modelLabelKey — pas de ternaire à 2 branches chipRow.appendChild(assistChip(`${tr.esterType} · ${t(modelLabelKey(tr.pkModel))}`)); } else { chipRow.appendChild(assistChip(`${t('pk_absorption')} ${formatDose(tr.absorptionHours)}h`)); } if (tr.scaleFactor !== 1.0) chipRow.appendChild(assistChip(`×${tr.scaleFactor.toFixed(2)}`)); if (tr.reminderEnabled) { const hh = String(tr.reminderHour ?? 0).padStart(2, '0'); const mm = String(tr.reminderMinute ?? 0).padStart(2, '0'); chipRow.appendChild(assistChip(`⏰ ${hh}:${mm}`)); } card.appendChild(chipRow); return card; }; for (const tr of active) { col.appendChild(renderCard(tr, false)); } // En-tête de section SEULEMENT s'il existe des inactifs (miroir Android) if (inactive.length > 0) { col.appendChild(el('p', { class: 'sub', style: 'margin:14px 0 4px;' }, t('inactive_section'))); } for (const tr of inactive) { col.appendChild(renderCard(tr, true)); } container.appendChild(fab(ctx.openNew)); }