Feature: Support both Free-Text and Multiple-Choice question types

This commit is contained in:
kobold-ai
2026-09-21 11:35:39 +02:00
parent c3a21369ef
commit 58959ca881
13 changed files with 448 additions and 47 deletions
+62 -4
View File
@@ -52,15 +52,25 @@
{% for q in pending_questions %}
<div class="card question-admin-card" id="q-card-{{ q.id }}">
<div class="q-header">
<span class="badge badge-warning">⚠️ Status: Prüfung ausstehend</span>
<div style="display: flex; gap: 8px; align-items: center;">
<span class="badge badge-warning">⚠️ Prüfung ausstehend</span>
{% if q.question_type == 'multiple_choice' %}
<span class="badge" style="background: rgba(155, 89, 182, 0.2); border-color: #9b59b6; color: #d2b4de;">🔘 Multiple-Choice</span>
{% else %}
<span class="badge badge-muted">🔤 Freitext</span>
{% endif %}
</div>
<span class="q-submitter">Von: <strong>{{ q.submitted_by or 'Gast' }}</strong> am {{ q.created_at.strftime('%d.%m.%Y %H:%M') }}</span>
</div>
<div class="q-body">
<h3>{{ q.question }}</h3>
<p><strong>Erwartete Antwort:</strong> <span class="highlight-answer">{{ q.canonical_answer }}</span></p>
{% if q.options %}
<p style="margin-top: 5px;"><strong>Auswahl-Optionen:</strong> <code>{{ q.options }}</code></p>
{% endif %}
{% if q.hint %}
<p><strong>Tipp:</strong> <em>{{ q.hint }}</em></p>
<p style="margin-top: 5px;"><strong>Tipp:</strong> <em>{{ q.hint }}</em></p>
{% endif %}
<!-- Interaktives Testfeld für den Admin -->
@@ -93,10 +103,21 @@
<label>Frage:</label>
<input type="text" name="question" class="input-text" value="{{ q.question }}" required>
</div>
<div class="form-group">
<label>Fragentyp:</label>
<select name="question_type" class="input-text">
<option value="text" {% if q.question_type != 'multiple_choice' %}selected{% endif %}>🔤 Freitext</option>
<option value="multiple_choice" {% if q.question_type == 'multiple_choice' %}selected{% endif %}>🔘 Multiple Choice</option>
</select>
</div>
<div class="form-group">
<label>Richtige Antwort:</label>
<input type="text" name="canonical_answer" class="input-text" value="{{ q.canonical_answer }}" required>
</div>
<div class="form-group">
<label>Optionen (JSON-Liste oder Komma-getrennt für Multiple Choice):</label>
<input type="text" name="options_raw" class="input-text" value="{{ q.options or '' }}">
</div>
<div class="form-group">
<label>Tipp:</label>
<input type="text" name="hint" class="input-text" value="{{ q.hint or '' }}">
@@ -120,15 +141,25 @@
{% for q in active_questions %}
<div class="card question-admin-card" id="q-card-{{ q.id }}">
<div class="q-header">
<span class="badge badge-success">Reihenfolge #{{ q.sort_order }}</span>
<div style="display: flex; gap: 8px; align-items: center;">
<span class="badge badge-success">Reihenfolge #{{ q.sort_order }}</span>
{% if q.question_type == 'multiple_choice' %}
<span class="badge" style="background: rgba(155, 89, 182, 0.2); border-color: #9b59b6; color: #d2b4de;">🔘 Multiple-Choice</span>
{% else %}
<span class="badge badge-muted">🔤 Freitext</span>
{% endif %}
</div>
<span class="q-category">Kategorie: {{ q.category }}</span>
</div>
<div class="q-body">
<h3>{{ loop.index }}. {{ q.question }}</h3>
<p><strong>Antwort:</strong> <span class="highlight-answer">{{ q.canonical_answer }}</span></p>
{% if q.options %}
<p style="margin-top: 5px;"><strong>Optionen:</strong> <code>{{ q.options }}</code></p>
{% endif %}
{% if q.hint %}
<p><strong>Tipp:</strong> <em>{{ q.hint }}</em></p>
<p style="margin-top: 5px;"><strong>Tipp:</strong> <em>{{ q.hint }}</em></p>
{% endif %}
</div>
@@ -144,10 +175,21 @@
<label>Frage:</label>
<input type="text" name="question" class="input-text" value="{{ q.question }}" required>
</div>
<div class="form-group">
<label>Fragentyp:</label>
<select name="question_type" class="input-text">
<option value="text" {% if q.question_type != 'multiple_choice' %}selected{% endif %}>🔤 Freitext</option>
<option value="multiple_choice" {% if q.question_type == 'multiple_choice' %}selected{% endif %}>🔘 Multiple Choice</option>
</select>
</div>
<div class="form-group">
<label>Richtige Antwort:</label>
<input type="text" name="canonical_answer" class="input-text" value="{{ q.canonical_answer }}" required>
</div>
<div class="form-group">
<label>Optionen (JSON-Liste oder Komma-getrennt für Multiple Choice):</label>
<input type="text" name="options_raw" class="input-text" value="{{ q.options or '' }}">
</div>
<div class="form-group">
<label>Tipp:</label>
<input type="text" name="hint" class="input-text" value="{{ q.hint or '' }}">
@@ -179,6 +221,14 @@
</select>
</div>
<div class="form-group">
<label for="new_type">Fragentyp:</label>
<select name="question_type" id="new_type" class="input-text" onchange="toggleAdminNewType(this.value)">
<option value="text" selected>🔤 Freitext-Eingabe (Tippen)</option>
<option value="multiple_choice">🔘 Multiple Choice (Auswahl)</option>
</select>
</div>
<div class="form-group">
<label for="new_question">Frage:</label>
<textarea name="question" id="new_question" class="textarea" rows="2" required placeholder="z. B. Welcher Zauber entwaffnet Gegner?"></textarea>
@@ -189,6 +239,14 @@
<input type="text" name="canonical_answer" id="new_answer" class="input-text" required placeholder="z. B. Expelliarmus">
</div>
<!-- Multiple Choice Optionen für Admin -->
<div id="adminMcOptions" class="form-group hidden" style="background: rgba(255,255,255,0.03); padding: 15px; border-radius: 8px; border: 1px dashed var(--border-gold);">
<label style="color: var(--gold);">Falsche Optionen für Multiple Choice (Optionen 2 bis 4):</label>
<input type="text" name="wrong_option_1" class="input-text" placeholder="Falsche Option 1 (z.B. Stupor)" style="margin-bottom: 8px;">
<input type="text" name="wrong_option_2" class="input-text" placeholder="Falsche Option 2 (z.B. Lumos)" style="margin-bottom: 8px;">
<input type="text" name="wrong_option_3" class="input-text" placeholder="Falsche Option 3 (z.B. Alohomora)">
</div>
<div class="form-group">
<label for="new_hint">Tipp (optional):</label>
<input type="text" name="hint" id="new_hint" class="input-text" placeholder="z. B. Harrys Lieblingszauber">
+12 -1
View File
@@ -53,7 +53,8 @@
<h2 id="frageText" class="question-text">Lade verzauberte Schriftrollen...</h2>
<div class="answer-form">
<!-- 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">
@@ -66,6 +67,16 @@
</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()">
💡 Zaubertipp
</button>
</div>
</div>
<div id="hintBox" class="hint-box hidden">
<strong>📜 Notiz aus der verbotenen Abteilung:</strong>
<p id="hintText"></p>
+18 -2
View File
@@ -24,9 +24,25 @@
</div>
<div class="form-group">
<label for="antwort">Richtige Antwort: <span class="required">*</span></label>
<label for="q_type">Art der Frage:</label>
<select id="q_type" name="q_type" class="input-text" onchange="toggleVorschlagType(this.value)">
<option value="text" selected>🔤 Freitext-Antwort (Tippen mit Fehlertoleranz)</option>
<option value="multiple_choice">🔘 Multiple Choice (Auswahl aus 4 Antwortmöglichkeiten)</option>
</select>
</div>
<div class="form-group">
<label for="antwort"><span id="antwortLabel">Richtige Antwort:</span> <span class="required">*</span></label>
<input type="text" id="antwort" name="antwort" class="input-text" placeholder="z. B. Albus Dumbledore" required>
<small class="field-help">Unser System gleicht Tippfehler und Groß-/Kleinschreibung automatisch ab.</small>
<small class="field-help" id="antwortHelp">Unser System gleicht Tippfehler und Groß-/Kleinschreibung automatisch ab.</small>
</div>
<!-- Zusätzliche Optionen für Multiple Choice -->
<div id="mcOptionsGroup" class="form-group hidden" style="background: rgba(255,255,255,0.03); padding: 15px; border-radius: 8px; border: 1px dashed var(--border-gold);">
<label style="color: var(--gold);">Falsche Antwortmöglichkeiten (zur Auswahl für die Spieler):</label>
<input type="text" id="wrong1" class="input-text" placeholder="Falsche Option 1 (z. B. Severus Snape)" style="margin-bottom: 8px;">
<input type="text" id="wrong2" class="input-text" placeholder="Falsche Option 2 (z. B. Minerva McGonagall)" style="margin-bottom: 8px;">
<input type="text" id="wrong3" class="input-text" placeholder="Falsche Option 3 (z. B. Rubeus Hagrid)">
</div>
<div class="form-group">