Files

192 lines
7.1 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace App\Filament\Pages\Radio;
use App\Models\RadioApiKey;
use Filament\Actions\Action;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
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 Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Table;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\HtmlString;
final class ApiKeys extends Page implements HasTable
{
use InteractsWithTable;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-key';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Radio';
#[\Override]
protected static ?string $navigationLabel = 'API Sleutels';
#[\Override]
protected static ?string $title = 'Radio API Sleutels';
#[\Override]
protected string $view = 'filament.pages.radio.api-keys';
public ?string $newKey = null;
public function table(Table $table): Table
{
return $table
->query(RadioApiKey::query())
->defaultSort('created_at', 'desc')
->columns([
TextColumn::make('name')
->label('Naam')
->searchable(),
TextColumn::make('key')
->label('API Key')
->formatStateUsing(fn ($state) => substr($state, 0, 16) . '...')
->copyable()
->copyMessage('Gekopieerd!'),
TextColumn::make('rate_limit')
->label('Rate Limit')
->badge()
->color('info'),
IconColumn::make('is_active')
->label('Actief')
->boolean()
->trueIcon('heroicon-o-check-circle')
->falseIcon('heroicon-o-x-circle')
->trueColor('success')
->falseColor('danger'),
TextColumn::make('last_used_at')
->label('Laatst gebruikt')
->dateTime('d-m-Y H:i')
->placeholder('Nooit'),
TextColumn::make('expires_at')
->label('Verloopt')
->dateTime('d-m-Y')
->placeholder('Nooit'),
TextColumn::make('created_at')
->label('Aangemaakt')
->dateTime('d-m-Y H:i'),
])
->actions([
Action::make('toggle')
->label(fn ($record) => $record->is_active ? 'Deactiveren' : 'Activeren')
->icon(fn ($record) => $record->is_active ? 'heroicon-o-pause' : 'heroicon-o-play')
->action(fn ($record) => $this->toggleKey($record)),
Action::make('delete')
->label('Verwijderen')
->icon('heroicon-o-trash')
->color('danger')
->requiresConfirmation()
->action(fn ($record) => $record->delete()),
])
->headerActions([
Action::make('create')
->label('Nieuwe API Sleutel')
->icon('heroicon-o-plus')
->color('primary')
->form([
TextInput::make('name')
->label('Naam')
->required()
->maxLength(255)
->placeholder('Bijv. Discord Bot, Mobiele App'),
TextInput::make('allowed_ips')
->label('Toegestane IP-adressen')
->placeholder('Leeg laten voor alle IPs (bijv. 1.2.3.4, 5.6.7.8)')
->helperText('Komma-gescheiden lijst van IP-adressen. Leeg = alle IPs toegestaan.'),
Select::make('rate_limit')
->label('Rate Limit (verzoeken per minuut)')
->options([
60 => '60/min',
100 => '100/min',
300 => '300/min',
500 => '500/min',
1000 => '1000/min',
])
->default(300),
Select::make('permissions')
->label('Permissies')
->multiple()
->options([
'*' => 'Alle permissies',
'now-playing' => 'Nu Afspelen',
'listeners' => 'Luisteraars',
'current-dj' => 'Huidige DJ',
'config' => 'Configuratie',
'shouts' => 'Shouts',
'points' => 'Punten',
'requests' => 'Song Requests',
])
->default(['*']),
Toggle::make('set_expiration')
->label('Vervaldatum instellen')
->live(),
TextInput::make('expires_at')
->label('Vervaldatum')
->type('date')
->visible(fn ($get) => $get('set_expiration')),
])
->action(function (array $data) {
$this->createKey($data);
}),
]);
}
private function createKey(array $data): void
{
$key = RadioApiKey::generate($data['name'], [
'allowed_ips' => $data['allowed_ips'] ?? null,
'permissions' => $data['permissions'] ?? ['*'],
'rate_limit' => $data['rate_limit'] ?? 300,
'expires_at' => ! empty($data['set_expiration']) && ! empty($data['expires_at'])
? $data['expires_at'] : null,
]);
$this->newKey = $key->key;
Notification::make()
->success()
->title('API Sleutel Aangemaakt!')
->body('Kopieer de sleutel nu - deze wordt niet meer getoond.')
->send();
}
private function toggleKey(RadioApiKey $key): void
{
$key->update(['is_active' => ! $key->is_active]);
Notification::make()
->success()
->title($key->is_active ? 'API Sleutel geactiveerd' : 'API Sleutel gedeactiveerd')
->send();
}
#[\Override]
protected function getHeaderActions(): array
{
return [];
}
public function getNewKey(): ?string
{
$key = $this->newKey;
$this->newKey = null;
return $key;
}
}