Files
lernapp/resources/views/child/quiz/question.blade.php
T
root 6c6dd26823 Add Quiz feature: 10-question quizzes with progressive scoring (max 40 pts)
- Quizzes table with questions, answer options, attempts, answers
- Question types: multiple_choice, exclusion, true_false, free_text
- Progressive scoring: [1,1,2,2,3,3,4,6,8,10] = max 40 per quiz
- Alpine.js countdown timer per question with auto-submit on timeout
- Admin: CRUD for quizzes + per-question editor, JSON export/import
- Child: quiz overview with best scores, question view, result breakdown
- Nav: Quiz link in child header and admin sidebar
2026-05-05 21:14:09 +00:00

124 lines
5.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@extends('layouts.child')
@section('content')
@php $tl = $question->time_limit ?? 0; @endphp
<div x-data="{
tl: {{ $tl }},
left: {{ $tl }},
timedOut: false,
timer: null,
init() {
if (this.tl > 0) {
this.timer = setInterval(() => {
this.left--;
if (this.left <= 0) {
clearInterval(this.timer);
this.timedOut = true;
this.$nextTick(() => {
document.querySelectorAll('[required]').forEach(e => e.removeAttribute('required'));
document.getElementById('timeout-input').value = '1';
document.getElementById('answer-form').submit();
});
}
}, 1000);
}
}
}">
{{-- Header bar --}}
<div class="flex items-center gap-3 mb-4">
<a href="{{ route('quiz.index') }}" class="text-slate-400 hover:text-slate-600 text-sm"> Quiz</a>
<div class="flex-1 bg-slate-200 rounded-full h-2.5">
<div class="bg-violet-500 h-2.5 rounded-full transition-all duration-300"
style="width: {{ ($attempt->current_question / max($attempt->quiz->questions()->count(),1)) * 100 }}%"></div>
</div>
<span class="text-sm font-semibold text-slate-600 whitespace-nowrap">
{{ $attempt->current_question + 1 }} / {{ $attempt->quiz->questions()->count() }}
</span>
</div>
{{-- Timer bar --}}
<template x-if="tl > 0">
<div class="mb-4">
<div class="bg-slate-200 rounded-full h-2">
<div class="h-2 rounded-full transition-all duration-1000"
:class="left > tl*0.5 ? 'bg-green-500' : (left > tl*0.25 ? 'bg-yellow-500' : 'bg-red-500')"
:style="'width:' + Math.max(0,(left/tl)*100) + '%'"></div>
</div>
<div class="text-right text-xs mt-1" :class="left <= 5 ? 'text-red-500 font-bold' : 'text-slate-400'">
<span x-text="left"></span>s
</div>
</div>
</template>
{{-- Last answer flash --}}
@if(session('last_answer'))
@php $la = session('last_answer'); @endphp
<div class="mb-4 rounded-xl px-4 py-3 text-sm font-medium flex items-center gap-2
{{ $la['timeout'] ? 'bg-slate-100 text-slate-600' : ($la['correct'] ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-700') }}">
@if($la['timeout']) Zeit abgelaufen 0 Münzen
@elseif($la['correct']) Richtig! +{{ $la['points'] }} 🪙
@else Leider falsch 0 Münzen
@endif
</div>
@endif
{{-- Points badge --}}
<div class="text-center mb-5">
<span class="bg-amber-100 text-amber-700 text-sm font-bold px-4 py-1.5 rounded-full">
+{{ $pointsIfCorrect }} 🪙 bei richtiger Antwort
</span>
</div>
{{-- Question card --}}
<div class="bg-white rounded-2xl shadow-sm border border-slate-200 p-6">
<h2 class="text-xl font-black text-slate-800 mb-6 leading-snug">{{ $question->question_text }}</h2>
<form method="POST" action="{{ route('quiz.answer',$attempt) }}" id="answer-form">
@csrf
<input type="hidden" name="timeout" value="0" id="timeout-input">
@if(in_array($question->type, ['multiple_choice','exclusion']))
<div class="grid grid-cols-2 gap-3 mb-6">
@foreach($question->answerOptions as $opt)
<label class="flex items-center gap-3 p-4 border-2 border-slate-200 rounded-xl cursor-pointer
hover:border-violet-300 hover:bg-violet-50 has-[:checked]:border-violet-500 has-[:checked]:bg-violet-50
transition-colors">
<input type="radio" name="answer" value="{{ $opt->id }}" required class="w-4 h-4 text-violet-600 shrink-0">
<span class="text-slate-700 font-medium text-sm">{{ $opt->text }}</span>
</label>
@endforeach
</div>
@elseif($question->type === 'true_false')
<div class="grid grid-cols-2 gap-4 mb-6">
<label class="flex items-center justify-center gap-3 p-5 border-2 border-slate-200 rounded-xl cursor-pointer
hover:border-green-400 hover:bg-green-50 has-[:checked]:border-green-500 has-[:checked]:bg-green-50
transition-colors">
<input type="radio" name="answer" value="true" required class="sr-only">
<span class="text-2xl"></span>
<span class="font-bold text-slate-700">Wahr</span>
</label>
<label class="flex items-center justify-center gap-3 p-5 border-2 border-slate-200 rounded-xl cursor-pointer
hover:border-red-400 hover:bg-red-50 has-[:checked]:border-red-500 has-[:checked]:bg-red-50
transition-colors">
<input type="radio" name="answer" value="false" required class="sr-only">
<span class="text-2xl"></span>
<span class="font-bold text-slate-700">Falsch</span>
</label>
</div>
@elseif($question->type === 'free_text')
<div class="mb-6">
<input type="text" name="answer" required autofocus placeholder="Deine Antwort eingeben …"
class="w-full border-2 border-slate-200 focus:border-violet-500 rounded-xl px-4 py-3 text-lg font-bold text-slate-800 outline-none text-center transition-colors">
</div>
@endif
<button type="submit" class="w-full bg-violet-600 hover:bg-violet-700 text-white py-3 rounded-xl font-bold text-base">
Antworten
</button>
</form>
</div>
</div>
@endsection