252 lines
12 KiB
JavaScript
Executable File
252 lines
12 KiB
JavaScript
Executable File
const SUGGESTION_TEXT = {
|
||
de: {
|
||
title: "✍️ Neue Quiz-Frage einreichen",
|
||
subtitle: "Bereichere PotterTrivia mit deinen eigenen Fragen zu Büchern, Filmen oder magischen Geschöpfen!",
|
||
alert: "ℹ️ <strong>Hinweis zur Moderation:</strong> Eingereichte Fragen werden kurz auf Richtigkeit geprüft, bevor sie im öffentlichen Quiz-Pool freigeschaltet werden.",
|
||
nameLabel: "Dein Name / Alias (optional):",
|
||
namePlaceholder: "z. B. Hermine Granger",
|
||
catLabel: "Kategorie / Themenbereich:",
|
||
catBooks: "📖 Buchwissen (Buch-Details)",
|
||
catMovies: "🎬 Filmwissen (Kino & Drehorte)",
|
||
catHogwarts: "🏰 Hogwarts & Orte",
|
||
catCharacters: "🧙♂️ Charaktere & Personen",
|
||
catSpells: "🪄 Zaubersprüche & Tränke",
|
||
catCreatures: "🐉 Magische Geschöpfe",
|
||
catQuidditch: "🧹 Quidditch & Sport",
|
||
catLore: "🔮 Artefakte & Geschichte",
|
||
catGeneral: "⚡ Allgemeines Wissen",
|
||
frageLabel: "Deine Frage: *",
|
||
fragePlaceholder: "z. B. Wie heißt der Schulleiter von Hogwarts?",
|
||
diffLabel: "Schwierigkeitsgrad:",
|
||
typeLabel: "Art der Frage:",
|
||
optText: "🔤 Freitext-Antwort (Tippen mit Fehlertoleranz)",
|
||
optMC: "🔘 Multiple Choice (Auswahl aus 4 Antwortmöglichkeiten)",
|
||
antwortLabelText: "Richtige Antwort:",
|
||
antwortLabelMC: "Richtige Antwort (die korrekte Option):",
|
||
antwortHelpText: "Unser System gleicht Tippfehler und Groß-/Kleinschreibung automatisch ab.",
|
||
antwortHelpMC: "Diese Antwort wird zusammen mit den falschen Optionen zufällig für den Spieler angeordnet.",
|
||
wrongLabel: "Falsche Antwortmöglichkeiten (zur Auswahl für die Spieler):",
|
||
wrongPlaceholder1: "Falsche Option 1 (z. B. Severus Snape)",
|
||
wrongPlaceholder2: "Falsche Option 2 (z. B. Minerva McGonagall)",
|
||
wrongPlaceholder3: "Falsche Option 3 (z. B. Rubeus Hagrid)",
|
||
tippLabel: "Tipp / Hinweis (optional):",
|
||
tippPlaceholder: "z. B. Er trägt eine Halbmondbrille.",
|
||
submitBtn: "📜 Vorschlag an das Ministerium senden",
|
||
submitBtnCasting: "✨ Vorschlag wird übertragen...",
|
||
alertFillRequired: "Bitte gib mindestens die Frage und die richtige Antwort ein.",
|
||
alertMCRequired: "Bitte gib bei Multiple-Choice mindestens eine falsche Antwortmöglichkeit an.",
|
||
successHeader: "✨ Vorschlag erfolgreich übermittelt! ✨"
|
||
},
|
||
en: {
|
||
title: "✍️ Submit a New Quiz Question",
|
||
subtitle: "Enrich PotterTrivia with your own questions about the books, movies, or magical creatures!",
|
||
alert: "ℹ️ <strong>Moderation Note:</strong> Submitted questions are briefly reviewed for accuracy before going live in the public quiz pool.",
|
||
nameLabel: "Your Name / Alias (optional):",
|
||
namePlaceholder: "e.g. Hermione Granger",
|
||
catLabel: "Category / Topic Area:",
|
||
catBooks: "📖 Book Lore (Book Details)",
|
||
catMovies: "🎬 Movie Trivia (Cinema & Filming)",
|
||
catHogwarts: "🏰 Hogwarts & Places",
|
||
catCharacters: "🧙♂️ Characters & People",
|
||
catSpells: "🪄 Spells & Potions",
|
||
catCreatures: "🐉 Magical Creatures",
|
||
catQuidditch: "🧹 Quidditch & Sport",
|
||
catLore: "🔮 Artifacts & Lore",
|
||
catGeneral: "⚡ General Knowledge",
|
||
frageLabel: "Your Question: *",
|
||
fragePlaceholder: "e.g. Who is the Headmaster of Hogwarts?",
|
||
diffLabel: "Difficulty Level:",
|
||
typeLabel: "Question Type:",
|
||
optText: "🔤 Free-Text Input (with typo tolerance)",
|
||
optMC: "🔘 Multiple Choice (Selection of 4 options)",
|
||
antwortLabelText: "Correct Answer:",
|
||
antwortLabelMC: "Correct Answer (the winning option):",
|
||
antwortHelpText: "Our system automatically matches minor typos and casing.",
|
||
antwortHelpMC: "This option will be shuffled together with the false choices.",
|
||
wrongLabel: "Wrong Answer Options (for player to choose from):",
|
||
wrongPlaceholder1: "Wrong Option 1 (e.g. Severus Snape)",
|
||
wrongPlaceholder2: "Wrong Option 2 (e.g. Minerva McGonagall)",
|
||
wrongPlaceholder3: "Wrong Option 3 (e.g. Rubeus Hagrid)",
|
||
tippLabel: "Hint / Clue (optional):",
|
||
tippPlaceholder: "e.g. He wears half-moon spectacles.",
|
||
submitBtn: "📜 Submit Proposal to the Ministry",
|
||
submitBtnCasting: "✨ Transmitting proposal...",
|
||
alertFillRequired: "Please enter at least the question and the correct answer.",
|
||
alertMCRequired: "For Multiple Choice, please provide at least one incorrect option.",
|
||
successHeader: "✨ Question successfully submitted! ✨"
|
||
}
|
||
};
|
||
|
||
function onLanguageChange(lang) {
|
||
const t = SUGGESTION_TEXT[lang] || SUGGESTION_TEXT.de;
|
||
const title = document.getElementById("suggTitle");
|
||
const subtitle = document.getElementById("suggSubtitle");
|
||
const alertBox = document.getElementById("suggAlert");
|
||
const nameLabel = document.getElementById("suggNameLabel");
|
||
const nameInput = document.getElementById("name");
|
||
const frageLabel = document.getElementById("suggFrageLabel");
|
||
const frageInput = document.getElementById("frage");
|
||
const diffLabel = document.getElementById("suggDiffLabel");
|
||
const typeLabel = document.getElementById("suggTypeLabel");
|
||
const optText = document.getElementById("optText");
|
||
const optMC = document.getElementById("optMC");
|
||
const mcWrongLabel = document.getElementById("mcWrongLabel");
|
||
const tippLabel = document.getElementById("suggTippLabel");
|
||
const tippInput = document.getElementById("tipp");
|
||
const submitBtn = document.getElementById("submitBtn");
|
||
|
||
const catLabel = document.getElementById("suggCatLabel");
|
||
const catBooks = document.getElementById("catBooks");
|
||
const catMovies = document.getElementById("catMovies");
|
||
const catHogwarts = document.getElementById("catHogwarts");
|
||
const catCharacters = document.getElementById("catCharacters");
|
||
const catSpells = document.getElementById("catSpells");
|
||
const catCreatures = document.getElementById("catCreatures");
|
||
const catQuidditch = document.getElementById("catQuidditch");
|
||
const catLore = document.getElementById("catLore");
|
||
const catGeneral = document.getElementById("catGeneral");
|
||
|
||
if (title) title.innerText = t.title;
|
||
if (subtitle) subtitle.innerText = t.subtitle;
|
||
if (alertBox) alertBox.innerHTML = t.alert;
|
||
if (nameLabel) nameLabel.innerText = t.nameLabel;
|
||
if (nameInput) nameInput.placeholder = t.namePlaceholder;
|
||
if (catLabel) catLabel.innerText = t.catLabel;
|
||
if (catBooks) catBooks.innerText = t.catBooks;
|
||
if (catMovies) catMovies.innerText = t.catMovies;
|
||
if (catHogwarts) catHogwarts.innerText = t.catHogwarts;
|
||
if (catCharacters) catCharacters.innerText = t.catCharacters;
|
||
if (catSpells) catSpells.innerText = t.catSpells;
|
||
if (catCreatures) catCreatures.innerText = t.catCreatures;
|
||
if (catQuidditch) catQuidditch.innerText = t.catQuidditch;
|
||
if (catLore) catLore.innerText = t.catLore;
|
||
if (catGeneral) catGeneral.innerText = t.catGeneral;
|
||
if (frageLabel) frageLabel.innerText = t.frageLabel;
|
||
if (frageInput) frageInput.placeholder = t.fragePlaceholder;
|
||
if (diffLabel) diffLabel.innerText = t.diffLabel;
|
||
if (typeLabel) typeLabel.innerText = t.typeLabel;
|
||
if (optText) optText.innerText = t.optText;
|
||
if (optMC) optMC.innerText = t.optMC;
|
||
if (mcWrongLabel) mcWrongLabel.innerText = t.wrongLabel;
|
||
if (tippLabel) tippLabel.innerText = t.tippLabel;
|
||
if (tippInput) tippInput.placeholder = t.tippPlaceholder;
|
||
if (submitBtn && !submitBtn.disabled) submitBtn.innerText = t.submitBtn;
|
||
|
||
const qType = document.getElementById("q_type");
|
||
if (qType) toggleVorschlagType(qType.value);
|
||
}
|
||
|
||
function toggleVorschlagType(type) {
|
||
const lang = (typeof currentLang !== "undefined") ? currentLang : (localStorage.getItem("quiz_lang") || "de");
|
||
const t = SUGGESTION_TEXT[lang] || SUGGESTION_TEXT.de;
|
||
|
||
const mcGroup = document.getElementById("mcOptionsGroup");
|
||
const antwortLabel = document.getElementById("antwortLabel");
|
||
const antwortHelp = document.getElementById("antwortHelp");
|
||
|
||
if (type === "multiple_choice") {
|
||
mcGroup.classList.remove("hidden");
|
||
antwortLabel.innerText = t.antwortLabelMC;
|
||
antwortHelp.innerText = t.antwortHelpMC;
|
||
} else {
|
||
mcGroup.classList.add("hidden");
|
||
antwortLabel.innerText = t.antwortLabelText;
|
||
antwortHelp.innerText = t.antwortHelpText;
|
||
}
|
||
}
|
||
|
||
async function submitSuggestion(event) {
|
||
event.preventDefault();
|
||
|
||
const lang = (typeof currentLang !== "undefined") ? currentLang : (localStorage.getItem("quiz_lang") || "de");
|
||
const t = SUGGESTION_TEXT[lang] || SUGGESTION_TEXT.de;
|
||
|
||
const name = document.getElementById("name").value.trim();
|
||
const frage = document.getElementById("frage").value.trim();
|
||
const antwort = document.getElementById("antwort").value.trim();
|
||
const tipp = document.getElementById("tipp").value.trim();
|
||
const qType = document.getElementById("q_type").value;
|
||
const diff = document.getElementById("diff_select") ? document.getElementById("diff_select").value : "medium";
|
||
const submitBtn = document.getElementById("submitBtn");
|
||
const resultBox = document.getElementById("resultMessage");
|
||
|
||
if (!frage || !antwort) {
|
||
alert(t.alertFillRequired);
|
||
return;
|
||
}
|
||
|
||
let falscheAntworten = [];
|
||
if (qType === "multiple_choice") {
|
||
const w1 = document.getElementById("wrong1").value.trim();
|
||
const w2 = document.getElementById("wrong2").value.trim();
|
||
const w3 = document.getElementById("wrong3").value.trim();
|
||
falscheAntworten = [w1, w2, w3].filter(x => x.length > 0);
|
||
|
||
if (falscheAntworten.length === 0) {
|
||
alert(t.alertMCRequired);
|
||
return;
|
||
}
|
||
}
|
||
|
||
submitBtn.disabled = true;
|
||
submitBtn.innerText = t.submitBtnCasting;
|
||
|
||
try {
|
||
const catElem = document.getElementById("kategorie");
|
||
const category = catElem ? catElem.value : "general";
|
||
|
||
const payload = {
|
||
name: name || "Gast",
|
||
category: category,
|
||
frage: frage,
|
||
antwort: antwort,
|
||
tipp: tipp || null,
|
||
question_type: qType,
|
||
difficulty: diff,
|
||
falsche_antworten: falscheAntworten
|
||
};
|
||
|
||
const res = await fetch("/api/suggestions", {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify(payload)
|
||
});
|
||
|
||
const data = await res.json();
|
||
|
||
if (res.ok && data.success) {
|
||
resultBox.innerHTML = `
|
||
<div style="background: rgba(46, 204, 113, 0.2); border: 1px solid #2ecc71; color: #55efc4; padding: 15px; border-radius: 8px;">
|
||
<h3>${t.successHeader}</h3>
|
||
<p>${data.message}</p>
|
||
</div>
|
||
`;
|
||
resultBox.classList.remove("hidden");
|
||
document.getElementById("suggestionForm").reset();
|
||
toggleVorschlagType("text");
|
||
} else {
|
||
resultBox.innerHTML = `
|
||
<div class="alert alert-danger">
|
||
${data.detail || "Fehler beim Einreichen deines Vorschlags."}
|
||
</div>
|
||
`;
|
||
resultBox.classList.remove("hidden");
|
||
}
|
||
} catch (err) {
|
||
resultBox.innerHTML = `
|
||
<div class="alert alert-danger">
|
||
Netzwerkfehler: ${err.message}
|
||
</div>
|
||
`;
|
||
resultBox.classList.remove("hidden");
|
||
} finally {
|
||
submitBtn.disabled = false;
|
||
submitBtn.innerText = t.submitBtn;
|
||
}
|
||
}
|
||
|
||
document.addEventListener("DOMContentLoaded", () => {
|
||
const lang = (typeof currentLang !== "undefined") ? currentLang : (localStorage.getItem("quiz_lang") || "de");
|
||
onLanguageChange(lang);
|
||
});
|