diff --git a/frontend/templates/admin/print.html b/frontend/templates/admin/print.html index 7cfc59d..2257879 100644 --- a/frontend/templates/admin/print.html +++ b/frontend/templates/admin/print.html @@ -128,14 +128,14 @@
- + {% if p.state == 'idle' %}βœ… Disponible {% elif p.state == 'printing' %}πŸ–¨ En impression {% elif p.state == 'disabled' %}⏸ DΓ©sactivΓ©e {% elif p.state == 'offline' %}❌ Hors ligne {% else %}❓ {{ p.state }}{% endif %} - + {{ 'βœ“ Accepte les jobs' if p.accepting else 'βœ— Refuse les jobs' }} {% if p.jobs_count %} @@ -151,15 +151,15 @@
+
{% if p.reasons %} -
{% for reason in p.reasons %}
{{ reason }}
{% endfor %} -
{% endif %} +
{% if p.markers %} @@ -344,27 +344,76 @@ document.querySelectorAll('input[name="print-mode"]').forEach(r => { }); // ── Imprimantes ──────────────────────────────────────────────────────────────── +const STATE_LABELS = { + idle: 'βœ… Disponible', + printing: 'πŸ–¨ En impression', + disabled: '⏸ DΓ©sactivΓ©e', + offline: '❌ Hors ligne', + error: '❌ Erreur', + unknown: '❓ Inconnu', +}; +const STATE_CLASSES = { + idle: 'bs-idle', printing: 'bs-printing', disabled: 'bs-disabled', + offline: 'bs-offline', error: 'bs-offline', unknown: 'bs-unknown', +}; + async function refreshPrinters() { try { const printers = await api('GET', '/api/print/printers'); printers.forEach(p => { - // Met Γ  jour les badges et compteur de jobs const card = document.getElementById('pc-' + p.name); if (!card) return; + + // Classe de la carte card.className = `printer-card state-${p.state}`; - // Actualise les jobs CUPS + + // Badge Γ©tat + const stateBadge = card.querySelector('.badge-state'); + if (stateBadge) { + stateBadge.className = `badge-printer badge-state ${STATE_CLASSES[p.state] || 'bs-unknown'}`; + stateBadge.textContent = STATE_LABELS[p.state] || p.state; + } + + // Badge accepting + const acceptBadge = card.querySelector('.badge-accept'); + if (acceptBadge) { + acceptBadge.className = `badge-printer badge-accept ${p.accepting ? 'bs-accept' : 'bs-reject'}`; + acceptBadge.textContent = p.accepting ? 'βœ“ Accepte les jobs' : 'βœ— Refuse les jobs'; + } + + // Boutons actions + const actionsDiv = card.querySelector('.printer-actions'); + if (actionsDiv) { + actionsDiv.innerHTML = ` + ${p.state === 'disabled' + ? `` + : ``} + ${p.accepting + ? `` + : ``} + ${p.jobs_count ? `` : ''} + `; + } + + // Jobs CUPS const jobsDiv = document.getElementById('jobs-' + p.name); if (jobsDiv) { - if (p.jobs && p.jobs.length) { - jobsDiv.innerHTML = p.jobs.map(j => ` -
- ${j.id} - ${j.user} β€” ${j.size} - -
`).join(''); - } else { - jobsDiv.innerHTML = '
Aucun job en cours
'; - } + jobsDiv.innerHTML = p.jobs && p.jobs.length + ? p.jobs.map(j => ` +
+ ${j.id} + ${j.user} β€” ${j.size} + +
`).join('') + : '
Aucun job en cours
'; + } + + // Erreurs/raisons + const reasonsDiv = card.querySelector('.printer-reasons'); + if (reasonsDiv) { + reasonsDiv.innerHTML = p.reasons && p.reasons.length + ? p.reasons.map(r => `
${r}
`).join('') + : ''; } }); } catch(err) {} diff --git a/frontend/templates/admin/settings.html b/frontend/templates/admin/settings.html index 6162915..641c755 100644 --- a/frontend/templates/admin/settings.html +++ b/frontend/templates/admin/settings.html @@ -807,20 +807,82 @@ async function loadBrightnessConfig() { } } -function previewBrightness(val) { +async function previewBrightness() { + const val = parseInt(document.getElementById('brightness-slider').value); document.getElementById('brightness-val').textContent = val; + try { + await api('PUT', `/api/leds/brightness?value=${val}&save=false`); + showToast(`πŸ‘ AperΓ§u luminositΓ© : ${val}`, 'info'); + } catch(e) { + showToast('Erreur aperΓ§u : ' + e.message, 'error'); + } } async function saveBrightness() { const val = parseInt(document.getElementById('brightness-slider').value); try { await api('PUT', `/api/leds/brightness?value=${val}`); - showToast(`βœ… LuminositΓ© rΓ©glΓ©e Γ  ${val}`, 'success'); + showToast(`βœ… LuminositΓ© ${val} sauvegardΓ©e`, 'success'); } catch(e) { showToast('Erreur : ' + e.message, 'error'); } } +async function previewFlash() { + try { + await api('POST', '/api/leds/effect?effect=capture'); + showToast('πŸ’‘ Flash dΓ©clenchΓ©', 'info'); + } catch(e) { + showToast('Erreur flash : ' + e.message, 'error'); + } +} + +async function saveFlash() { + const r = parseInt(document.getElementById('flash-r').value) || 255; + const g = parseInt(document.getElementById('flash-g').value) || 200; + const b = parseInt(document.getElementById('flash-b').value) || 80; + const duration = parseFloat(document.getElementById('flash-duration').value) || 0.3; + const flashes = parseInt(document.getElementById('flash-count').value) || 2; + try { + await api('PUT', `/api/leds/effect/capture?r=${r}&g=${g}&b=${b}&flash_duration=${duration}&flashes=${flashes}`); + showToast('βœ… Flash sauvegardΓ©', 'success'); + } catch(e) { + showToast('Erreur : ' + e.message, 'error'); + } +} + +function colorPickerToRgb(hex) { + const r = parseInt(hex.slice(1,3), 16); + const g = parseInt(hex.slice(3,5), 16); + const b = parseInt(hex.slice(5,7), 16); + document.getElementById('flash-r').value = r; + document.getElementById('flash-g').value = g; + document.getElementById('flash-b').value = b; + document.getElementById('flash-preview').style.background = `rgb(${r},${g},${b})`; +} + +async function loadFlashConfig() { + try { + const effects = await api('GET', '/api/leds/effects'); + const cap = effects.capture; + if (!cap) return; + if (cap.color) { + document.getElementById('flash-r').value = cap.color[0] ?? 255; + document.getElementById('flash-g').value = cap.color[1] ?? 200; + document.getElementById('flash-b').value = cap.color[2] ?? 80; + document.getElementById('flash-preview').style.background = + `rgb(${cap.color[0]},${cap.color[1]},${cap.color[2]})`; + } + if (cap.flash_duration !== undefined) { + document.getElementById('flash-duration').value = cap.flash_duration; + document.getElementById('flash-dur-val').textContent = cap.flash_duration.toFixed(2); + } + if (cap.flashes !== undefined) { + document.getElementById('flash-count').value = cap.flashes; + } + } catch(e) { console.warn('loadFlashConfig:', e); } +} + async function setAutoBrightness(enabled) { try { await api('PUT', `/api/leds/auto-brightness?enabled=${enabled}`); @@ -836,5 +898,6 @@ async function setAutoBrightness(enabled) { // ── Init ────────────────────────────────────────────────────────────────────── loadBrightnessConfig(); +loadFlashConfig(); {% endblock %} \ No newline at end of file