Files
Atomcms-edit/app/Filament/Pages/Radio/PointsSettings.php
T

246 lines
8.6 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace App\Filament\Pages\Radio;
use App\Models\Miscellaneous\WebsiteSetting;
use App\Models\RadioListenerPoint;
use App\Models\User;
use App\Services\PointsService;
use Filament\Actions\Action;
use Filament\Forms\Components\Slider;
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\Schema;
final class PointsSettings extends Page implements HasForms
{
use InteractsWithForms;
#[\Override]
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-currency-euro';
#[\Override]
protected static string|\UnitEnum|null $navigationGroup = 'Radio';
#[\Override]
protected static ?string $navigationLabel = null;
#[\Override]
public static function getNavigationLabel(): string
{
return __('Points System');
}
#[\Override]
protected static ?string $title = 'Punten Systeem';
#[\Override]
protected string $view = 'filament.pages.radio.points-settings';
/** @var array<string, mixed> */
public array $data = [];
private PointsService $pointsService;
public function __construct()
{
$this->pointsService = new PointsService;
}
public function mount(): void
{
$this->fillForm();
}
protected function fillForm(): void
{
$this->data = [
'points_enabled' => $this->getSettingBool('points_enabled'),
'points_per_minute' => (int) $this->getSetting('points_per_minute', '1'),
'max_points_per_day' => (int) $this->getSetting('max_points_per_day', '100'),
'points_for_request' => (int) $this->getSetting('points_for_request', '5'),
'points_for_vote' => (int) $this->getSetting('points_for_vote', '2'),
'points_for_giveaway_win' => (int) $this->getSetting('points_for_giveaway_win', '50'),
'points_for_contest_win' => (int) $this->getSetting('points_for_contest_win', '100'),
'points_for_shout' => (int) $this->getSetting('points_for_shout', '1'),
];
}
public function form(Schema $schema): Schema
{
return $schema
->components([
Section::make('Punten Configuratie')
->description('Configureer het punten systeem')
->columns(2)
->headerActions([
Action::make('save_points')
->label('Opslaan')
->action('savePoints')
->color('primary'),
])
->schema([
Toggle::make('points_enabled')
->label('Punten Systeem Inschakelen')
->columnSpanFull(),
Section::make('Luisteren')
->description('Punten voor luisteren')
->columns(1)
->schema([
Slider::make('points_per_minute')
->label('Punten per Minuut')
->minValue(0)
->maxValue(10)
->step(0.5)
->default(1),
TextInput::make('max_points_per_day')
->label('Max. Punten per Dag')
->numeric()
->default(100),
]),
Section::make('Acties')
->description('Punten voor acties')
->columns(1)
->schema([
TextInput::make('points_for_request')
->label('Punten voor Song Request')
->numeric()
->default(5),
TextInput::make('points_for_vote')
->label('Punten voor Stemmen')
->numeric()
->default(2),
TextInput::make('points_for_shout')
->label('Punten voor Shout')
->numeric()
->default(1),
]),
Section::make('Winnaars')
->description('Punten voor winst')
->columns(1)
->schema([
TextInput::make('points_for_giveaway_win')
->label('Punten voor Winactie Winst')
->numeric()
->default(50),
TextInput::make('points_for_contest_win')
->label('Punten voor Competitie Winst')
->numeric()
->default(100),
]),
]),
Section::make('Acties')
->description('Systeem acties')
->columns(2)
->schema([
Action::make('reset_leaderboard')
->label('Leaderboard Resetten')
->action('resetLeaderboard')
->color('warning')
->requiresConfirmation(),
Action::make('view_stats')
->label('Bekijk Statistieken')
->action('viewStats')
->color('info'),
Action::make('export_leaderboard')
->label('Exporteren')
->action('exportLeaderboard')
->color('secondary'),
]),
])
->statePath('data');
}
public function savePoints(): void
{
$keys = [
'points_enabled',
'points_per_minute',
'max_points_per_day',
'points_for_request',
'points_for_vote',
'points_for_shout',
'points_for_giveaway_win',
'points_for_contest_win',
];
foreach ($keys as $key) {
$value = $this->data[$key] ?? '';
if ($key === 'points_enabled') {
$dbValue = $value ? '1' : '0';
} else {
$dbValue = (string) $value;
}
WebsiteSetting::updateOrCreate(['key' => $key], ['value' => $dbValue]);
}
$this->pointsService->clearSettingsCache();
$this->fillForm();
Notification::make()
->success()
->title(__('Saved'))
->body('Punten instellingen zijn bijgewerkt!')
->send();
}
public function resetLeaderboard(): void
{
User::query()->where('radio_points', '>', 0)->each(fn (User $u) => $u->forceFill(['radio_points' => 0])->save());
RadioListenerPoint::query()->delete();
$this->pointsService->clearLeaderboardCache();
$this->fillForm();
Notification::make()
->success()
->title('Leaderboard Gereset')
->body('Alle punten zijn gewist.')
->send();
}
public function viewStats(): void
{
$stats = $this->pointsService->getStats();
Notification::make()
->title('Punten Statistieken')
->body(
"Totale punten: {$stats['total_points_awarded']}\n" .
"Actieve gebruikers: {$stats['total_active_users']}",
)
->info()
->send();
}
public function exportLeaderboard(): void
{
Notification::make()
->info()
->title('Export Gestart')
->body('Leaderboard wordt gedownload...')
->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;
}
}