Files
Atomcms-edit/app/Filament/Pages/Radio/DjModeration.php
T
root 0c6c558a59 Add radio embed widget, SSE real-time, song history, moderation panel, and Auto DJ
- Embed widget: standalone iframe player with dark/light/transparent themes, copy-paste embed code admin page
- Real-time SSE: streaming now-playing/listeners/dj events, replaces polling in radio-player and embed
- Song history: auto-records song changes to radio_song_plays table, Filament resource to view
- DJ moderation: unified panel for shouts approval, song request queue, DJ applications
- Auto DJ: playlist management with round-robin playback when no DJ is live
- Refactored radio-player Alpine component to use EventSource API with auto-reconnect
2026-05-24 14:07:32 +02:00

147 lines
4.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Filament\Pages\Radio;
use App\Models\RadioApplication;
use App\Models\RadioShout;
use App\Models\RadioSongRequest;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
final class DjModeration extends Page
{
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-shield-check';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Radio';
#[\Override]
protected static ?string $navigationLabel = 'Moderatie';
#[\Override]
protected static ?string $title = 'DJ Moderatie';
#[\Override]
protected string $view = 'filament.pages.radio.dj-moderation';
public function getShouts()
{
return RadioShout::with('user')->latest()->paginate(20);
}
public function getPendingShouts()
{
return RadioShout::with('user')->where('approved', false)->latest()->paginate(20);
}
public function getReportedShouts()
{
return RadioShout::with('user')->where('reported', true)->latest()->paginate(20);
}
public function getRequests()
{
return RadioSongRequest::with('user')->latest('submitted_at')->paginate(20);
}
public function getPendingRequests()
{
return RadioSongRequest::with('user')->where('is_approved', false)->where('is_played', false)->latest('submitted_at')->paginate(20);
}
public function getApplications()
{
return RadioApplication::with(['user', 'rank'])->latest()->paginate(20);
}
public function getPendingApplications()
{
return RadioApplication::with(['user', 'rank'])->where('status', 'pending')->latest()->paginate(20);
}
public function approveShout(int $id): void
{
$shout = RadioShout::findOrFail($id);
$shout->update([
'approved' => true,
'approved_by' => auth()->id(),
'approved_at' => now(),
]);
Notification::make()->success()->title('Shout goedgekeurd')->send();
}
public function dismissShoutReport(int $id): void
{
$shout = RadioShout::findOrFail($id);
$shout->update(['reported' => false, 'reported_by' => null]);
Notification::make()->success()->title('Melding genegeerd')->send();
}
public function deleteShout(int $id): void
{
RadioShout::findOrFail($id)->delete();
Notification::make()->success()->title('Shout verwijderd')->send();
}
public function approveRequest(int $id): void
{
$request = RadioSongRequest::findOrFail($id);
$request->approve();
Notification::make()->success()->title('Verzoek goedgekeurd')->send();
}
public function markRequestPlayed(int $id): void
{
$request = RadioSongRequest::findOrFail($id);
$request->markAsPlayed();
Notification::make()->success()->title('Verzoek gemarkeerd als gespeeld')->send();
}
public function rejectRequest(int $id): void
{
$request = RadioSongRequest::findOrFail($id);
$request->update(['is_approved' => false]);
Notification::make()->success()->title('Verzoek afgewezen')->send();
}
public function approveApplication(int $id): void
{
$application = RadioApplication::findOrFail($id);
$application->update([
'status' => 'approved',
'approved_by' => auth()->id(),
'approved_at' => now(),
]);
Notification::make()->success()->title('Aanmelding goedgekeurd')->send();
}
public function rejectApplication(int $id): void
{
$application = RadioApplication::findOrFail($id);
$application->update([
'status' => 'rejected',
'rejected_by' => auth()->id(),
'rejected_at' => now(),
]);
Notification::make()->success()->title('Aanmelding afgewezen')->send();
}
#[\Override]
protected function getHeaderActions(): array
{
return [];
}
}