lernschiff/resources/views/livewire/tasks/index.blade.php

120 lines
6.5 KiB
PHP

@php
$colorMap = [
'primary' => ['bg' => 'bg-primary-soft', 'ink' => 'text-primary-ink'],
'rose' => ['bg' => 'bg-rose-soft', 'ink' => 'text-rose-ink'],
'violet' => ['bg' => 'bg-violet-soft', 'ink' => 'text-violet-ink'],
'green' => ['bg' => 'bg-green-soft', 'ink' => 'text-green-ink'],
'amber' => ['bg' => 'bg-amber-soft', 'ink' => 'text-amber-ink'],
];
@endphp
<div class="flex flex-col gap-6">
<header class="flex justify-between items-end gap-6">
<div>
<div class="text-[11px] uppercase tracking-[0.14em] text-ink-3 font-semibold mb-1.5">Heute</div>
<h1 class="text-[28px] leading-tight font-extrabold tracking-tight text-ink-1">Aufgaben</h1>
<p class="text-sm text-ink-2 mt-2 max-w-xl leading-relaxed">Deine offenen Aufgaben sortiert nach Fälligkeit und Punkten.</p>
</div>
<x-btn variant="primary" size="lg">
<x-heroicon-s-play class="w-4 h-4" />
Alle starten
</x-btn>
</header>
{{-- Filter Pills (URL-synced via #[Url]) --}}
<div class="flex gap-2" wire:key="filter-bar">
@foreach(['open' => 'Offen', 'done' => 'Erledigt', 'all' => 'Alle'] as $key => $label)
<button
type="button"
wire:click="setFilter('{{ $key }}')"
wire:loading.attr="disabled"
class="inline-flex items-center gap-2 px-3 py-1.5 rounded-full border text-xs font-semibold transition-all cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1 {{ $filter === $key ? 'bg-ink-1 text-bg-base border-ink-1' : 'bg-bg-soft text-ink-2 border-line hover:bg-bg-tint' }}"
data-testid="filter-{{ $key }}"
@if($filter === $key) aria-current="page" @endif
>
@if($key === 'open')
<x-heroicon-o-clock class="w-3.5 h-3.5" />
@elseif($key === 'done')
<x-heroicon-o-check-circle class="w-3.5 h-3.5" />
@endif
{{ $label }} <span class="font-mono tabular-nums">({{ $this->counts[$key] }})</span>
</button>
@endforeach
</div>
{{-- Skeleton during filter switch bg-bg-tint container, bg-line bars for contrast --}}
<div wire:loading.flex wire:target="setFilter" class="hidden flex-col bg-bg-soft border border-line rounded-xl p-5 shadow-sm" data-testid="tasks-skeleton">
@for($i = 0; $i < 4; $i++)
<div class="grid grid-cols-[44px_1fr_auto] gap-3 items-center py-3 border-t border-line first:border-t-0 animate-pulse">
<div class="w-10 h-10 rounded-lg bg-line"></div>
<div class="flex flex-col gap-2">
<div class="h-3 bg-line rounded w-3/5"></div>
<div class="h-2 bg-line rounded w-2/5"></div>
</div>
<div class="flex items-center gap-3">
<div class="h-3 bg-line rounded w-16"></div>
<div class="h-7 bg-line rounded w-20"></div>
</div>
</div>
@endfor
</div>
{{-- Task list modal triggered ONLY by Detail button, row itself is passive --}}
<x-card class="shadow-sm" wire:loading.remove wire:target="setFilter">
@if(empty($this->filteredTasks))
<div class="py-8 text-center text-sm text-ink-3">Keine Aufgaben in dieser Ansicht.</div>
@else
<div class="flex flex-col">
@foreach($this->filteredTasks as $t)
@php $c = $colorMap[$t['color']]; @endphp
<div
wire:key="task-{{ $t['slug'] }}"
class="group grid grid-cols-[44px_1fr_auto] gap-3 items-center py-3 border-t border-line first:border-t-0"
data-testid="task-row"
>
<div class="w-10 h-10 rounded-lg {{ $c['bg'] }} {{ $c['ink'] }} grid place-items-center font-bold">
{{ $t['icon'] }}
</div>
<div class="min-w-0">
<div class="flex items-center gap-2">
<div class="font-semibold text-sm text-ink-1 truncate">{{ $t['title'] }}</div>
@if($t['status'] === 'done')
<x-heroicon-s-check-circle class="w-4 h-4 text-green-ink shrink-0" />
@endif
</div>
<div class="text-xs text-ink-3 mt-0.5 truncate">{{ $t['meta'] }} · {{ $t['due'] }}</div>
</div>
<div class="flex items-center gap-2">
<span class="font-mono tabular-nums text-xs text-amber-ink font-bold">+{{ $t['points'] }} Pkt.</span>
<button
type="button"
wire:click="$dispatch('openModal', { component: 'tasks.modals.detail', arguments: { task: {{ \Illuminate\Support\Js::from($t) }} } })"
class="w-8 h-8 grid place-items-center rounded-lg border border-line bg-bg-soft text-ink-2 hover:bg-bg-tint hover:text-ink-1 transition-all cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1"
aria-label="Details anzeigen"
data-testid="task-detail-btn"
>
<x-heroicon-o-information-circle class="w-4 h-4" />
</button>
@if($t['status'] === 'open')
<x-btn variant="primary" size="sm"
wire:click="startTask('{{ $t['slug'] }}')"
data-testid="task-start-btn">
Starten
</x-btn>
@else
<x-btn size="sm"
wire:click="repeatTask('{{ $t['slug'] }}')"
data-testid="task-repeat-btn">
Wiederholen
</x-btn>
@endif
</div>
</div>
@endforeach
</div>
@endif
</x-card>
</div>