diff --git a/app/static/script.js b/app/static/script.js index 8119a6c..0d477c5 100644 --- a/app/static/script.js +++ b/app/static/script.js @@ -1,79 +1,92 @@ -let currentMode = 'random'; +let mainMode = null; // 'vocab' oder 'irregular' +let subMode = null; // 'de-en', 'start-german', etc. let selectedPages = []; let currentCard = null; -let attempts = 0; let stats = { correct: 0, total: 0 }; -document.addEventListener('DOMContentLoaded', () => { - fetchPages(); - - // Enter-Taste für alle Inputs - const inputs = ['answer-input', 'input-simple', 'input-participle']; - inputs.forEach(id => { - const el = document.getElementById(id); - if (el) { - el.addEventListener('keypress', function (e) { - if (e.key === 'Enter') { - if (document.getElementById('next-btn').style.display !== 'none') { - nextQuestion(); - } else { - checkAnswer(); - } - } - }); - } - }); -}); +// --- SETUP LOGIC --- -function setMode(mode) { - currentMode = mode; - document.querySelectorAll('.mode-select button').forEach(b => b.classList.remove('active')); - document.getElementById(`btn-${mode}`).classList.add('active'); +function selectMainMode(mode) { + mainMode = mode; + subMode = null; // Reset submode + + // UI Updates + document.querySelectorAll('.mode-btn').forEach(b => b.classList.remove('active')); + document.getElementById(`btn-main-${mode}`).classList.add('active'); + + // Hide all submodes first + document.querySelectorAll('.submode-container').forEach(el => el.style.display = 'none'); + + // Show correct submode + document.getElementById(`submode-${mode}`).style.display = 'block'; + + // Hide Start & Pages until submode selected + document.getElementById('page-section').style.display = 'none'; + + // Reset Submode buttons + document.querySelectorAll('.sub-btn').forEach(b => b.classList.remove('active')); + + // Fetch pages for this mode immediately + fetchPages(mode); } -function fetchPages() { - fetch('/api/pages') +function selectSubMode(mode) { + subMode = mode; + + document.querySelectorAll('.sub-btn').forEach(b => b.classList.remove('active')); + document.getElementById(`btn-sub-${mode}`).classList.add('active'); + + // Now show page selection and start button + document.getElementById('page-section').style.display = 'block'; + document.getElementById('btn-start').disabled = false; + document.getElementById('btn-start').style.opacity = '1'; +} + +function fetchPages(type) { + fetch(`/api/pages?type=${type}`) .then(res => res.json()) .then(pages => { const list = document.getElementById('page-list'); - if(list) { - list.innerHTML = ''; - pages.forEach(p => { - const div = document.createElement('div'); - div.className = 'page-item'; - div.innerHTML = ` - - - `; - list.appendChild(div); - }); - } - }) - .catch(err => console.error("Fehler beim Laden der Seiten:", err)); + list.innerHTML = ''; + + // Auto-select logic: Select all by default + selectedPages = pages; + updatePageDisplay(); + + pages.forEach(p => { + const div = document.createElement('div'); + div.className = 'page-item'; + div.innerHTML = ` + + + `; + list.appendChild(div); + }); + }); } function updatePageSelection() { const checkboxes = document.querySelectorAll('#page-list input:checked'); selectedPages = Array.from(checkboxes).map(cb => parseInt(cb.value)); - - const display = document.getElementById('selected-pages-display'); - if (selectedPages.length === 0) display.innerText = "Alle Seiten"; - else display.innerText = `Seiten: ${selectedPages.join(', ')}`; + updatePageDisplay(); } -function openPageOverlay() { - const overlay = document.getElementById('overlay'); - if(overlay) overlay.style.display = 'flex'; +function updatePageDisplay() { + const d = document.getElementById('selected-pages-display'); + if (selectedPages.length === 0) { + d.innerText = "Keine Seiten gewählt!"; + document.getElementById('btn-start').disabled = true; + } else { + d.innerText = `Seiten: ${selectedPages.join(', ')}`; + if (subMode) document.getElementById('btn-start').disabled = false; + } } -function closeOverlay() { - const overlay = document.getElementById('overlay'); - if(overlay) overlay.style.display = 'none'; -} +// --- QUIZ LOGIC --- function startQuiz() { stats = { correct: 0, total: 0 }; - updateProgress(); + updateStats(); document.getElementById('setup-screen').style.display = 'none'; document.getElementById('quiz-screen').style.display = 'flex'; nextQuestion(); @@ -81,156 +94,138 @@ function startQuiz() { function stopQuiz() { document.getElementById('quiz-screen').style.display = 'none'; - document.getElementById('setup-screen').style.display = 'flex'; - fetchPages(); + document.getElementById('setup-screen').style.display = 'block'; } function nextQuestion() { - document.getElementById('check-btn').style.display = 'inline-block'; - document.getElementById('next-btn').style.display = 'none'; - const feedback = document.getElementById('feedback-msg'); - feedback.innerText = ''; - feedback.className = ''; + // UI Reset + document.getElementById('btn-check').style.display = 'block'; + document.getElementById('btn-next').style.display = 'none'; + document.getElementById('feedback').innerText = ''; + document.getElementById('feedback').className = 'feedback'; - // Inputs leeren - document.getElementById('answer-input').value = ''; - document.getElementById('input-simple').value = ''; - document.getElementById('input-participle').value = ''; - - attempts = 0; + // Clear Inputs + document.querySelectorAll('input').forEach(i => i.value = ''); - // Abfrage an Backend fetch('/api/question', { method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ mode: currentMode, pages: selectedPages }) + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({ mainMode, subMode, pages: selectedPages }) }) .then(res => res.json()) .then(data => { - if (data.error) { - alert(data.error); - stopQuiz(); - return; - } + if(data.error) { alert(data.error); stopQuiz(); return; } currentCard = data; renderCard(data); - }) - .catch(err => { - console.error(err); - alert("Fehler beim Laden der Frage."); - stopQuiz(); }); } function renderCard(card) { - const label = document.getElementById('question-label'); - const text = document.getElementById('question-text'); - const hint = document.getElementById('hint-text'); + const lbl = document.getElementById('q-label'); + const txt = document.getElementById('q-text'); + const hint = document.getElementById('q-hint'); - const standardInput = document.getElementById('answer-input'); - const verbInputs = document.getElementById('verb-inputs'); + const inpStd = document.getElementById('inp-standard'); + const boxVerbs = document.getElementById('verb-inputs'); + const inpInf = document.getElementById('inp-inf'); + + hint.innerText = ''; - if(hint) hint.innerText = ''; - - if (card.type === 'irregular') { - // UI für Verben - label.innerText = 'Bilde Simple Past & Past Participle:'; - text.innerText = `to ${card.question}`; - if(hint) hint.innerText = `(Deutsch: ${card.german_hint})`; + if (card.type === 'vocab') { + lbl.innerText = 'Übersetze:'; + txt.innerText = card.question; + inpStd.style.display = 'block'; + boxVerbs.style.display = 'none'; + inpStd.focus(); + } + else if (card.type === 'irregular_standard') { + lbl.innerText = 'Unregelmäßiges Verb:'; + txt.innerText = `to ${card.question}`; + hint.innerText = `(Deutsch: ${card.german_hint})`; - standardInput.style.display = 'none'; - verbInputs.style.display = 'flex'; - document.getElementById('input-simple').focus(); - } else { - // UI für normale Vokabeln - label.innerText = 'Übersetze:'; - text.innerText = card.question; + inpStd.style.display = 'none'; + boxVerbs.style.display = 'flex'; + inpInf.style.display = 'none'; // Infinitiv ist gegeben + document.getElementById('inp-simple').focus(); + } + else if (card.type === 'irregular_full') { + lbl.innerText = 'Unregelmäßiges Verb (Alle Formen):'; + txt.innerText = card.question; // Deutsch - standardInput.style.display = 'block'; - verbInputs.style.display = 'none'; - standardInput.focus(); + inpStd.style.display = 'none'; + boxVerbs.style.display = 'flex'; + inpInf.style.display = 'block'; // Muss eingegeben werden + inpInf.focus(); } } function checkAnswer() { - const feedback = document.getElementById('feedback-msg'); - - let payload = {}; - - if (currentCard.type === 'irregular') { - payload = { - type: 'irregular', - input_simple: document.getElementById('input-simple').value, - input_participle: document.getElementById('input-participle').value, - correct_simple: currentCard.answer_simple, - correct_participle: currentCard.answer_participle - }; + let payload = { type: currentCard.type }; + + if (currentCard.type === 'vocab') { + payload.input = document.getElementById('inp-standard').value; + payload.correct = currentCard.answer; } else { - payload = { - type: 'vocab', - input: document.getElementById('answer-input').value, - correct: currentCard.answer - }; + // Verben + payload.simple = document.getElementById('inp-simple').value; + payload.participle = document.getElementById('inp-part').value; + payload.correct_simple = currentCard.answer_simple; + payload.correct_participle = currentCard.answer_participle; + + if (currentCard.type === 'irregular_full') { + payload.infinitive = document.getElementById('inp-inf').value; + payload.correct_infinitive = currentCard.answer_infinitive; + } } fetch('/api/check', { method: 'POST', - headers: { 'Content-Type': 'application/json' }, + headers: {'Content-Type': 'application/json'}, body: JSON.stringify(payload) }) .then(res => res.json()) .then(res => { + const fb = document.getElementById('feedback'); + fb.innerText = res.msg; + if (res.status === 'correct') { - feedback.innerText = res.msg; - feedback.classList.add('msg-correct'); - document.getElementById('check-btn').style.display = 'none'; - document.getElementById('next-btn').style.display = 'inline-block'; - document.getElementById('next-btn').focus(); + fb.classList.add('correct'); stats.correct++; - stats.total++; - updateProgress(); + finishTurn(); } else if (res.status === 'typo') { - feedback.innerText = res.msg; - feedback.classList.add('msg-typo'); - attempts++; - checkAttempts(); + fb.classList.add('typo'); + // Darf nochmal probieren } else { - feedback.innerText = res.msg; - feedback.classList.add('msg-wrong'); - attempts++; - checkAttempts(); + fb.classList.add('wrong'); + finishTurn(); } }); } -function checkAttempts() { - if (attempts >= 3) { - const feedback = document.getElementById('feedback-msg'); - if (currentCard.type === 'irregular') { - feedback.innerText = `Leider nicht geschafft. Lösung: ${currentCard.answer_simple} | ${currentCard.answer_participle}`; - } else { - feedback.innerText = `Leider nicht geschafft. Lösung: ${currentCard.answer}`; - } - document.getElementById('check-btn').style.display = 'none'; - document.getElementById('next-btn').style.display = 'inline-block'; - stats.total++; - updateProgress(); - } +function finishTurn() { + stats.total++; + updateStats(); + document.getElementById('btn-check').style.display = 'none'; + document.getElementById('btn-next').style.display = 'block'; + document.getElementById('btn-next').focus(); } -function updateProgress() { - let percent = 0; - if (stats.total > 0) { - percent = Math.round((stats.correct / stats.total) * 100); +function updateStats() { + let p = 0; + if (stats.total > 0) p = Math.round((stats.correct / stats.total) * 100); + document.getElementById('progress-bar').style.width = `${p}%`; + document.getElementById('stats-text').innerText = `${p}% Richtig (${stats.correct}/${stats.total})`; +} + +// Enter Key Handler +document.addEventListener('keypress', (e) => { + if (e.key === 'Enter') { + const nextBtn = document.getElementById('btn-next'); + if (nextBtn.style.display !== 'none') nextQuestion(); + else checkAnswer(); } - const text = document.getElementById('progress-text'); - const bar = document.getElementById('progress-bar'); - - text.innerText = `${percent}% Richtig (${stats.correct}/${stats.total})`; - bar.style.width = `${percent}%`; - - if (percent < 50) bar.style.backgroundColor = '#dc3545'; - else if (percent < 65) bar.style.backgroundColor = '#f08080'; - else if (percent < 85) bar.style.backgroundColor = '#ffc107'; - else bar.style.backgroundColor = '#28a745'; -} \ No newline at end of file +}); + +// Overlay Logic +function openPageOverlay() { document.getElementById('overlay').style.display = 'flex'; } +function closeOverlay() { document.getElementById('overlay').style.display = 'none'; } \ No newline at end of file