Merge branch '103-verschiedene-lernmodi' into 'master'

Resolve "verschiedene Lernmodi"

Closes #103

See merge request enrichment-2024/qivip!47

(cherry picked from commit d4252c1297)

5b4c76a1 Zwischenstand Lernmodus
4209dcbc Merge branch 'master' into 103-verschiedene-lernmodi
9fb9ab91 Lernfunktion
e22ea409 Lernmodus verbessert und Testmodus entfernt
2052a702 Merge branch 'master' into '103-verschiedene-lernmodi'

Co-authored-by: ben8 <ben_ollech@bessermailer.de>
This commit is contained in:
ben8
2025-04-18 14:00:29 +00:00
parent 937fd4a2e4
commit bcdfebf791
7 changed files with 185 additions and 42 deletions

View File

@@ -1,46 +1,67 @@
{% extends 'base.html' %}
{% block content %}
{% if request.session.mode == "learn" %}
<div class="container mx-auto px-4">
<div class="flex justify-end mb-4">
<button onclick="leaveGame()" class="bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded">
Spiel verlassen
</button>
</div>{% endif %}
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
<p class="text-gray-700 font-bold text-xl mb-4">Frage {{ question_index|add:1 }} von {{ total_questions }}</p>
<h1 class="text-3xl font-bold mb-6">{{ question_data.question }}</h1>
<div class="grid grid-cols-2 gap-4 mb-6">
{% if request.session.mode == "learn" %}
<div class="grid grid-cols-1 gap-4 mb-6">
{% else %}
<div class="grid grid-cols-2 gap-4 mb-6">
{% endif %}
{% if request.session.mode != "learn" %}
<div class="p-4 bg-blue-50 rounded-lg">
<p class="text-blue-600 text-xl mb-2">Verbleibende Zeit</p>
<p class="text-blue-600 text-xl mb-2">Verbleibende Zeit </p>
<p id="remaining-time" class="text-6xl font-bold text-blue-700">30</p>
</div>
{% endif %}
<div class="p-4 bg-blue-50 rounded-lg">
<p class="text-blue-600 text-xl mb-2">Antworten</p>
<p id="answer-count" class="text-6xl font-bold text-blue-700">0/0</p>
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<div class="grid grid-cols-2 gap-4" id="options-container">
{% for option in question_data.options %}
<div class="p-4 bg-gray-100 rounded-lg" data-correct="{{ option.is_correct }}">
<button
class="p-4 bg-gray-100 hover:bg-blue-100 rounded-lg transition-colors duration-200 answer-option"
data-index="{{ forloop.counter0 }}"
{% if request.session.mode == "learn" %}
onclick="submitAnswer({{ forloop.counter0 }});" {% endif %}>
<p class="text-lg">{{ option.value }}</p>
<p id="option-count-{{ forloop.counter0 }}" class="text-gray-600 hidden">0 Antworten</p>
</div>
</button>
{% endfor %}
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
{% include 'play/game/common_scripts.html' %}
<script>
const joinCode = '{{ quiz_game.join_code }}';
const hostId = '{{ host_id }}';
const questionStartTime = {{ start_time }};
const questionDuration = '{{ current_question.time_per_question }}'*1000; //Zeit pro Frage (indviduell eingestellt)
var questionDuration = 30000; // 30 seconds in milliseconds
const gameSocket = initializeGameSocket(joinCode);
let answeredParticipants = 0;
let totalParticipants = 0;
const optionCounts = {};
gameSocket.onmessage = function(e) {
const data = JSON.parse(e.data);
if (data.type === 'participant_answer') {
@@ -85,7 +106,7 @@
// Show correct answers and answer counts
var correctOptions = document.querySelectorAll('[data-correct="True"]');
for (var i = 0; i < correctOptions.length; i++) {
correctOptions[i].classList.add('border-2', 'border-green-500');
correctOptions[i].classList.add('border-2', 'border-blue-500');
}
// Show answer counts
@@ -104,6 +125,7 @@
}
// Timer
{% if request.session.mode != "learn" %}
function updateTimer() {
const now = Date.now();
const elapsed = now - questionStartTime;
@@ -118,6 +140,9 @@
}
}
{% endif %}
// Request initial participants list
gameSocket.onopen = function(e) {
gameSocket.send(JSON.stringify({
@@ -125,5 +150,51 @@
}));
updateTimer();
};
let hasAnswered = false;
const participantId = '{{ host_id }}'; // HIER IST DER HOST DER SPIELER
function leaveGame() {
if (confirm('Möchtest du das Spiel wirklich verlassen?')) {
gameSocket.send(JSON.stringify({
type: 'leave_game',
participant_id: participantId
}));
window.location.href = '/';
gameSocket.close();
}
}
function submitAnswer(optionIndex) {
if (hasAnswered) return;
hasAnswered = true;
const now = Date.now();
const timeRemaining = Math.max(0, questionDuration - (now - questionStartTime));
// Disable all options and highlight selected
const options = document.getElementsByClassName('answer-option');
for (let option of options) {
option.disabled = true;
option.classList.remove('hover:bg-blue-100');
if (parseInt(option.dataset.index) === optionIndex) {
option.classList.remove('bg-gray-100');
option.classList.add('bg-blue-600', 'text-white');
} else {
option.classList.add('opacity-50');
}
}
// Send answer to server
gameSocket.send(JSON.stringify({
type: 'submit_answer',
participant_id: participantId,
answer: optionIndex,
time_remaining: timeRemaining
}));
}
</script>
{% endblock %}