Split du fichier HTML monolithique (1533 lignes, 884KB) en modules séparés : CSS découpé en 4 fichiers (variables, layout, components, features), JS découpé en 13 fichiers (db, state, helpers, render, modals, 7 vues). Ajout CLAUDE.md documentant l'architecture. Correction : routes tableau-de-bord et acces-libre absentes du dispatch render(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
57 lines
3.2 KiB
JavaScript
57 lines
3.2 KiB
JavaScript
// ===================== (ANCIEN) ACCÈS LIBRE — conservé pour toggleFreeAccess =====================
|
||
function viewAccesLibre({selectedClassId}){
|
||
const selId=selectedClassId||DB.classes[0].id;
|
||
const c=cls(selId);
|
||
const fa=DB.freeAccess[selId]||(DB.freeAccess[selId]=new Set());
|
||
const totalUnlocked=fa.size;
|
||
return`<div class="ph">
|
||
<div><div class="pt">🔓 Accès libre</div>
|
||
<div class="ps">Rendre un contenu accessible indépendamment de la progression de l'élève</div></div>
|
||
</div>
|
||
<div class="alert alert-info mb20">ℹ️ Par défaut, les élèves débloquent le contenu en progressant dans l'ordre. Ici vous pouvez forcer l'accès à n'importe quel chapitre ou étape pour une classe donnée, quelle que soit leur avancée.</div>
|
||
<div class="flex g12 mb24" style="align-items:center;flex-wrap:wrap;">
|
||
<label style="text-transform:none;font-size:13px;font-weight:600;margin-bottom:0;">Classe :</label>
|
||
${DB.classes.map(c2=>`<button class="btn ${selId===c2.id?'btn-p':'btn-s'} btn-sm" onclick="S.navigate('acces-libre',{selectedClassId:'${c2.id}'},false)">${c2.name}</button>`).join('')}
|
||
<span class="badge b-amber ms">${totalUnlocked} déverrouillé${totalUnlocked!==1?'s':''}</span>
|
||
</div>
|
||
<div class="al-grid">
|
||
${CHAP_CONTENT.map(ch=>`<div class="al-chap">
|
||
<div class="al-chap-hd">⚔️ Chapitre ${ch.chap}</div>
|
||
${ch.steps.map(step=>{
|
||
const key=`c${ch.chap}s${step.s}`;const isOn=fa.has(key);
|
||
const icon=step.type==='Aventure'?'🗺️':'📝';
|
||
return`<div class="al-item">
|
||
<div class="al-item-label">
|
||
<span style="font-size:14px;">${icon}</span>
|
||
<div>
|
||
<div style="font-size:12px;font-weight:600;">${step.type}</div>
|
||
<div style="font-size:10px;color:var(--muted);">${step.type==='Aventure'?'Aventure '+(step.s<=2?1:2):('Quiz '+(step.s<=2?1:2))}</div>
|
||
</div>
|
||
</div>
|
||
<label class="toggle-sw">
|
||
<input type="checkbox" ${isOn?'checked':''} onchange="toggleFreeAccess('${selId}','${key}',this.checked)">
|
||
<div class="toggle-track"></div>
|
||
<div class="toggle-thumb"></div>
|
||
</label>
|
||
</div>`;}).join('')}
|
||
</div>`).join('')}
|
||
</div>
|
||
<div class="card" style="padding:18px;">
|
||
<div class="card-title mb12">Résumé — ${c.name}</div>
|
||
${totalUnlocked===0?`<p class="sm muted">Aucun contenu déverrouillé. Tous les élèves progressent selon leur niveau.</p>`:`
|
||
<p class="sm muted mb12">Contenu déverrouillé pour tous les élèves de ${c.name} :</p>
|
||
<div class="flex g8" style="flex-wrap:wrap;">
|
||
${[...fa].map(key=>{
|
||
const m=key.match(/c(\d)s(\d)/);if(!m)return'';
|
||
const step=CHAP_CONTENT[m[1]-1]?.steps[m[2]-1];if(!step)return'';
|
||
return`<span class="badge b-amber">⚔️ Chap. ${m[1]} — ${step.type} ${m[2]<=2?1:2}</span>`;
|
||
}).join('')}
|
||
</div>`}
|
||
</div>`;
|
||
}
|
||
function toggleFreeAccess(classId,key,checked){
|
||
if(!DB.freeAccess[classId])DB.freeAccess[classId]=new Set();
|
||
if(checked){DB.freeAccess[classId].add(key);showToast('Accès activé ✓','ok');}
|
||
else{DB.freeAccess[classId].delete(key);showToast('Accès retiré');}
|
||
S.navigate('acces-libre',{selectedClassId:classId},false);
|
||
}
|