Fix SSE listeners type cast, replace Blade tab component with Alpine.js tabs in DjModeration, use wire:confirm instead of onclick

This commit is contained in:
root
2026-05-24 14:15:44 +02:00
parent 0c6c558a59
commit 261a5e63c6
27 changed files with 142 additions and 136 deletions
View File
View File
+136 -130
View File
@@ -7,145 +7,151 @@ use App\Models\RadioSongRequest;
?>
<x-filament-panels::page>
<x-filament::tabs>
<div x-data="{ tab: 'shouts' }">
<div class="flex gap-1 mb-6 border-b border-gray-200 dark:border-gray-700">
<button @click="tab = 'shouts'" :class="{ 'border-primary-600 text-primary-600': tab === 'shouts', 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300': tab !== 'shouts' }" class="px-4 py-2 text-sm font-medium border-b-2 transition flex items-center gap-2">
<x-filament::icon name="heroicon-o-chat-bubble-oval-left" class="w-4 h-4" />
Shouts
<span class="inline-flex items-center justify-center px-2 py-0.5 text-xs font-medium rounded-full bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400">{{ RadioShout::where('approved', false)->count() }}</span>
</button>
<button @click="tab = 'requests'" :class="{ 'border-primary-600 text-primary-600': tab === 'requests', 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300': tab !== 'requests' }" class="px-4 py-2 text-sm font-medium border-b-2 transition flex items-center gap-2">
<x-filament::icon name="heroicon-o-musical-note" class="w-4 h-4" />
Verzoeken
<span class="inline-flex items-center justify-center px-2 py-0.5 text-xs font-medium rounded-full bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400">{{ RadioSongRequest::where('is_approved', false)->where('is_played', false)->count() }}</span>
</button>
<button @click="tab = 'applications'" :class="{ 'border-primary-600 text-primary-600': tab === 'applications', 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300': tab !== 'applications' }" class="px-4 py-2 text-sm font-medium border-b-2 transition flex items-center gap-2">
<x-filament::icon name="heroicon-o-user-group" class="w-4 h-4" />
Aanmeldingen
<span class="inline-flex items-center justify-center px-2 py-0.5 text-xs font-medium rounded-full bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400">{{ RadioApplication::where('status', 'pending')->count() }}</span>
</button>
</div>
{{-- Shouts Tab --}}
<x-filament::tabs.tab
icon="heroicon-o-chat-bubble-oval-left"
label="Shouts ({{ RadioShout::where('approved', false)->count() }} wachtend, {{ RadioShout::where('reported', true)->count() }} gerapporteerd)"
>
<div class="space-y-4">
@php $pendingShouts = $this->getPendingShouts(); @endphp
@if($pendingShouts->count() > 0)
<h3 class="text-lg font-semibold">Wachtend op goedkeuring</h3>
<div class="space-y-2">
@foreach($pendingShouts as $shout)
<div class="bg-gray-50 dark:bg-gray-900 rounded-lg p-4 flex items-start justify-between gap-4">
<div class="flex-1 min-w-0">
<p class="font-medium text-sm">{{ $shout->user?->username ?? 'Onbekend' }}</p>
<p class="text-sm text-gray-600 dark:text-gray-400 truncate">{{ $shout->message }}</p>
<p class="text-xs text-gray-400 mt-1">{{ $shout->created_at->diffForHumans() }}</p>
</div>
<div class="flex gap-2 shrink-0">
<x-filament::button wire:click="approveShout({{ $shout->id }})" color="success" size="xs" icon="heroicon-o-check">
Goedkeuren
</x-filament::button>
<x-filament::button wire:click="deleteShout({{ $shout->id }})" color="danger" size="xs" icon="heroicon-o-trash" onclick="return confirm('Zeker weten?')">
Verwijderen
</x-filament::button>
</div>
</div>
@endforeach
{{ $pendingShouts->links() }}
</div>
@endif
<div x-show="tab === 'shouts'">
@php $pendingShouts = $this->getPendingShouts(); @endphp
@php $reportedShouts = $this->getReportedShouts(); @endphp
@php $reportedShouts = $this->getReportedShouts(); @endphp
@if($reportedShouts->count() > 0)
<h3 class="text-lg font-semibold mt-6">Gerapporteerde shouts</h3>
<div class="space-y-2">
@foreach($reportedShouts as $shout)
<div class="bg-red-50 dark:bg-red-950 rounded-lg p-4 flex items-start justify-between gap-4">
<div class="flex-1 min-w-0">
<p class="font-medium text-sm">{{ $shout->user?->username ?? 'Onbekend' }}</p>
<p class="text-sm text-gray-600 dark:text-gray-400 truncate">{{ $shout->message }}</p>
<p class="text-xs text-gray-400 mt-1">{{ $shout->created_at->diffForHumans() }}</p>
</div>
<div class="flex gap-2 shrink-0">
<x-filament::button wire:click="dismissShoutReport({{ $shout->id }})" color="info" size="xs" icon="heroicon-o-flag">
Negeren
</x-filament::button>
<x-filament::button wire:click="deleteShout({{ $shout->id }})" color="danger" size="xs" icon="heroicon-o-trash" onclick="return confirm('Zeker weten?')">
Verwijderen
</x-filament::button>
</div>
@if($pendingShouts->count() > 0)
<h3 class="text-lg font-semibold mb-3">Wachtend op goedkeuring</h3>
<div class="space-y-2 mb-6">
@foreach($pendingShouts as $shout)
<div class="bg-gray-50 dark:bg-gray-900 rounded-lg p-4 flex items-start justify-between gap-4">
<div class="flex-1 min-w-0">
<p class="font-medium text-sm">{{ $shout->user?->username ?? 'Onbekend' }}</p>
<p class="text-sm text-gray-600 dark:text-gray-400 truncate">{{ $shout->message }}</p>
<p class="text-xs text-gray-400 mt-1">{{ $shout->created_at->diffForHumans() }}</p>
</div>
@endforeach
{{ $reportedShouts->links() }}
</div>
@endif
<div class="flex gap-2 shrink-0">
<x-filament::button wire:click="approveShout({{ $shout->id }})" color="success" size="xs" icon="heroicon-o-check">
Goedkeuren
</x-filament::button>
<x-filament::button wire:click="deleteShout({{ $shout->id }})" color="danger" size="xs" icon="heroicon-o-trash" wire:confirm="Zeker weten?">
Verwijderen
</x-filament::button>
</div>
</div>
@endforeach
{{ $pendingShouts->links() }}
</div>
@endif
@if($pendingShouts->count() === 0 && $reportedShouts->count() === 0)
<p class="text-gray-500 text-center py-8">Geen shouts wachtend op moderatie</p>
@endif
</div>
</x-filament::tabs.tab>
@if($reportedShouts->count() > 0)
<h3 class="text-lg font-semibold mb-3">Gerapporteerde shouts</h3>
<div class="space-y-2">
@foreach($reportedShouts as $shout)
<div class="bg-red-50 dark:bg-red-950 rounded-lg p-4 flex items-start justify-between gap-4">
<div class="flex-1 min-w-0">
<p class="font-medium text-sm">{{ $shout->user?->username ?? 'Onbekend' }}</p>
<p class="text-sm text-gray-600 dark:text-gray-400 truncate">{{ $shout->message }}</p>
<p class="text-xs text-gray-400 mt-1">{{ $shout->created_at->diffForHumans() }}</p>
</div>
<div class="flex gap-2 shrink-0">
<x-filament::button wire:click="dismissShoutReport({{ $shout->id }})" color="info" size="xs" icon="heroicon-o-flag">
Negeren
</x-filament::button>
<x-filament::button wire:click="deleteShout({{ $shout->id }})" color="danger" size="xs" icon="heroicon-o-trash" wire:confirm="Zeker weten?">
Verwijderen
</x-filament::button>
</div>
</div>
@endforeach
{{ $reportedShouts->links() }}
</div>
@endif
@if($pendingShouts->count() === 0 && $reportedShouts->count() === 0)
<p class="text-gray-500 text-center py-8">Geen shouts wachtend op moderatie</p>
@endif
</div>
{{-- Song Requests Tab --}}
<x-filament::tabs.tab
icon="heroicon-o-musical-note"
label="Verzoeken ({{ RadioSongRequest::where('is_approved', false)->where('is_played', false)->count() }} wachtend)"
>
<div class="space-y-4">
@php $requests = $this->getPendingRequests(); @endphp
@if($requests->count() > 0)
<div class="space-y-2">
@foreach($requests as $request)
<div class="bg-gray-50 dark:bg-gray-900 rounded-lg p-4 flex items-start justify-between gap-4">
<div class="flex-1 min-w-0">
<p class="font-medium text-sm">{{ $request->user?->username ?? 'Onbekend' }}</p>
<p class="text-sm font-semibold">{{ $request->song_title }}</p>
<p class="text-sm text-gray-500" x-show="{{ $request->song_artist }}">{{ $request->song_artist }}</p>
<div class="flex items-center gap-3 mt-1">
<span class="text-xs text-gray-400">{{ $request->submitted_at->diffForHumans() }}</span>
<span class="text-xs text-amber-500">{{ $request->votes }} stemmen</span>
</div>
</div>
<div class="flex gap-2 shrink-0">
<x-filament::button wire:click="approveRequest({{ $request->id }})" color="success" size="xs" icon="heroicon-o-check">
Goedkeuren
</x-filament::button>
<x-filament::button wire:click="rejectRequest({{ $request->id }})" color="danger" size="xs" icon="heroicon-o-x-mark" onclick="return confirm('Zeker weten?')">
Afwijzen
</x-filament::button>
<div x-show="tab === 'requests'">
@php $requests = $this->getPendingRequests(); @endphp
@if($requests->count() > 0)
<div class="space-y-2">
@foreach($requests as $request)
<div class="bg-gray-50 dark:bg-gray-900 rounded-lg p-4 flex items-start justify-between gap-4">
<div class="flex-1 min-w-0">
<p class="font-medium text-sm">{{ $request->user?->username ?? 'Onbekend' }}</p>
<p class="text-sm font-semibold">{{ $request->song_title }}</p>
@if($request->song_artist)
<p class="text-sm text-gray-500">{{ $request->song_artist }}</p>
@endif
<div class="flex items-center gap-3 mt-1">
<span class="text-xs text-gray-400">{{ $request->submitted_at->diffForHumans() }}</span>
<span class="text-xs text-amber-500">{{ $request->votes }} stemmen</span>
</div>
</div>
@endforeach
{{ $requests->links() }}
</div>
@else
<p class="text-gray-500 text-center py-8">Geen verzoeken wachtend op goedkeuring</p>
@endif
</div>
</x-filament::tabs.tab>
<div class="flex gap-2 shrink-0">
<x-filament::button wire:click="approveRequest({{ $request->id }})" color="success" size="xs" icon="heroicon-o-check">
Goedkeuren
</x-filament::button>
<x-filament::button wire:click="rejectRequest({{ $request->id }})" color="danger" size="xs" icon="heroicon-o-x-mark" wire:confirm="Zeker weten?">
Afwijzen
</x-filament::button>
</div>
</div>
@endforeach
{{ $requests->links() }}
</div>
@else
<p class="text-gray-500 text-center py-8">Geen verzoeken wachtend op goedkeuring</p>
@endif
</div>
{{-- Applications Tab --}}
<x-filament::tabs.tab
icon="heroicon-o-user-group"
label="Aanmeldingen ({{ RadioApplication::where('status', 'pending')->count() }} wachtend)"
>
<div class="space-y-4">
@php $applications = $this->getPendingApplications(); @endphp
@if($applications->count() > 0)
<div class="space-y-2">
@foreach($applications as $app)
<div class="bg-gray-50 dark:bg-gray-900 rounded-lg p-4 flex items-start justify-between gap-4">
<div class="flex-1 min-w-0">
<p class="font-medium">{{ $app->user?->username ?? 'Onbekend' }}</p>
<p class="text-sm text-gray-600 dark:text-gray-400">
{{ $app->rank?->name ?? 'Geen functie' }} &middot; {{ $app->age }} jaar
</p>
<p class="text-sm mt-2">{{ $app->motivation }}</p>
@if($app->experience)
<p class="text-xs text-gray-400 mt-1">Ervaring: {{ $app->experience }}</p>
@endif
<p class="text-xs text-gray-400 mt-1">{{ $app->created_at->diffForHumans() }}</p>
</div>
<div class="flex gap-2 shrink-0">
<x-filament::button wire:click="approveApplication({{ $app->id }})" color="success" size="xs" icon="heroicon-o-check" onclick="return confirm('Aanmelding goedkeuren?')">
Goedkeuren
</x-filament::button>
<x-filament::button wire:click="rejectApplication({{ $app->id }})" color="danger" size="xs" icon="heroicon-o-x-mark" onclick="return confirm('Aanmelding afwijzen?')">
Afwijzen
</x-filament::button>
</div>
<div x-show="tab === 'applications'">
@php $applications = $this->getPendingApplications(); @endphp
@if($applications->count() > 0)
<div class="space-y-2">
@foreach($applications as $app)
<div class="bg-gray-50 dark:bg-gray-900 rounded-lg p-4 flex items-start justify-between gap-4">
<div class="flex-1 min-w-0">
<p class="font-medium">{{ $app->user?->username ?? 'Onbekend' }}</p>
<p class="text-sm text-gray-600 dark:text-gray-400">
{{ $app->rank?->name ?? 'Geen functie' }} &middot; {{ $app->age }} jaar
</p>
<p class="text-sm mt-2">{{ $app->motivation }}</p>
@if($app->experience)
<p class="text-xs text-gray-400 mt-1">Ervaring: {{ $app->experience }}</p>
@endif
<p class="text-xs text-gray-400 mt-1">{{ $app->created_at->diffForHumans() }}</p>
</div>
@endforeach
{{ $applications->links() }}
</div>
@else
<p class="text-gray-500 text-center py-8">Geen aanmeldingen wachtend</p>
@endif
</div>
</x-filament::tabs.tab>
</x-filament::tabs>
<div class="flex gap-2 shrink-0">
<x-filament::button wire:click="approveApplication({{ $app->id }})" color="success" size="xs" icon="heroicon-o-check" wire:confirm="Aanmelding goedkeuren?">
Goedkeuren
</x-filament::button>
<x-filament::button wire:click="rejectApplication({{ $app->id }})" color="danger" size="xs" icon="heroicon-o-x-mark" wire:confirm="Aanmelding afwijzen?">
Afwijzen
</x-filament::button>
</div>
</div>
@endforeach
{{ $applications->links() }}
</div>
@else
<p class="text-gray-500 text-center py-8">Geen aanmeldingen wachtend</p>
@endif
</div>
</div>
</x-filament-panels::page>
View File
View File