Wizard evenement tactile + menu admin simplifie + bouton update + logo SikaPics

- Wizard: 6 etapes (nom, theme, modes, nb photos, partage, resume)
- Gros boutons tactiles, une question par ecran
- Parametres avances accessibles depuis le wizard
- Bouton "Mettre a jour l'affichage" dans Fonctions > Systeme
- Logo SikaPics dans le theme sikapics
- Menu admin reorganise: Materiel / Compteur / Destinations / Personnalisation / Evenement / Fonctions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-07 18:12:51 +02:00
parent 626db8905a
commit 229a388a1e
4 changed files with 440 additions and 59 deletions

View File

@@ -152,11 +152,11 @@ function validerMdpAdmin() {
const input = document.getElementById('input-mdp-admin');
if (input.value === MDP_ADMIN) {
fermerPopupMdp();
allerA('admin');
allerA('wizard');
wizardInit();
} else {
document.getElementById('mdp-erreur').classList.remove('cache');
input.value = '';
input.focus();
}
}
@@ -252,5 +252,121 @@ wsOnMessage('config_maj', (msg) => {
appliquerConfig();
});
// === WIZARD ===
let wizardStep = 1;
const WIZARD_TOTAL = 6;
let wizardData = {
nom: '',
theme: 'base',
modes: { simple: true, multi: true },
nbPhotos: 4,
fonctions: {},
};
function wizardInit() {
wizardStep = 1;
wizardData.nom = config.evenement?.nom || '';
wizardData.theme = config.evenement?.theme || 'base';
wizardData.nbPhotos = config.multi_shot?.nombre_photos || 4;
document.getElementById('wiz-nom').value = wizardData.nom;
document.getElementById('wiz-nb-photos').textContent = wizardData.nbPhotos;
wizardAfficherStep();
}
function wizardAfficherStep() {
document.querySelectorAll('.wizard-step').forEach(s => s.classList.remove('actif'));
const step = document.querySelector(`.wizard-step[data-step="${wizardStep}"]`);
if (step) step.classList.add('actif');
// Progress dots
const prog = document.getElementById('wizard-progress');
prog.innerHTML = '';
for (let i = 1; i <= WIZARD_TOTAL; i++) {
const dot = document.createElement('div');
dot.className = 'wizard-dot' + (i === wizardStep ? ' actif' : '') + (i < wizardStep ? ' fait' : '');
prog.appendChild(dot);
}
}
function wizardSuivant() {
// Sauvegarder l'etape courante
if (wizardStep === 1) wizardData.nom = document.getElementById('wiz-nom').value;
if (wizardStep === 4) wizardData.nbPhotos = parseInt(document.getElementById('wiz-nb-photos').textContent);
wizardStep++;
if (wizardStep > WIZARD_TOTAL) wizardStep = WIZARD_TOTAL;
// Resume
if (wizardStep === WIZARD_TOTAL) {
const modes = Object.keys(wizardData.modes).filter(k => wizardData.modes[k]);
const foncs = Object.keys(wizardData.fonctions).filter(k => wizardData.fonctions[k]);
document.getElementById('wiz-resume').innerHTML = `
<div><strong>Evenement :</strong> ${wizardData.nom || 'Photobooth'}</div>
<div><strong>Theme :</strong> ${wizardData.theme}</div>
<div><strong>Modes :</strong> ${modes.join(', ') || 'photo'}</div>
<div><strong>Photos/pellicule :</strong> ${wizardData.nbPhotos}</div>
<div><strong>Partage :</strong> ${foncs.join(', ') || 'aucun'}</div>
`;
}
wizardAfficherStep();
}
function wizardChoisir(btn, key) {
btn.closest('.wizard-choix').querySelectorAll('.wizard-card').forEach(c => c.classList.remove('actif'));
btn.classList.add('actif');
wizardData[key] = btn.dataset.val;
}
function wizardToggle(btn) {
btn.classList.toggle('actif');
const val = btn.dataset.val;
const isActive = btn.classList.contains('actif');
if (['simple', 'multi'].includes(val)) {
wizardData.modes[val] = isActive;
} else {
wizardData.fonctions[val] = isActive;
}
}
function wizardNbPhotos(delta) {
const el = document.getElementById('wiz-nb-photos');
let n = parseInt(el.textContent) + delta;
n = Math.max(2, Math.min(8, n));
el.textContent = n;
wizardData.nbPhotos = n;
}
async function wizardTerminer() {
// Sauvegarder toute la config
await apiPost('/api/config', {
evenement: {
nom: wizardData.nom || 'Photobooth',
theme: wizardData.theme,
},
fonctionnalites: {
photo_simple: wizardData.modes.simple !== false,
multi_shot: wizardData.modes.multi !== false,
impression: !!wizardData.fonctions.impression,
email: !!wizardData.fonctions.email,
qr_code: !!wizardData.fonctions.qr,
},
multi_shot: {
nombre_photos: wizardData.nbPhotos,
mode: 'strip',
},
booth: {
actif: !!wizardData.fonctions.galerie_live,
},
});
config = await apiGet('/api/config');
appliquerConfig();
chargerBoothInfo();
allerA('accueil');
}
// Demarrage
document.addEventListener('DOMContentLoaded', init);