This commit is contained in:
@@ -16,15 +16,17 @@
|
||||
const drawers = ['junior','senior','principal'].map(level => {
|
||||
const cases = catalog.map((hunt, i) => ({hunt, i})).filter(entry => entry.hunt.difficulty === level);
|
||||
if (!cases.length) return '';
|
||||
return `<div class="bh-cabinet-level">${difficultyNames[level]}</div>${cases.map(({hunt, i}) => `<button class="bh-drawer ${i === selectedCase ? 'active' : ''}" data-select="${i}" ${i === selectedCase ? 'aria-pressed="true"' : 'aria-pressed="false"'}><span class="bh-drawer-handle"></span><span class="bh-case-no">${esc(hunt.examScope)} · ${esc(hunt.difficulty).toUpperCase()}</span><strong>${esc(hunt.title)}</strong><small>${hunt.bugCount} Bug${hunt.bugCount === 1 ? '' : 's'} · ${hunt.fileCount} ${hunt.fileCount === 1 ? 'Datei' : 'Dateien'}</small></button>`).join('')}`;
|
||||
return `<div class="bh-cabinet-level">${difficultyNames[level]}</div>${cases.map(({hunt, i}) => `<button class="bh-drawer ${hunt.solved ? 'solved' : ''} ${i === selectedCase ? 'active' : ''}" data-select="${i}" ${i === selectedCase ? 'aria-pressed="true"' : 'aria-pressed="false"'}><span class="bh-drawer-handle"></span>${hunt.solved ? '<span class="bh-solved-stamp">GELÖST</span>' : ''}<span class="bh-case-no">${esc(hunt.examScope)} · ${esc(hunt.difficulty).toUpperCase()}</span><strong>${esc(hunt.title)}</strong><small>${hunt.bugCount} Bug${hunt.bugCount === 1 ? '' : 's'} · ${hunt.fileCount} ${hunt.fileCount === 1 ? 'Datei' : 'Dateien'}</small></button>`).join('')}`;
|
||||
}).join('');
|
||||
view.innerHTML = `<section class="bh-hero"><span class="bh-stamp">VERTRAULICH</span><span class="bh-kicker">DEBUG-FALLAKTEN</span><h1>Welche Spur verfolgst du?</h1><p>Öffne eine Akte, lies die Beweise und sichere deinen Befund Schritt für Schritt. Jede Akte bleibt so lange offen, wie du sie brauchst.</p></section><section class="bh-archive"><div class="bh-archive-head"><div><span class="bh-kicker">AKTENSCHRANK · ${catalog.length} AKTEN</span><h2>Fallarchiv</h2></div><p>Nach Schwierigkeit sortiert: Grundlagen, Praxis, Komplexfälle.</p></div><div class="bh-cabinet" aria-label="Fallakten nach Schwierigkeit"><div class="bh-cabinet-label">BUGHUNTER · ARCHIV</div>${drawers}</div><article class="bh-case-detail"><span class="bh-stamp">AUSGEWÄHLTE AKTE</span><span class="bh-kicker">${esc(selectedHunt.examScope)} · ${esc(selectedHunt.difficulty).toUpperCase()} · ${esc(selectedHunt.language)}</span><h2>${esc(selectedHunt.title)}</h2><p>${esc(selectedHunt.description)}</p><div class="bh-tags"><span>${selectedHunt.fileCount} ${selectedHunt.fileCount === 1 ? 'Datei' : 'Dateien'}</span><span>${selectedHunt.bugCount} Bug${selectedHunt.bugCount === 1 ? '' : 's'}</span></div><button class="bh-btn primary" data-start="${esc(selectedHunt.slug)}">AKTE ÖFFNEN</button></article></section>`;
|
||||
view.innerHTML = `<section class="bh-hero"><span class="bh-stamp">VERTRAULICH</span><span class="bh-kicker">DEBUG-FALLAKTEN</span><h1>Welche Spur verfolgst du?</h1><p>Öffne eine Akte, lies die Beweise und sichere deinen Befund Schritt für Schritt. Jede Akte bleibt so lange offen, wie du sie brauchst.</p></section><section class="bh-archive"><div class="bh-archive-head"><div><span class="bh-kicker">AKTENSCHRANK · ${catalog.length} AKTEN</span><h2>Fallarchiv</h2></div><p>Nach Schwierigkeit sortiert: Grundlagen, Praxis, Komplexfälle.</p></div><div class="bh-cabinet" aria-label="Fallakten nach Schwierigkeit"><div class="bh-cabinet-label">BUGHUNTER · ARCHIV</div>${drawers}</div><article class="bh-case-detail">${selectedHunt.solved ? '<span class="bh-solved-stamp bh-solved-stamp-detail">GELÖST</span>' : ''}<span class="bh-stamp">AUSGEWÄHLTE AKTE</span><span class="bh-kicker">${esc(selectedHunt.examScope)} · ${esc(selectedHunt.difficulty).toUpperCase()} · ${esc(selectedHunt.language)}</span><h2>${esc(selectedHunt.title)}</h2><p>${esc(selectedHunt.description)}</p><div class="bh-tags"><span>${selectedHunt.fileCount} ${selectedHunt.fileCount === 1 ? 'Datei' : 'Dateien'}</span><span>${selectedHunt.bugCount} Bug${selectedHunt.bugCount === 1 ? '' : 's'}</span></div><div class="bh-actions"><button class="bh-btn primary" data-start="${esc(selectedHunt.slug)}">${selectedHunt.solved ? 'ERNEUT SPIELEN' : 'AKTE ÖFFNEN'}</button>${selectedHunt.solved ? `<button class="bh-btn" data-reset="${esc(selectedHunt.slug)}">FALL VARIIEREN</button>` : ''}</div></article></section>`;
|
||||
view.querySelectorAll('[data-select]').forEach(drawer => drawer.addEventListener('click', () => { selectedCase = Number(drawer.dataset.select); renderCatalog(); }));
|
||||
view.querySelector('[data-start]')?.addEventListener('click', event => begin(event.currentTarget.dataset.start));
|
||||
view.querySelector('[data-reset]')?.addEventListener('click', event => resetCase(event.currentTarget.dataset.reset));
|
||||
}
|
||||
function begin(slug) { api('/session/' + encodeURIComponent(slug)).then(data => { if (!data.found) throw new Error('Fallakte nicht verfügbar.'); session = data; index = 0; handoff = null; answers = session.bugs.map(() => ({locate:null, classify:null, fix:null})); started = Date.now(); renderBriefing(); }).catch(error); }
|
||||
function resetCase(slug) { post('/reset/' + encodeURIComponent(slug), {}).then(() => begin(slug)).catch(error); }
|
||||
function renderBriefing() {
|
||||
view.innerHTML = `<section class="bh-briefing"><span class="bh-stamp">NEUE AKTE</span><span class="bh-kicker">${esc(session.examScope)} · ${esc(session.difficulty).toUpperCase()} · ${esc(session.language)}</span><h1>${esc(session.title)}</h1><p>${esc(session.briefing)}</p><pre>${esc(session.consoleOutput)}</pre><div class="bh-rules"><div><b>1</b> Ort markieren</div><div><b>2</b> Fehler einordnen</div><div><b>3</b> sauberen Fix wählen</div></div><button class="bh-btn primary" id="bhStart">ERMITTLUNG STARTEN</button></section>`;
|
||||
view.innerHTML = `<section class="bh-briefing"><span class="bh-stamp">NEUE AKTE</span><span class="bh-kicker">${esc(session.examScope)} · ${esc(session.difficulty).toUpperCase()} · ${esc(session.language)}${session.variant ? ` · VARIANTE ${session.variant + 1}` : ''}</span><h1>${esc(session.title)}</h1><p>${esc(session.briefing)}</p><pre>${esc(session.consoleOutput)}</pre><div class="bh-rules"><div><b>1</b> Ort markieren</div><div><b>2</b> Fehler einordnen</div><div><b>3</b> sauberen Fix wählen</div></div><button class="bh-btn primary" id="bhStart">ERMITTLUNG STARTEN</button></section>`;
|
||||
document.getElementById('bhStart').addEventListener('click', () => { selectedFile = session.files[0]?.filename || ''; selectedLine = 0; selected = ''; options = []; renderHunt(); });
|
||||
}
|
||||
function activePhase() { const s = state(); return !s.locate?.done ? 'locate' : !s.classify?.done ? 'classify' : 'fix'; }
|
||||
@@ -83,7 +85,7 @@
|
||||
function finish() { post('/finish', {slug:session.slug, durationSeconds:seconds(), items:answers.map((answer, i) => ({bugId:session.bugs[i].bugId, locate:strip(answer.locate), classify:strip(answer.classify), fix:strip(answer.fix)}))}).then(renderResult).catch(error); }
|
||||
function strip(value) { return value ? {submission:value.submission, attempts:value.attempts, revealed:!!value.revealed} : null; }
|
||||
function comboText() { let combo = 0; for (let i = 0; i < index; i++) { const a = answers[i]; const clean = ['locate','classify','fix'].every(key => a[key] && a[key].attempts === 1 && !a[key].revealed); combo = clean ? combo + 1 : 0; } return `×${combo}`; }
|
||||
function renderResult(result) { view.innerHTML = `<section class="bh-result"><span class="bh-stamp">ERMITTLUNG ABGESCHLOSSEN</span><h1>Fallakten geschlossen.</h1><div class="bh-score">${result.score}</div><p class="bh-stars">${'★'.repeat(result.stars)}${'☆'.repeat(3-result.stars)}</p><div class="bh-stats"><div><b>${result.baseScore}</b>Basis</div><div><b>+${result.comboBonus}</b>Combo</div><div><b>${result.bugsSolved}/${result.totalBugs}</b>gelöst</div><div><b>×${result.maxCombo}</b>Serie</div><div><b>${result.highscore}</b>Highscore</div><div><b>${result.plays}</b>Akten</div></div><button class="bh-btn primary" id="bhAgain">WEITERE FÄLLE</button></section>`; document.getElementById('bhAgain').addEventListener('click', loadCatalog); }
|
||||
function renderResult(result) { view.innerHTML = `<section class="bh-result">${result.cleanSolve ? '<span class="bh-solved-stamp bh-solved-stamp-result">GELÖST</span>' : ''}<span class="bh-stamp">ERMITTLUNG ABGESCHLOSSEN</span><h1>${result.cleanSolve ? 'Fall fehlerfrei geschlossen.' : 'Fallakten geschlossen.'}</h1><div class="bh-score">${result.score}</div><p class="bh-stars">${'★'.repeat(result.stars)}${'☆'.repeat(3-result.stars)}</p><div class="bh-stats"><div><b>${result.baseScore}</b>Basis</div><div><b>+${result.comboBonus}</b>Combo</div><div><b>${result.bugsSolved}/${result.totalBugs}</b>gelöst</div><div><b>×${result.maxCombo}</b>Serie</div><div><b>${result.highscore}</b>Highscore</div><div><b>${result.plays}</b>Akten</div></div><button class="bh-btn primary" id="bhAgain">WEITERE FÄLLE</button></section>`; document.getElementById('bhAgain').addEventListener('click', loadCatalog); }
|
||||
function feedback(message, type) { const target = document.getElementById('bhFeedback'); if (target) { target.textContent = message; target.className = 'bh-feedback ' + type; } }
|
||||
function error(err) { view.innerHTML = `<section class="bh-result"><h1>AKTE NICHT LESBAR</h1><p>${esc(err.message || err)}</p><button class="bh-btn" id="bhReload">ERNEUT VERSUCHEN</button></section>`; document.getElementById('bhReload').addEventListener('click', loadCatalog); }
|
||||
loadCatalog();
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
document.head.appendChild(accessibilityCss);
|
||||
var accessibilityPlacementCss = document.createElement('link');
|
||||
accessibilityPlacementCss.rel = 'stylesheet';
|
||||
accessibilityPlacementCss.href = '/css/accessibility-placement.css?v=4';
|
||||
accessibilityPlacementCss.href = '/css/accessibility-placement.css?v=5';
|
||||
accessibilityPlacementCss.setAttribute('data-accessibility', '');
|
||||
document.head.appendChild(accessibilityPlacementCss);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user