lernschiff/app/Livewire/Tasks/Run.php

103 lines
2.7 KiB
PHP

<?php
namespace App\Livewire\Tasks;
use Illuminate\Contracts\View\View;
use Livewire\Attributes\Lazy;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Url;
use Livewire\Component;
#[Layout('layouts.dashboard', ['active' => 'tasks'])]
#[Lazy]
class Run extends Component
{
public string $slug = '';
public array $task = [];
public array $questions = [];
public int $currentStep = 1;
public int $totalSteps = 0;
public bool $finished = false;
public int $correctAnswers = 0;
public ?int $lastAnswerIndex = null;
public ?bool $lastAnswerCorrect = null;
/** Lerni AI helper panel — toggled via showLerni; can be shared via URL (?lerni=1). */
#[Url(as: 'lerni', keep: false)]
public bool $showLerni = false;
public function mount(string $slug): void
{
$task = $this->findTask($slug);
abort_if($task === null, 404, "Task '{$slug}' not found.");
$this->slug = $slug;
$this->task = $task;
$this->questions = config("task-questions.{$slug}", []);
$this->totalSteps = count($this->questions);
abort_if($this->totalSteps === 0, 404, "No questions configured for task '{$slug}'.");
}
public static function placeholder(array $params = []): View
{
return view('livewire.tasks.run-placeholder');
}
public function currentQuestion(): array
{
return $this->questions[$this->currentStep - 1] ?? $this->questions[0];
}
public function submitAnswer(int $optionIndex): void
{
$q = $this->currentQuestion();
$isCorrect = $optionIndex === ($q['correct'] ?? -1);
$this->lastAnswerIndex = $optionIndex;
$this->lastAnswerCorrect = $isCorrect;
if ($isCorrect) {
$this->correctAnswers++;
}
}
public function nextStep(): void
{
if ($this->currentStep >= $this->totalSteps) {
$this->finished = true;
return;
}
$this->currentStep++;
$this->lastAnswerIndex = null;
$this->lastAnswerCorrect = null;
// Auto-close Lerni helper when moving to next question
$this->showLerni = false;
}
public function toggleLerni(): void
{
$this->showLerni = ! $this->showLerni;
}
public function restart(): void
{
$this->currentStep = 1;
$this->finished = false;
$this->correctAnswers = 0;
$this->lastAnswerIndex = null;
$this->lastAnswerCorrect = null;
$this->showLerni = false;
}
protected function findTask(string $slug): ?array
{
return collect(config('tasks', []))->firstWhere('slug', $slug);
}
public function render(): View
{
return view('livewire.tasks.run');
}
}