106 lines
4.0 KiB
PHP
106 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Tasks;
|
|
|
|
use Illuminate\Contracts\View\View;
|
|
use Livewire\Attributes\Computed;
|
|
use Livewire\Attributes\Lazy;
|
|
use Livewire\Attributes\Layout;
|
|
use Livewire\Attributes\Url;
|
|
use Livewire\Component;
|
|
|
|
#[Layout('layouts.dashboard', ['active' => 'tasks'])]
|
|
#[Lazy]
|
|
class Index extends Component
|
|
{
|
|
public static function placeholder(array $params = []): View
|
|
{
|
|
return view('components.skeleton.page', ['rows' => 5]);
|
|
}
|
|
|
|
|
|
#[Url(as: 'filter', keep: true)]
|
|
public string $filter = 'open';
|
|
|
|
/** @var array<int,string> */
|
|
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<int,string> */
|
|
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.
|
|
// Must target wire-elements modal component explicitly — Livewire 4
|
|
// server-side dispatch does not auto-broadcast to other components.
|
|
$this->dispatch('openModal', component: 'tasks.modals.detail', arguments: ['task' => $task])
|
|
->to('livewire-ui-modal');
|
|
}
|
|
|
|
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');
|
|
}
|
|
}
|