feat: Add lore pack, UI adjustments, requirements.txt and INSTALL.md

This commit is contained in:
kobold-ai
2026-10-29 08:51:28 +01:00
parent fb789e8866
commit 6c62676d0d
14 changed files with 3281 additions and 2725 deletions
+9 -3
View File
@@ -225,9 +225,15 @@
<div class="form-group">
<label for="category">Kategorie:</label>
<select name="category" id="category" class="input-text">
<option value="harry_potter" selected>Harry Potter / Escape</option>
<option value="insider">Persönlich / Insider</option>
<option value="general">Allgemeines Rätsel</option>
<option value="books">📖 Buchwissen</option>
<option value="movies">🎬 Filmwissen</option>
<option value="creatures">🐉 Magische Geschöpfe</option>
<option value="spells">🪄 Zaubersprüche & Tränke</option>
<option value="characters" selected>🧙‍♂️ Charaktere</option>
<option value="hogwarts">🏰 Hogwarts & Orte</option>
<option value="quidditch">🧹 Quidditch</option>
<option value="lore">🔮 Artefakte & Lore</option>
<option value="general">⚡ Allgemein</option>
</select>
</div>
+117 -167
View File
@@ -1,167 +1,117 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
<title>{% block title %}Magisches Harry-Potter-Escape-Quiz{% endblock %}</title>
<link rel="icon" href="/static/favicon.ico">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Caveat:wght@500;700&family=Marck+Script&family=MedievalSharp&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/static/css/style.css?v=3.5">
{% block head %}{% endblock %}
</head>
<body>
<audio id="bgm" src="/static/audio/music.mp3" loop preload="auto"></audio>
<header class="site-header">
<div class="header-inner">
<a href="/" class="brand-link">
<span class="brand-sparkle">⚡</span>
<span class="brand-title">Hogwarts Quiz</span>
</a>
<div class="header-right">
<div class="lang-switch-group" role="group" aria-label="Sprachauswahl / Language">
<button type="button" id="langDe" class="lang-btn active" onclick="setLanguage('de')" title="Deutsch">🇩🇪 DE</button>
<button type="button" id="langEn" class="lang-btn" onclick="setLanguage('en')" title="English">🇬🇧 EN</button>
</div>
<button id="audioToggle" class="audio-btn" title="Musik an/aus" onclick="toggleAudio()">
<span id="audioIcon">🔇</span>
<span id="audioText" class="audio-label">Musik: Aus</span>
</button>
<button id="menuToggle" class="menu-toggle-btn" aria-label="Menü öffnen" onclick="toggleMobileMenu()">
<span id="menuIcon">☰</span>
</button>
</div>
<nav id="navLinks" class="nav-links">
<a href="/" class="nav-link" id="navQuiz" onclick="closeMobileMenu()">✨ Zum Quiz</a>
<a href="https://bootle.dev.waiswuaschd.de" class="nav-link" id="navEscape" target="_blank" rel="noopener">🧪 Escape Adventure</a>
<a href="/bestenliste" class="nav-link" id="navLeaderboard" onclick="closeMobileMenu()">🏆 Bestenliste</a>
<a href="/vorschlag" class="nav-link" id="navSuggest" onclick="closeMobileMenu()">✍️ Frage einreichen</a>
<a href="/admin" class="nav-link" id="navAdmin" onclick="closeMobileMenu()">🔒 Admin-Cockpit</a>
</nav>
</div>
</header>
<main class="container">
{% block content %}{% endblock %}
</main>
<footer class="footer">
<p id="footerText">⚡ Magisches Hogwarts-Escape-Quiz · Betrieben mit Liebe & Zauberkraft ⚡</p>
<div class="footer-links">
<a href="/impressum" class="footer-link" id="footerImpressum">⚖️ Impressum</a>
<span class="footer-sep">·</span>
<a href="/datenschutz" class="footer-link" id="footerDatenschutz">🛡️ Datenschutz</a>
</div>
</footer>
<script>
const bgm = document.getElementById("bgm");
const audioIcon = document.getElementById("audioIcon");
const audioText = document.getElementById("audioText");
const navLinks = document.getElementById("navLinks");
const menuIcon = document.getElementById("menuIcon");
let currentLang = localStorage.getItem("quiz_lang") || "de";
function setLanguage(lang) {
currentLang = (lang === "en") ? "en" : "de";
localStorage.setItem("quiz_lang", currentLang);
document.documentElement.lang = currentLang;
updateLanguageUI();
if (typeof onLanguageChange === "function") {
onLanguageChange(currentLang);
}
}
function updateLanguageUI() {
const isDe = currentLang === "de";
const deBtn = document.getElementById("langDe");
const enBtn = document.getElementById("langEn");
if (deBtn && enBtn) {
deBtn.classList.toggle("active", isDe);
enBtn.classList.toggle("active", !isDe);
}
const navQuiz = document.getElementById("navQuiz");
const navLeaderboard = document.getElementById("navLeaderboard");
const navSuggest = document.getElementById("navSuggest");
const navAdmin = document.getElementById("navAdmin");
const footerText = document.getElementById("footerText");
const footerImpressum = document.getElementById("footerImpressum");
const footerDatenschutz = document.getElementById("footerDatenschutz");
if (navQuiz) navQuiz.innerText = isDe ? "✨ Zum Quiz" : "✨ To Quiz";
if (navLeaderboard) navLeaderboard.innerText = isDe ? "🏆 Bestenliste" : "🏆 Leaderboard";
if (navSuggest) navSuggest.innerText = isDe ? "✍️ Frage einreichen" : "✍️ Submit Question";
if (navAdmin) navAdmin.innerText = isDe ? "🔒 Admin-Cockpit" : "🔒 Admin Cockpit";
if (footerText) {
footerText.innerText = isDe
? "⚡ Magisches Hogwarts-Escape-Quiz · Betrieben mit Liebe & Zauberkraft ⚡"
: "⚡ Magical Hogwarts Escape Quiz · Powered by Love & Wizardry ⚡";
}
if (footerImpressum) footerImpressum.innerText = isDe ? "⚖️ Impressum" : "⚖️ Legal Notice";
if (footerDatenschutz) footerDatenschutz.innerText = isDe ? "🛡️ Datenschutz" : "🛡️ Privacy Policy";
if (audioText) {
const isPlaying = bgm && !bgm.paused;
if (isDe) {
audioText.innerText = isPlaying ? "Musik: An" : "Musik: Aus";
} else {
audioText.innerText = isPlaying ? "Music: On" : "Music: Off";
}
}
}
function toggleAudio() {
const isDe = currentLang === "de";
if (bgm.paused) {
bgm.play().then(() => {
audioIcon.innerText = "🔊";
audioText.innerText = isDe ? "Musik: An" : "Music: On";
localStorage.setItem("bgm_enabled", "true");
}).catch(err => {
console.log("Audio play blocked:", err);
});
} else {
bgm.pause();
audioIcon.innerText = "🔇";
audioText.innerText = isDe ? "Musik: Aus" : "Music: Off";
localStorage.setItem("bgm_enabled", "false");
}
}
function toggleMobileMenu() {
const isOpen = navLinks.classList.toggle("nav-open");
menuIcon.innerText = isOpen ? "✕" : "☰";
}
function closeMobileMenu() {
navLinks.classList.remove("nav-open");
menuIcon.innerText = "☰";
}
// Auto-resume audio if previously enabled
document.addEventListener("click", function initAudioOnInteraction() {
if (localStorage.getItem("bgm_enabled") === "true" && bgm.paused) {
bgm.play().then(() => {
audioIcon.innerText = "🔊";
audioText.innerText = (currentLang === "de") ? "Musik: An" : "Music: On";
}).catch(() => {});
}
document.removeEventListener("click", initAudioOnInteraction);
}, { once: true });
// Initialize UI on load
document.addEventListener("DOMContentLoaded", () => {
updateLanguageUI();
});
</script>
{% block scripts %}{% endblock %}
</body>
</html>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
<title>{% block title %}PotterTrivia – Das Harry-Potter-Wissensquiz{% endblock %}</title>
<link rel="icon" href="/static/favicon.ico">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/static/css/style.css?v=4.0">
{% block head %}{% endblock %}
</head>
<body>
<header class="site-header">
<div class="header-inner">
<a href="/" class="brand-link">
<span class="brand-badge">⚡</span>
<span class="brand-title">Potter<span class="brand-accent">Trivia</span></span>
</a>
<nav id="navLinks" class="nav-links">
<a href="/" class="nav-link" id="navQuiz" onclick="closeMobileMenu()">🎯 Quiz</a>
<a href="/bestenliste" class="nav-link" id="navLeaderboard" onclick="closeMobileMenu()">🏆 Bestenliste</a>
<a href="/vorschlag" class="nav-link" id="navSuggest" onclick="closeMobileMenu()">✍️ Frage einreichen</a>
<a href="/admin" class="nav-link" id="navAdmin" onclick="closeMobileMenu()">⚙️ Admin</a>
</nav>
<div class="header-right">
<div class="lang-switch-group" role="group" aria-label="Sprachauswahl / Language">
<button type="button" id="langDe" class="lang-btn active" onclick="setLanguage('de')" title="Deutsch">🇩🇪 DE</button>
<button type="button" id="langEn" class="lang-btn" onclick="setLanguage('en')" title="English">🇬🇧 EN</button>
</div>
<button id="menuToggle" class="menu-toggle-btn" aria-label="Menü öffnen" onclick="toggleMobileMenu()">
<span id="menuIcon">☰</span>
</button>
</div>
</div>
</header>
<main class="container">
{% block content %}{% endblock %}
</main>
<footer class="footer">
<p id="footerText">⚡ PotterTrivia · Das unabhängige Harry-Potter-Wissensquiz</p>
<div class="footer-links">
<a href="/impressum" class="footer-link" id="footerImpressum">⚖️ Impressum</a>
<span class="footer-sep">·</span>
<a href="/datenschutz" class="footer-link" id="footerDatenschutz">🛡️ Datenschutz</a>
</div>
</footer>
<script>
const navLinks = document.getElementById("navLinks");
const menuIcon = document.getElementById("menuIcon");
let currentLang = localStorage.getItem("quiz_lang") || "de";
function setLanguage(lang) {
currentLang = (lang === "en") ? "en" : "de";
localStorage.setItem("quiz_lang", currentLang);
document.documentElement.lang = currentLang;
updateLanguageUI();
if (typeof onLanguageChange === "function") {
onLanguageChange(currentLang);
}
}
function updateLanguageUI() {
const isDe = currentLang === "de";
const deBtn = document.getElementById("langDe");
const enBtn = document.getElementById("langEn");
if (deBtn && enBtn) {
deBtn.classList.toggle("active", isDe);
enBtn.classList.toggle("active", !isDe);
}
const navQuiz = document.getElementById("navQuiz");
const navLeaderboard = document.getElementById("navLeaderboard");
const navSuggest = document.getElementById("navSuggest");
const navAdmin = document.getElementById("navAdmin");
const footerText = document.getElementById("footerText");
const footerImpressum = document.getElementById("footerImpressum");
const footerDatenschutz = document.getElementById("footerDatenschutz");
if (navQuiz) navQuiz.innerText = isDe ? "🎯 Quiz" : "🎯 Quiz";
if (navLeaderboard) navLeaderboard.innerText = isDe ? "🏆 Bestenliste" : "🏆 Leaderboard";
if (navSuggest) navSuggest.innerText = isDe ? "✍️ Frage einreichen" : "✍️ Submit Question";
if (navAdmin) navAdmin.innerText = isDe ? "⚙️ Admin" : "⚙️ Admin";
if (footerText) {
footerText.innerText = isDe
? "⚡ PotterTrivia · Das unabhängige Harry-Potter-Wissensquiz"
: "⚡ PotterTrivia · The Independent Wizarding World Trivia Quiz";
}
if (footerImpressum) footerImpressum.innerText = isDe ? "⚖️ Impressum" : "⚖️ Legal Notice";
if (footerDatenschutz) footerDatenschutz.innerText = isDe ? "🛡️ Datenschutz" : "🛡️ Privacy Policy";
}
function toggleMobileMenu() {
const isOpen = navLinks.classList.toggle("nav-open");
menuIcon.innerText = isOpen ? "✕" : "☰";
}
function closeMobileMenu() {
navLinks.classList.remove("nav-open");
menuIcon.innerText = "☰";
}
document.addEventListener("DOMContentLoaded", () => {
updateLanguageUI();
});
</script>
{% block scripts %}{% endblock %}
</body>
</html>
+160 -174
View File
@@ -1,174 +1,160 @@
{% extends "base.html" %}
{% block title %}✨ Magisches Harry-Potter-Escape-Quiz ✨{% endblock %}
{% block content %}
<div class="quiz-wrapper">
<header class="quiz-header">
<h1 class="glow-title" id="pageTitle">✨ Magisches Hogwarts-Escape-Quiz ✨</h1>
<p class="subtitle" id="pageSubtitle">10 knifflige Rätsel aus der Zauberwelt warten auf dich</p>
</header>
<!-- Brief-Intro / Startmaske -->
<div id="introCard" class="card intro-card intro-parchment-wrapper">
<!-- Antiker geschlossener Hogwarts-Umschlag (öffnet sich bei Klick auf das Siegel) -->
<div class="antique-envelope-scene" id="envelope">
<div class="envelope-base">
<!-- Dunkleres Pergament-Innenfutter -->
<div class="envelope-interior"></div>
<!-- Der darin liegende Briefbogen (gleitet beim Öffnen majestätisch hervor) -->
<div class="letter-sheet" id="letterSheet">
<div class="sheet-parchment-layer"></div>
<header class="letter-header">
<div class="letter-crest-box">
<img src="/static/img/hogwarts_seal.jpg" alt="Hogwarts Crest" class="letter-crest-sketch">
</div>
<h3 class="letter-school-name" id="letterSchoolTitle">Hogwarts-Schule für Hexerei und Zauberei</h3>
<p class="letter-headmaster" id="letterHeadmaster">Schulleiter: Albus Dumbledore<br><span>(Großhexenmeister, Träger des Merlin-Ordens 1. Klasse)</span></p>
<div class="letter-ornament-line">
<span class="ornament-leaf">❦</span>
<span class="ornament-rule"></span>
<span class="ornament-shield">✦</span>
<span class="ornament-rule"></span>
<span class="ornament-leaf">❧</span>
</div>
</header>
<div class="letter-body-handwritten">
<p class="letter-salutation" id="letterSalutation">Liebe Hexe, lieber Zauberer,</p>
<p class="letter-paragraph" id="letterParagraph1">
wir freuen uns, dir mitteilen zu dürfen, dass du zu den <strong>Magischen Z.A.G.-Prüfungen</strong> an der Hogwarts-Schule zugelassen bist.
</p>
<p class="letter-paragraph" id="letterParagraph2">
Zehn anspruchsvolle Prüfungsfragen entscheiden über deinen Rang in den Chroniken. Zeige deinen Scharfsinn und sichere bis zu <strong>1.000 Hauspunkte</strong> für dein Haus!
</p>
</div>
<footer class="letter-signature-block">
<p class="letter-closing" id="letterClosing">Mit vorzüglicher Hochachtung,</p>
<p class="letter-signature-ink" id="letterSignature">Minerva McGonagall</p>
<p class="letter-sign-title" id="letterSignTitle">Stellvertretende Schulleiterin</p>
</footer>
</div>
<!-- Vordere Umschlagtasche mit handschriftlicher Smaragd-Anschrift -->
<div class="envelope-front-pocket">
<div class="envelope-sketch-border"></div>
<div class="envelope-address-block">
<p class="addr-line addr-school" id="envelopeLetter">Hogwarts-Schule für Hexerei und Zauberei</p>
<p class="addr-line addr-recipient" id="envelopeRecipient">An den ehrenwerten Zauberschüler</p>
<p class="addr-line addr-location" id="envelopeLocation">Auf dem Prüfungspfad • Schloss Hogwarts</p>
</div>
</div>
<!-- Obere Klappe des Umschlags (überdeckt die Tasche und wird vom Siegel gehalten) -->
<div class="envelope-closing-flap">
<div class="flap-sketch-line"></div>
</div>
<!-- Handgezeichnetes Wachssiegel über der Klappenspitze -->
<div class="sketched-wax-seal" id="waxSeal" onclick="startGame()" title="Siegel brechen & Brief öffnen">
<img src="/static/img/hogwarts_seal.jpg" alt="Hogwarts-Wappen Siegel" class="seal-crest-img">
<div class="seal-emboss-ring"></div>
<div class="seal-glow"></div>
</div>
</div>
</div>
<!-- Auswahlbereich unter dem Pergament -->
<div class="intro-content intro-controls-panel">
<p class="intro-subnote" id="introDesc">
Ein verzauberter Pergamentbrief aus Hogwarts liegt vor dir.<br>
Wähle deinen Schwierigkeitsgrad und brich das rote Zaubersiegel:
</p>
<!-- Difficulty Selector Chips -->
<div class="difficulty-selection">
<span class="difficulty-label" id="diffLabel">Schwierigkeitsgrad wählen:</span>
<div class="difficulty-chips" role="radiogroup" aria-label="Schwierigkeitsgrad">
<button type="button" class="diff-chip active" data-diff="all" onclick="selectDifficulty('all')">
<span class="diff-icon">🎲</span> <span class="diff-text" id="diffAllText">Alle gemischt</span>
</button>
<button type="button" class="diff-chip" data-diff="easy" onclick="selectDifficulty('easy')">
<span class="diff-icon">🟢</span> <span class="diff-text" id="diffEasyText">Leicht</span>
</button>
<button type="button" class="diff-chip" data-diff="medium" onclick="selectDifficulty('medium')">
<span class="diff-icon">🟡</span> <span class="diff-text" id="diffMedText">Mittel</span>
</button>
<button type="button" class="diff-chip" data-diff="hard" onclick="selectDifficulty('hard')">
<span class="diff-icon">🔴</span> <span class="diff-text" id="diffHardText">Schwer</span>
</button>
</div>
</div>
<button id="startBtn" class="btn btn-primary btn-large btn-break-seal" onclick="startGame()">
📜 Siegel brechen & Brief öffnen
</button>
</div>
</div>
<!-- Spielbereich (initial versteckt) -->
<div id="gameCard" class="game-area hidden">
<!-- Fortschritt & Punkte & Zeit -->
<div class="status-panel">
<div class="progress-info">
<span id="questionCounter">Frage 1 von 10</span>
<span id="timerBadge" class="timer-badge">⏱️ 00:00</span>
<span id="pointsCounter" class="points-badge">🏆 Hauspunkte: 0</span>
</div>
<div class="progress-container">
<div id="progressBar" class="progress-bar"></div>
</div>
</div>
<!-- Frage-Container -->
<div id="frageBox" class="card question-card">
<div class="question-meta">
<div class="meta-left">
<span id="badgeCategory" class="badge">⚡ Harry Potter</span>
<span id="badgeDifficulty" class="badge badge-diff">🟢 Leicht</span>
</div>
<span id="attemptBadge" class="attempt-badge">Versuch 1 von 3</span>
</div>
<h2 id="frageText" class="question-text">Lade verzauberte Schriftrollen...</h2>
<!-- Freitext-Eingabe (wenn question_type == 'text') -->
<div id="textAnswerGroup" class="answer-form">
<input type="text" id="answerInput" class="input-answer" placeholder="Deine Antwort hier eingeben..." autocomplete="off">
<div class="btn-group">
<button id="checkBtn" class="btn btn-primary" onclick="checkAnswer()">
✨ Antwort prüfen
</button>
<button id="hintBtn" class="btn btn-secondary" onclick="requestHint()">
💡 Hinweis anzeigen
</button>
</div>
</div>
<!-- Multiple-Choice-Auswahl (wenn question_type == 'multiple_choice') -->
<div id="choiceAnswerGroup" class="choice-group hidden">
<div id="choiceOptionsContainer" class="choice-grid"></div>
<div class="btn-group" style="margin-top: 15px;">
<button id="hintBtnMC" class="btn btn-secondary" onclick="requestHint()">
💡 Hinweis anzeigen
</button>
</div>
</div>
<div id="hintBox" class="hint-box hidden">
<strong id="hintHeading">📜 Notiz aus der verbotenen Abteilung:</strong>
<p id="hintText"></p>
</div>
<div id="feedbackBox" class="feedback-box"></div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script src="/static/js/quiz.js?v=3.2"></script>
{% endblock %}
{% extends "base.html" %}
{% block title %}⚡ PotterTrivia – Das Harry-Potter-Wissensquiz{% endblock %}
{% block content %}
<div class="quiz-wrapper">
<header class="quiz-header">
<div class="hero-pill" id="heroPill">⚡ {{ question_count }} Fragen im Wissens-Pool · Buch & Film</div>
<h1 class="glow-title" id="pageTitle">Harry Potter Wissensquiz</h1>
<p class="subtitle" id="pageSubtitle">Teste dein Wissen über Bücher, Filme, Geschöpfe und Zaubersprüche – direkt & ohne Umwege.</p>
</header>
<!-- Kompaktes Direct-Start Dashboard -->
<div id="introCard" class="card start-dashboard-card">
<div class="dashboard-grid">
<!-- Sektion 1: Schwierigkeitsgrad -->
<div class="config-section">
<div class="config-header">
<span class="config-step">1</span>
<span class="difficulty-label" id="diffLabel">Schwierigkeitsgrad</span>
</div>
<div class="difficulty-chips" role="radiogroup" aria-label="Schwierigkeitsgrad">
<button type="button" class="diff-chip active" data-diff="all" onclick="selectDifficulty('all')">
<span class="diff-icon">🎲</span>
<span class="diff-text" id="diffAllText">Alle Stufen</span>
</button>
<button type="button" class="diff-chip" data-diff="easy" onclick="selectDifficulty('easy')">
<span class="diff-icon">🟢</span>
<span class="diff-text" id="diffEasyText">Leicht</span>
</button>
<button type="button" class="diff-chip" data-diff="medium" onclick="selectDifficulty('medium')">
<span class="diff-icon">🟡</span>
<span class="diff-text" id="diffMedText">Mittel</span>
</button>
<button type="button" class="diff-chip" data-diff="hard" onclick="selectDifficulty('hard')">
<span class="diff-icon">🔴</span>
<span class="diff-text" id="diffHardText">Schwer (Experte)</span>
</button>
</div>
</div>
<!-- Sektion 2: Kategorie-Filter -->
<div class="config-section">
<div class="config-header">
<span class="config-step">2</span>
<span class="difficulty-label" id="catLabel">Themengebiet wählen</span>
</div>
<div class="category-chips" role="radiogroup" aria-label="Themengebiet">
<button type="button" class="cat-chip active" data-cat="all" onclick="selectCategory('all')">
<span>✨</span> <span id="catAllText">Alle Kategorien</span>
</button>
<button type="button" class="cat-chip" data-cat="books" onclick="selectCategory('books')">
<span>📖</span> <span id="catBooksText">Buchwissen</span>
</button>
<button type="button" class="cat-chip" data-cat="movies" onclick="selectCategory('movies')">
<span>🎬</span> <span id="catMoviesText">Filmwissen</span>
</button>
<button type="button" class="cat-chip" data-cat="creatures" onclick="selectCategory('creatures')">
<span>🐉</span> <span id="catCreaturesText">Magische Geschöpfe</span>
</button>
<button type="button" class="cat-chip" data-cat="spells" onclick="selectCategory('spells')">
<span>🪄</span> <span id="catSpellsText">Zaubersprüche & Tränke</span>
</button>
<button type="button" class="cat-chip" data-cat="characters" onclick="selectCategory('characters')">
<span>🧙‍♂️</span> <span id="catCharsText">Charaktere</span>
</button>
<button type="button" class="cat-chip" data-cat="hogwarts" onclick="selectCategory('hogwarts')">
<span>🏰</span> <span id="catHogwartsText">Hogwarts & Orte</span>
</button>
<button type="button" class="cat-chip" data-cat="quidditch" onclick="selectCategory('quidditch')">
<span>🧹</span> <span id="catQuidditchText">Quidditch</span>
</button>
<button type="button" class="cat-chip" data-cat="lore" onclick="selectCategory('lore')">
<span>🔮</span> <span id="catLoreText">Artefakte & Lore</span>
</button>
</div>
</div>
</div>
<div class="dashboard-footer">
<div class="dashboard-rules" id="dashboardRules">
<span>🎯 10 Fragen pro Runde</span>
<span>·</span>
<span>🔥 Streak-Zähler</span>
<span>·</span>
<span>💡 Bis zu 3 Versuche je Frage</span>
</div>
<button id="startQuizBtn" class="btn btn-primary btn-large btn-launch-quiz" onclick="startGame()">
⚡ Quiz jetzt starten ➔
</button>
</div>
</div>
<!-- Spielbereich (initial versteckt) -->
<div id="gameCard" class="game-area hidden">
<!-- HUD: Fortschritt, Streak, Zeit & Punkte -->
<div class="status-panel">
<div class="progress-info">
<span id="questionCounter" class="hud-pill">Frage 1 / 10</span>
<div class="hud-center-group">
<span id="streakBadge" class="streak-badge" title="Antwort-Serie in Folge">🔥 0</span>
<span id="timerBadge" class="timer-badge">⏱️ 00:00</span>
</div>
<span id="pointsCounter" class="points-badge">🏆 0 Pkt.</span>
</div>
<div class="progress-container">
<div id="progressBar" class="progress-bar"></div>
</div>
</div>
<!-- Frage-Container -->
<div id="frageBox" class="card question-card">
<div class="question-meta">
<div class="meta-left">
<span id="badgeCategory" class="badge">⚡ Allgemein</span>
<span id="badgeDifficulty" class="badge badge-diff">🟢 Leicht</span>
</div>
<span id="attemptBadge" class="attempt-badge">Versuch 1 / 3</span>
</div>
<h2 id="frageText" class="question-text">Lade nächste Frage...</h2>
<!-- Freitext-Eingabe (wenn question_type == 'text') -->
<div id="textAnswerGroup" class="answer-form">
<input type="text" id="answerInput" class="input-answer" placeholder="Deine Antwort eingeben..." autocomplete="off">
<div class="btn-group">
<button id="checkBtn" class="btn btn-primary" onclick="checkAnswer()">
✓ Antwort prüfen
</button>
<button id="hintBtn" class="btn btn-secondary" onclick="requestHint()">
💡 Tipp anzeigen
</button>
</div>
</div>
<!-- Multiple-Choice-Auswahl (wenn question_type == 'multiple_choice') -->
<div id="choiceAnswerGroup" class="choice-group hidden">
<div id="choiceOptionsContainer" class="choice-grid"></div>
<div class="btn-group" style="margin-top: 16px;">
<button id="hintBtnMC" class="btn btn-secondary" onclick="requestHint()">
💡 Tipp anzeigen
</button>
</div>
</div>
<div id="hintBox" class="hint-box hidden">
<strong id="hintHeading">💡 Hinweis:</strong>
<p id="hintText"></p>
</div>
<div id="feedbackBox" class="feedback-box"></div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script src="/static/js/quiz.js?v=4.0"></script>
{% endblock %}
+10 -8
View File
@@ -5,11 +5,11 @@
{% block content %}
<div class="quiz-wrapper">
<div class="card vorschlag-card">
<h1 class="glow-title" id="suggTitle">✨ Neue Frage für das Quiz vorschlagen ✨</h1>
<p class="subtitle" id="suggSubtitle">Bereichere das magische Quiz mit kniffligen Harry-Potter- oder Escape-Rätseln!</p>
<h1 class="glow-title" id="suggTitle">✍️ Neue Quiz-Frage einreichen</h1>
<p class="subtitle" id="suggSubtitle">Bereichere PotterTrivia mit deinen eigenen Fragen zu Büchern, Filmen oder magischen Geschöpfen!</p>
<div class="info-alert" id="suggAlert">
ℹ️ <strong>Hinweis zur Moderation:</strong> Eingereichte Fragen werden nicht sofort öffentlich sichtbar, sondern erhalten automatisch den Status <em>„Prüfung ausstehend“</em>. Unser Zaubereiministerium prüft und testet die Antwort, bevor die Frage freigeschaltet wird.
ℹ️ <strong>Hinweis zur Moderation:</strong> Eingereichte Fragen werden kurz auf Richtigkeit geprüft, bevor sie im öffentlichen Quiz-Pool freigeschaltet werden.
</div>
<form id="suggestionForm" class="magic-form" onsubmit="submitSuggestion(event)">
@@ -26,13 +26,15 @@
<div class="form-group">
<label for="kategorie" id="suggCatLabel">Kategorie / Themenbereich:</label>
<select id="kategorie" name="category" class="input-text">
<option value="hogwarts" id="catHogwarts">🏰 Hogwarts & Schulgelände</option>
<option value="characters" id="catCharacters" selected>🧙 Charaktere & Personen</option>
<option value="spells" id="catSpells">⚡ Zaubersprüche & Magie</option>
<option value="creatures" id="catCreatures">🐉 Magische Tierwesen</option>
<option value="books" id="catBooks">📖 Buchwissen (Buch-Details)</option>
<option value="movies" id="catMovies">🎬 Filmwissen (Kino & Drehorte)</option>
<option value="creatures" id="catCreatures">🐉 Magische Geschöpfe</option>
<option value="spells" id="catSpells">🪄 Zaubersprüche & Tränke</option>
<option value="characters" id="catCharacters" selected>🧙‍♂️ Charaktere & Personen</option>
<option value="hogwarts" id="catHogwarts">🏰 Hogwarts & Orte</option>
<option value="quidditch" id="catQuidditch">🧹 Quidditch & Sport</option>
<option value="lore" id="catLore">🔮 Artefakte & Geschichte</option>
<option value="general" id="catGeneral">📜 Allgemeines Zauberwissen</option>
<option value="general" id="catGeneral">⚡ Allgemeines Wissen</option>
</select>
</div>