Files
qivip/django/templates/play/game/question_participant.html

180 lines
6.5 KiB
HTML

{% extends 'base.html' %}
{% block content %}
<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>
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
<div class="flex justify-between mb-2">
<div class="flex gap-1 text-sm"><p class="text-sm">Frage</p>
<p class="text-gray-700 font-bold text-sm">{{ question_index|add:1 }}</p>
<p class="text-sm">von</p>
<p class="text-gray-700 font-bold text-sm">{{ total_questions }}</p>
</div>
</div>
<h1 class="text-xl font-black mb-2 border-blue-500 border-4 p-4 text-center rounded-lg md:text-2xl lg:text-4xl">{{ question_data.question}}</h1>
<div class="w-full bg-gray-300 rounded-full h-4 my-4">
<div id="time-bar" class="bg-blue-600 h-4 rounded-full transition-all duration-100 linear" style="width: 100%;"></div>
</div>
{% if question_data.type != "input" %}
<div class="grid grid-cols-2 gap-4" id="options-container">
{% for option in question_data.options %}
<button
class="
{% if forloop.counter0 == 0 %}
bg-green-500
hover:bg-green-600
{% elif forloop.counter0 == 1 %}
bg-red-500
hover:bg-red-600
{% elif forloop.counter0 == 2 %}
bg-blue-500
hover:bg-blue-600
{% elif forloop.counter0 == 3 %}
bg-purple-500
hover:bg-purple-600
{% elif forloop.counter0 == 4 %}
bg-orange-500
hover:bg-orange-600
{% elif forloop.counter0 == 5 %}
bg-yellow-500
hover:bg-yellow-600
{% else %}
bg-gray-500
hover:bg-gray-600
{% endif %}
p-4 rounded-lg text-white transition-colors duration-200 answer-option overflow-auto break-words hyphens-auto "
data-index="{{ forloop.counter0 }}"
onclick="submitAnswer({{ forloop.counter0 }});">
<p class="text-lg">{{ option.value }}</p>
</button>
{% endfor %}
</div>
{% else %}
<form action="">
<input id="textanswer" type="text" placeholder="DEINE ANTWORT"
class="answer-option text-center p-2 bg-gray-100 hover:bg-blue-100 rounded-lg transition-colors duration-200 answer-option lg:w-80">
<button
onclick="submitAnswer( -1 );"
class="mt-2 text-center p-2 bg-gray-100 hover:bg-blue-100 rounded-lg transition-colors duration-200 answer-option">
abschicken
</button>
</form>
{% endif %}
</div>
</div>
{% endblock %}
{% block extra_js %}
{% include 'play/game/common_scripts.html' %}
<script>
let hasAnswered = false;
const joinCode = '{{ quiz_game.join_code }}';
const participantId = '{{ participant.participant_id }}';
const questionStartTime = Date.now();
const questionDuration = '{{ current_question.time_per_question }}'*1000; //Zeit pro Frage (indviduell eingestellt)
const gameSocket = initializeGameSocket(joinCode);
gameSocket.onmessage = function(e) {
const data = JSON.parse(e.data);
if (data.type === 'redirect' && data.url) {
window.location.href = data.url;
} else if (data.type === 'game_state_update' &&
data.action === 'show_scores' &&
data.redirect_url) {
window.location.href = data.redirect_url;
submitAnswer( -1 );
}
};
gameSocket.onclose = function(e) {
wsUtil.handleClose(e);
};
function submitAnswer(optionIndex) {
if (hasAnswered) return;
let input = ""; // Declare input here
try {
input = document.getElementById("textanswer").value;
} catch (e) {
input = "";
}
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');
}
}
if(input!=""){
// Send answer to server
gameSocket.send(JSON.stringify({
type: 'submit_answer',
participant_id: participantId,
answer:input,
time_remaining: timeRemaining
}));
}
else{
gameSocket.send(JSON.stringify({
type: 'submit_answer',
participant_id: participantId,
answer:optionIndex,
time_remaining: timeRemaining
}));
}
}
// Timer
function updateTimer() {
const now = Date.now();
const elapsed = now - questionStartTime;
const remaining = Math.max(0, (questionDuration - elapsed) / 1000);
document.getElementById('time-bar').style.width = ((remaining * 1000) / questionDuration * 100) + '%';
if (remaining<3){
document.getElementById('time-bar').style.backgroundColor="red";}else if(remaining<5){document.getElementById('time-bar').style.backgroundColor="orange";}
//document.getElementById('remaining-time').textContent = remaining;
if (remaining === 0 && !hasAnswered) {
// Auto-submit timeout answer
submitAnswer(-1);
} else if (remaining > 0) {
requestAnimationFrame(updateTimer);
}
}
function leaveGame() {
if (confirm('Möchtest du das Spiel wirklich verlassen?')) {
gameSocket.send(JSON.stringify({
type: 'leave_game',
participant_id: participantId
}));
}
}
// Start timer when page loads
updateTimer();
</script>
{% endblock %}