Initial commit

This commit is contained in:
root
2026-05-09 17:28:23 +02:00
commit 9d73f82529
5575 changed files with 281989 additions and 0 deletions
+310
View File
@@ -0,0 +1,310 @@
<?php
declare(strict_types=1);
namespace App\Filament\Pages\Radio;
use App\Models\Miscellaneous\WebsiteSetting;
use App\Services\StreamMonitoringService;
use Filament\Actions\Action;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Components\Tabs\Tab;
use Filament\Schemas\Schema;
use Illuminate\Support\Facades\Http;
final class StreamMonitoring extends Page implements HasForms
{
use InteractsWithForms;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-signal';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Radio';
#[\Override]
protected static ?string $navigationLabel = null;
#[\Override]
public static function getNavigationLabel(): string
{
return __('Stream Status');
}
#[\Override]
protected static ?string $title = 'Stream Monitoring';
#[\Override]
protected string $view = 'filament.pages.radio.stream-monitoring';
/** @var array<string, mixed> */
public array $data = [];
private StreamMonitoringService $monitoringService;
public function __construct()
{
$this->monitoringService = new StreamMonitoringService;
}
public function mount(): void
{
$this->fillForm();
}
protected function fillForm(): void
{
$this->data = [
'radio_stream_url' => $this->getSetting('radio_stream_url', ''),
'radio_monitoring_enabled' => $this->getSettingBool('radio_monitoring_enabled'),
'radio_monitoring_interval' => (int) $this->getSetting('radio_monitoring_interval', '5'),
'radio_alert_email' => $this->getSetting('radio_alert_email', ''),
'radio_alert_enabled' => $this->getSettingBool('radio_alert_enabled'),
];
}
public function form(Schema $schema): Schema
{
return $schema
->components([
Tabs::make('Monitoring')
->tabs([
Tab::make('Huidige Status')
->icon('heroicon-o-signal')
->schema([
Section::make('Stream Status')
->description('Real-time stream monitoring')
->columns(2)
->headerActions([
Action::make('refresh')
->label('Vernieuwen')
->action('refreshStatus')
->color('primary')
->icon('heroicon-o-arrow-path'),
])
->schema([
Section::make('Info')
->description('Stream informatie')
->columns(1)
->schema([
TextInput::make('status.online')
->label('Status')
->disabled(),
TextInput::make('status.listeners')
->label('Luisteraars')
->disabled(),
TextInput::make('status.bitrate')
->label('Bitrate')
->disabled(),
TextInput::make('status.format')
->label('Formaat')
->disabled(),
TextInput::make('status.server')
->label('Server')
->disabled(),
]),
]),
Section::make('Uptime')
->description('Uptime statistieken')
->columns(2)
->schema([
TextInput::make('uptime.last_online')
->label('Laatst Online')
->disabled(),
TextInput::make('uptime.uptime_pct')
->label('Uptime %')
->disabled(),
]),
]),
Tab::make('Instellingen')
->icon('heroicon-o-cog-6-tooth')
->schema([
Section::make('Monitoring Configuratie')
->description('Configureer monitoring')
->columns(2)
->headerActions([
Action::make('save_monitoring')
->label('Opslaan')
->action('saveMonitoring')
->color('primary'),
])
->schema([
Toggle::make('radio_monitoring_enabled')
->label('Monitoring Inschakelen')
->columnSpanFull(),
TextInput::make('radio_monitoring_interval')
->label('Check Interval (minuten)')
->numeric()
->default(5),
]),
Section::make('Alert Instellingen')
->description('Alert e-mails')
->columns(2)
->headerActions([
Action::make('test_alert')
->label('Test Alert')
->action('testAlert')
->color('info'),
])
->schema([
Toggle::make('radio_alert_enabled')
->label('Alerts Inschakelen')
->columnSpanFull(),
TextInput::make('radio_alert_email')
->label('Alert E-mail')
->email()
->placeholder('admin@jouwdomein.nl'),
]),
Section::make('Stream URL')
->description('Stream configuratie')
->columns(1)
->schema([
TextInput::make('radio_stream_url')
->label('Stream URL')
->url()
->placeholder('https://radio.nl/stream')
->columnSpanFull(),
Action::make('test_stream')
->label('Test Stream')
->action('testStream')
->color('success'),
]),
]),
]),
])
->statePath('data');
}
public function refreshStatus(): void
{
$status = $this->monitoringService->getStatus();
$this->data['status'] = [
'online' => $status['online'] ? 'Online' : 'Offline',
'listeners' => $status['listeners'],
'bitrate' => $status['bitrate'] ? $status['bitrate'] . ' kbps' : 'N/A',
'format' => $status['format'] ?? 'N/A',
'server' => $status['server_type'] ?? 'N/A',
];
$uptime = $this->monitoringService->getUptime();
$this->data['uptime'] = [
'last_online' => $uptime['last_online_human'] ?? 'Nooit',
'uptime_pct' => ($uptime['uptime_percentage'] ?? 0) . '%',
];
$this->fillForm();
Notification::make()
->success()
->title('Status Vernieuwd')
->body($status['online'] ? 'Stream is Online' : 'Stream is Offline')
->send();
}
public function saveMonitoring(): void
{
$keys = [
'radio_monitoring_enabled', 'radio_monitoring_interval',
'radio_alert_enabled', 'radio_alert_email',
];
foreach ($keys as $key) {
$value = $this->data[$key] ?? '';
if (in_array($key, ['radio_monitoring_enabled', 'radio_alert_enabled'])) {
$dbValue = $value ? '1' : '0';
} else {
$dbValue = (string) $value;
}
WebsiteSetting::updateOrCreate(['key' => $key], ['value' => $dbValue]);
}
$this->fillForm();
Notification::make()
->success()
->title(__('Saved'))
->body('Monitoring instellingen zijn bijgewerkt!')
->send();
}
public function testStream(): void
{
$url = $this->data['radio_stream_url'] ?? '';
if (empty($url)) {
Notification::make()
->warning()
->title('URL Ontbreekt')
->body('Voer eerst een stream URL in.')
->send();
return;
}
try {
$response = Http::timeout(10)->head($url);
if ($response->successful()) {
Notification::make()
->success()
->title('Stream Bereikbaar!')
->body('De stream URL is correct.')
->send();
} else {
Notification::make()
->danger()
->title('Stream Niet Bereikbaar')
->body('Status: ' . $response->status())
->send();
}
} catch (\Exception $e) {
Notification::make()
->danger()
->title('Verbindingsfout')
->body($e->getMessage())
->send();
}
}
public function testAlert(): void
{
$email = $this->data['radio_alert_email'] ?? '';
if (empty($email) || ! filter_var($email, FILTER_VALIDATE_EMAIL)) {
Notification::make()
->warning()
->title('Ongeldig E-mail')
->body('Voer een geldig e-mailadres in.')
->send();
return;
}
Notification::make()
->info()
->title('Test Alert')
->body('Test alert zou verstuurd moeten worden.')
->send();
}
private function getSettingBool(string $key): bool
{
return (bool) WebsiteSetting::where('key', $key)->first()?->value;
}
private function getSetting(string $key, string $default = ''): string
{
return WebsiteSetting::where('key', $key)->first()?->value ?? $default;
}
}