'tasks'])] #[Lazy] class Index extends Component { public static function placeholder(array $params = []): View { return view('livewire.tasks.placeholder'); } #[Url(as: 'filter', keep: true)] public string $filter = 'open'; /** @var array */ protected array $allowedFilters = ['open', 'done', 'all']; public function mount(): void { if (! in_array($this->filter, $this->allowedFilters, true)) { $this->filter = 'open'; } } public function setFilter(string $filter): void { if (in_array($filter, $this->allowedFilters, true)) { $this->filter = $filter; } } /** @var array */ public array $startedKeys = []; public function startTask(string $key): void { $task = collect($this->tasks)->firstWhere('key', $key); if ($task === null) { return; } if (! in_array($key, $this->startedKeys, true)) { $this->startedKeys[] = $key; } // Future: redirect to a real lesson runner. For now open detail modal. // Use $this->js() to emit a browser-side Livewire dispatch — server-side // $this->dispatch()->to(...) in Livewire 4 + wire-elements drops named // payload args, causing "$component dependency unresolved" in Modal::openModal. $payload = json_encode([ 'component' => 'tasks.modals.detail', 'arguments' => ['task' => $task], ], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR); $this->js("Livewire.dispatch('openModal', {$payload})"); } public function repeatTask(string $key): void { $this->startTask($key); } #[Computed] public function tasks(): array { return [ ['key' => 't1', 'title' => 'Multiplikation bis 100', 'meta' => 'Mathematik · 12 Aufgaben · 15 Min.', 'icon' => '∑', 'color' => 'primary', 'points' => 120, 'status' => 'open', 'due' => 'Heute'], ['key' => 't2', 'title' => 'Wortarten: Nomen & Verben', 'meta' => 'Deutsch · Lese-Aufgabe · 10 Min.', 'icon' => 'A', 'color' => 'rose', 'points' => 80, 'status' => 'open', 'due' => 'Heute'], ['key' => 't3', 'title' => 'Vocab Review: Animals', 'meta' => 'Englisch · Karteikarten · 8 Min.', 'icon' => 'E', 'color' => 'violet', 'points' => 60, 'status' => 'open', 'due' => 'Heute'], ['key' => 't4', 'title' => 'Kreislauf des Wassers', 'meta' => 'Sachkunde · Video + Quiz · 12 Min.', 'icon' => '🌱', 'color' => 'green', 'points' => 100, 'status' => 'open', 'due' => 'Heute'], ['key' => 't5', 'title' => 'Geometrie: Flächen', 'meta' => 'Mathematik · Übung · 20 Min.', 'icon' => '∑', 'color' => 'primary', 'points' => 150, 'status' => 'open', 'due' => 'Morgen'], ['key' => 't6', 'title' => 'Gedicht lernen', 'meta' => 'Deutsch · Lese-Aufgabe · 15 Min.', 'icon' => 'A', 'color' => 'rose', 'points' => 90, 'status' => 'done', 'due' => 'Gestern'], ['key' => 't7', 'title' => 'Past Simple Übung', 'meta' => 'Englisch · Übung · 10 Min.', 'icon' => 'E', 'color' => 'violet', 'points' => 70, 'status' => 'done', 'due' => 'Gestern'], ]; } #[Computed] public function filteredTasks(): array { if ($this->filter === 'all') { return $this->tasks; } return array_values(array_filter($this->tasks, fn($t) => $t['status'] === $this->filter)); } #[Computed] public function counts(): array { return [ 'open' => count(array_filter($this->tasks, fn($t) => $t['status'] === 'open')), 'done' => count(array_filter($this->tasks, fn($t) => $t['status'] === 'done')), 'all' => count($this->tasks), ]; } public function render(): View { return view('livewire.tasks.index'); } }