feat: Lernapp mit Mathe/Deutsch/Englisch, Münzsystem und Belohnungen

This commit is contained in:
root
2026-05-05 14:41:09 +00:00
parent 21e40cd2da
commit bd1640994c
45 changed files with 1522 additions and 58 deletions
+72
View File
@@ -0,0 +1,72 @@
@extends('layouts.child')
@section('content')
@php $level = auth()->user()->level() @endphp
<div class="text-center mb-8">
<div class="text-5xl mb-2">{{ $level['icon'] }}</div>
<h1 class="text-2xl font-bold text-indigo-700">Hallo, {{ auth()->user()->name }}! 👋</h1>
<p class="text-slate-500 mt-1">Du bist: <span class="{{ $level['color'] }} font-bold">{{ $level['label'] }}</span></p>
@if($streak >= 3)
<div class="mt-3 inline-flex items-center gap-2 bg-orange-100 text-orange-700 rounded-full px-4 py-1.5 text-sm font-bold">
🔥 {{ $streak }}er-Serie! +5 Bonusmünzen pro Antwort
</div>
@elseif($streak > 0)
<div class="mt-3 inline-flex items-center gap-2 bg-sky-100 text-sky-700 rounded-full px-4 py-1.5 text-sm font-medium">
{{ $streak }} richtige Antworten in Folge!
</div>
@endif
</div>
<div class="grid grid-cols-2 gap-4 mb-8">
<div class="bg-white rounded-2xl shadow-sm border border-amber-200 p-5 text-center">
<div class="text-4xl font-black text-amber-500">{{ auth()->user()->points }}</div>
<div class="text-sm text-slate-500 mt-1 font-medium">🪙 Münzen</div>
@if($level['next'])
<div class="mt-3">
<div class="text-xs text-slate-400 mb-1">Nächstes Level in {{ $level['next'] - auth()->user()->points }} Münzen</div>
<div class="bg-slate-200 rounded-full h-2"><div class="bg-amber-400 h-2 rounded-full transition-all" style="width:{{ $level['progress'] }}%"></div></div>
</div>
@endif
</div>
@if($pendingRedemptions > 0)
<a href="{{ route('rewards.index') }}" class="bg-green-50 border border-green-300 rounded-2xl p-5 text-center hover:bg-green-100 transition">
<div class="text-4xl font-black text-green-600">{{ $pendingRedemptions }}</div>
<div class="text-sm text-slate-500 mt-1 font-medium">🎁 Einlösung wartet</div>
</a>
@else
<a href="{{ route('rewards.index') }}" class="bg-white rounded-2xl shadow-sm border border-slate-200 p-5 text-center hover:border-indigo-300 transition">
<div class="text-4xl">🎁</div>
<div class="text-sm text-slate-500 mt-1 font-medium">Belohnungen</div>
</a>
@endif
</div>
<h2 class="font-bold text-slate-700 text-lg mb-4">📚 Fächer</h2>
<div class="grid grid-cols-3 gap-4 mb-8">
@foreach($subjects as $s)
@php $colors = ['green'=>'from-green-400 to-emerald-500','blue'=>'from-blue-400 to-indigo-500','orange'=>'from-orange-400 to-amber-500'] @endphp
<a href="{{ route('learn.quiz', $s->slug) }}" class="bg-gradient-to-br {{ $colors[$s->color] ?? 'from-violet-400 to-purple-500' }} rounded-2xl p-5 text-white text-center hover:scale-105 transition-transform shadow-sm">
<div class="text-3xl mb-2">{{ $s->icon }}</div>
<div class="font-bold text-sm">{{ $s->name }}</div>
<div class="text-white/80 text-xs mt-1">{{ $s->correct }} </div>
</a>
@endforeach
</div>
@if($recentAttempts->count())
<h2 class="font-bold text-slate-700 text-lg mb-4">⏱️ Zuletzt gespielt</h2>
<div class="bg-white rounded-2xl shadow-sm border border-slate-200 overflow-hidden">
@foreach($recentAttempts as $a)
<div class="flex items-center justify-between px-5 py-3 {{ !$loop->last ? 'border-b border-slate-100' : '' }}">
<div class="flex items-center gap-3">
<span class="text-lg">{{ $a->is_correct ? '✅' : '❌' }}</span>
<div>
<div class="text-sm font-medium text-slate-700 line-clamp-1">{{ Str::limit($a->question->question_text, 40) }}</div>
<div class="text-xs text-slate-400">{{ $a->question->subject->name }}</div>
</div>
</div>
@if($a->points_earned > 0)<span class="text-xs font-bold text-amber-500">+{{ $a->points_earned }} 🪙</span>@endif
</div>
@endforeach
</div>
@endif
@endsection
@@ -0,0 +1,34 @@
@extends('layouts.child')
@section('content')
<div class="mb-4 flex items-center gap-3">
<a href="{{ route('learn.subjects') }}" class="text-slate-400 hover:text-slate-600 text-sm"> Fächer</a>
<span class="text-lg">{{ $subject->icon }}</span>
<span class="font-bold text-slate-700">{{ $subject->name }}</span>
<span class="ml-auto text-sm text-slate-400">{{ $question->difficultyStars() }}</span>
</div>
<div class="bg-white rounded-2xl shadow-md border border-slate-200 p-6 mb-6">
<div class="text-xs text-slate-400 mb-3 font-medium">
{{ ['','⭐ Leicht — 5 Münzen','⭐⭐ Mittel — 10 Münzen','⭐⭐⭐ Schwer — 20 Münzen'][$question->difficulty] }}
</div>
<p class="text-xl font-bold text-slate-800 leading-snug">{{ $question->question_text }}</p>
</div>
<form method="POST" action="{{ route('learn.answer', $subject->slug) }}">
@csrf
<input type="hidden" name="question_id" value="{{ $question->id }}">
<div class="grid gap-3">
@foreach($question->answerOptions as $opt)
<label class="cursor-pointer">
<input type="radio" name="answer" value="{{ $opt->id }}" class="sr-only peer" required>
<div class="bg-white border-2 border-slate-200 rounded-2xl px-5 py-4 text-base font-medium text-slate-700
peer-checked:border-indigo-500 peer-checked:bg-indigo-50 peer-checked:text-indigo-700
hover:border-indigo-300 hover:bg-slate-50 transition-all">
{{ $opt->text }}
</div>
</label>
@endforeach
</div>
<button type="submit" class="mt-6 w-full bg-indigo-600 hover:bg-indigo-700 text-white text-lg font-bold py-4 rounded-2xl shadow-md transition-colors">
Antworten
</button>
</form>
@endsection
@@ -0,0 +1,41 @@
@extends('layouts.child')
@section('content')
<div class="text-center">
@if($isRight)
<div class="text-7xl mb-4 animate-bounce">🎉</div>
<h1 class="text-3xl font-black text-green-600 mb-2">Richtig!</h1>
<p class="text-slate-600 mb-4">Super gemacht!</p>
<div class="inline-flex items-center gap-2 bg-amber-100 text-amber-700 font-black text-2xl rounded-2xl px-6 py-3 mb-4">
+{{ $earned }} 🪙
</div>
@if($earned > $question->points_value)
<p class="text-orange-600 font-bold text-sm mb-4">🔥 Serien-Bonus inklusive!</p>
@endif
@if($newStreak >= 3)
<div class="bg-orange-50 border border-orange-200 rounded-xl px-4 py-2 text-orange-700 font-bold text-sm mb-4 inline-block">
🔥 {{ $newStreak }}er-Serie! Weiter so!
</div>
@endif
@else
<div class="text-7xl mb-4">😅</div>
<h1 class="text-3xl font-black text-red-500 mb-2">Leider falsch</h1>
<p class="text-slate-600 mb-4">Die richtige Antwort war:</p>
<div class="bg-green-100 border border-green-300 text-green-800 font-bold text-lg rounded-2xl px-6 py-3 mb-4 inline-block">
{{ $correct->text }}
</div>
@endif
<div class="mt-6 flex gap-3 justify-center">
<a href="{{ route('learn.quiz', $subject->slug) }}" class="bg-indigo-600 hover:bg-indigo-700 text-white font-bold px-8 py-3 rounded-2xl text-base shadow-md transition-colors">
Nächste Frage
</a>
<a href="{{ route('learn.subjects') }}" class="bg-slate-200 hover:bg-slate-300 text-slate-700 font-bold px-6 py-3 rounded-2xl text-base transition-colors">
Fächer
</a>
</div>
<div class="mt-6 text-slate-500 text-sm">
Dein Kontostand: <span class="font-bold text-amber-600">🪙 {{ auth()->user()->fresh()->points }}</span>
</div>
</div>
@endsection
@@ -0,0 +1,19 @@
@extends('layouts.child')
@section('content')
<h1 class="text-2xl font-bold text-indigo-700 mb-6 text-center">📚 Welches Fach?</h1>
<div class="grid gap-5">
@foreach($subjects as $s)
@php $colors = ['green'=>'from-green-400 to-emerald-500','blue'=>'from-blue-400 to-indigo-500','orange'=>'from-orange-400 to-amber-500'] @endphp
<a href="{{ route('learn.quiz', $s->slug) }}" class="bg-gradient-to-r {{ $colors[$s->color] ?? 'from-violet-400 to-purple-500' }} rounded-2xl p-6 text-white flex items-center justify-between hover:scale-[1.02] transition-transform shadow-md">
<div class="flex items-center gap-5">
<span class="text-5xl">{{ $s->icon }}</span>
<div>
<div class="text-2xl font-black">{{ $s->name }}</div>
<div class="text-white/80 text-sm mt-0.5">{{ $s->total }} Fragen · {{ $s->correct }} richtig beantwortet</div>
</div>
</div>
<div class="text-4xl"></div>
</a>
@endforeach
</div>
@endsection
@@ -0,0 +1,60 @@
@extends('layouts.child')
@section('content')
<div class="flex items-center justify-between mb-6">
<h1 class="text-2xl font-bold text-indigo-700">🎁 Belohnungen</h1>
<div class="bg-amber-100 text-amber-700 font-black rounded-full px-4 py-2">🪙 {{ auth()->user()->points }}</div>
</div>
<div class="grid gap-4 mb-8">
@foreach($rewards as $r)
@php $canAfford = auth()->user()->points >= $r->points_cost @endphp
<div class="bg-white rounded-2xl shadow-sm border {{ $canAfford ? 'border-slate-200 hover:border-indigo-300' : 'border-slate-100 opacity-60' }} p-5 transition-all">
<div class="flex items-center justify-between gap-4">
<div class="flex items-center gap-4">
<span class="text-4xl">{{ $r->icon }}</span>
<div>
<div class="font-bold text-slate-800 text-base">{{ $r->name }}</div>
@if($r->description)<div class="text-sm text-slate-500">{{ $r->description }}</div>@endif
@if($r->minutes)<div class="text-xs text-slate-400 mt-0.5"> {{ $r->minutes }} Minuten</div>@endif
</div>
</div>
<div class="text-right shrink-0">
<div class="font-black text-amber-600 text-lg">🪙 {{ $r->points_cost }}</div>
@if($canAfford)
<form method="POST" action="{{ route('rewards.redeem', $r) }}" onsubmit="return confirm('Möchtest du {{ $r->name }} für {{ $r->points_cost }} Münzen einlösen?')">
@csrf
<button class="mt-2 bg-indigo-600 hover:bg-indigo-700 text-white font-bold px-4 py-2 rounded-xl text-sm transition-colors">
Einlösen
</button>
</form>
@else
<div class="mt-2 text-xs text-slate-400 font-medium">Noch {{ $r->points_cost - auth()->user()->points }} fehlen</div>
@endif
</div>
</div>
</div>
@endforeach
</div>
@if($history->count())
<h2 class="font-bold text-slate-700 text-lg mb-4">📋 Meine Einlösungen</h2>
<div class="bg-white rounded-2xl shadow-sm border border-slate-200 overflow-hidden">
@foreach($history as $red)
<div class="flex items-center justify-between px-5 py-3 {{ !$loop->last ? 'border-b border-slate-100' : '' }}">
<div class="flex items-center gap-3">
<span class="text-xl">{{ $red->reward->icon }}</span>
<div>
<div class="text-sm font-medium text-slate-700">{{ $red->reward->name }}</div>
<div class="text-xs text-slate-400">{{ $red->created_at->format('d.m.Y') }}</div>
</div>
</div>
<span class="text-xs font-bold px-2.5 py-1 rounded-full
{{ $red->status==='approved' ? 'bg-green-100 text-green-700' :
($red->status==='rejected' ? 'bg-red-100 text-red-600' : 'bg-amber-100 text-amber-700') }}">
{{ $red->status==='approved' ? '✅ Freigegeben' : ($red->status==='rejected' ? '❌ Abgelehnt' : '⏳ Warten...') }}
</span>
</div>
@endforeach
</div>
@endif
@endsection