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