You've already forked Atomcms-edit
Initial commit
This commit is contained in:
+239
@@ -0,0 +1,239 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Pages\Radio;
|
||||
|
||||
use App\Models\RadioContest;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
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 ContestManagement extends Page implements HasForms
|
||||
{
|
||||
use InteractsWithForms;
|
||||
|
||||
#[\Override]
|
||||
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-trophy';
|
||||
|
||||
#[\Override]
|
||||
protected static string|\UnitEnum|null $navigationGroup = 'Radio';
|
||||
|
||||
#[\Override]
|
||||
protected static ?string $navigationLabel = null;
|
||||
|
||||
#[\Override]
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return __('Contests');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected static ?string $title = 'Competities Beheer';
|
||||
|
||||
#[\Override]
|
||||
protected string $view = 'filament.pages.radio.contest-management';
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
public array $data = [];
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->fillForm();
|
||||
}
|
||||
|
||||
protected function fillForm(): void
|
||||
{
|
||||
$contests = RadioContest::orderBy('created_at', 'desc')->get();
|
||||
|
||||
$this->data['contests'] = $contests->toArray();
|
||||
$this->data['active_contest'] = $contests->firstWhere('is_active', true)?->id;
|
||||
}
|
||||
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Section::make('Nieuwe Competitie Aanmaken')
|
||||
->description('Maak een nieuwe competitie aan')
|
||||
->columns(1)
|
||||
->headerActions([
|
||||
Action::make('create_contest')
|
||||
->label('Competitie Aanmaken')
|
||||
->action('createContest')
|
||||
->color('success'),
|
||||
])
|
||||
->schema([
|
||||
TextInput::make('contest.title')
|
||||
->label('Titel')
|
||||
->required()
|
||||
->placeholder('Bijv. Beste Song Suggestie'),
|
||||
Textarea::make('contest.description')
|
||||
->label('Beschrijving')
|
||||
->rows(3)
|
||||
->placeholder('Beschrijf de competitie regels...'),
|
||||
TextInput::make('contest.prize')
|
||||
->label('Prijs')
|
||||
->required()
|
||||
->placeholder('Bijv. VIP voor 1 maand'),
|
||||
TextInput::make('contest.max_winners')
|
||||
->label('Aantal Winnaars')
|
||||
->numeric()
|
||||
->default(1)
|
||||
->placeholder('1'),
|
||||
DateTimePicker::make('contest.starts_at')
|
||||
->label('Start Datum/Tijd')
|
||||
->required()
|
||||
->default(now()),
|
||||
DateTimePicker::make('contest.ends_at')
|
||||
->label('Eind Datum/Tijd')
|
||||
->required()
|
||||
->default(now()->addDays(14)),
|
||||
Toggle::make('contest.require_approval')
|
||||
->label('Goedkeuring Vereist')
|
||||
->default(false),
|
||||
]),
|
||||
Section::make('Actieve Competities')
|
||||
->description('Beheer lopende competities')
|
||||
->columns(1)
|
||||
->schema([
|
||||
Select::make('selected_contest')
|
||||
->label('Selecteer Competitie')
|
||||
->options(RadioContest::where('is_active', true)->pluck('title', 'id'))
|
||||
->placeholder('Kies een competitie...')
|
||||
->live(),
|
||||
]),
|
||||
Section::make('Acties')
|
||||
->description('Competitie beheer')
|
||||
->columns(2)
|
||||
->schema([
|
||||
Action::make('end_contest')
|
||||
->label('Competitie Beëindigen')
|
||||
->action('endContest')
|
||||
->color('danger')
|
||||
->requiresConfirmation(),
|
||||
Action::make('declare_winners')
|
||||
->label('Winnaars Bekend Maken')
|
||||
->action('declareWinners')
|
||||
->color('warning')
|
||||
->requiresConfirmation(),
|
||||
]),
|
||||
Section::make('Afgelopen Competities')
|
||||
->description('Bekijk resultaten van afgelopen competities')
|
||||
->columns(1)
|
||||
->schema([
|
||||
Select::make('ended_contest')
|
||||
->label('Selecteer Afgelopen Competitie')
|
||||
->options(RadioContest::where('is_ended', true)->pluck('title', 'id'))
|
||||
->placeholder('Kies een competitie...'),
|
||||
]),
|
||||
])
|
||||
->statePath('data');
|
||||
}
|
||||
|
||||
public function createContest(): void
|
||||
{
|
||||
$data = $this->data['contest'] ?? [];
|
||||
|
||||
$contest = RadioContest::create([
|
||||
'title' => $data['title'],
|
||||
'description' => $data['description'] ?? '',
|
||||
'prize' => $data['prize'],
|
||||
'max_winners' => $data['max_winners'] ?? 1,
|
||||
'starts_at' => $data['starts_at'] ?? now(),
|
||||
'ends_at' => $data['ends_at'] ?? now()->addDays(14),
|
||||
'is_active' => true,
|
||||
'is_ended' => false,
|
||||
'winners_announced' => false,
|
||||
'require_approval' => $data['require_approval'] ?? false,
|
||||
]);
|
||||
|
||||
$this->fillForm();
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Competitie Aangemaakt')
|
||||
->body("Competitie '{$contest->title}' is succesvol aangemaakt!")
|
||||
->send();
|
||||
}
|
||||
|
||||
public function endContest(): void
|
||||
{
|
||||
$contestId = $this->data['selected_contest'] ?? null;
|
||||
|
||||
if (! $contestId) {
|
||||
Notification::make()
|
||||
->warning()
|
||||
->title('Geen Competitie Geselecteerd')
|
||||
->body('Selecteer eerst een competitie.')
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$contest = RadioContest::find($contestId);
|
||||
|
||||
$contest->update(['is_ended' => true, 'is_active' => false]);
|
||||
|
||||
$this->fillForm();
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Competitie Beëindigd')
|
||||
->body("Competitie '{$contest->title}' is beëindigd.")
|
||||
->send();
|
||||
}
|
||||
|
||||
public function declareWinners(): void
|
||||
{
|
||||
$contestId = $this->data['selected_contest'] ?? null;
|
||||
|
||||
if (! $contestId) {
|
||||
Notification::make()
|
||||
->warning()
|
||||
->title('Geen Competitie Geselecteerd')
|
||||
->body('Selecteer eerst een competitie.')
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$contest = RadioContest::find($contestId);
|
||||
$entries = $contest->entries()->with('user')->get();
|
||||
|
||||
if ($entries->isEmpty()) {
|
||||
Notification::make()
|
||||
->warning()
|
||||
->title('Geen Inzendingen')
|
||||
->body('Er zijn nog geen inzendingen.')
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$winners = $entries->random(min($contest->max_winners, $entries->count()));
|
||||
|
||||
foreach ($winners as $winner) {
|
||||
$winner->markAsWinner();
|
||||
}
|
||||
|
||||
$contest->update(['winners_announced' => true]);
|
||||
|
||||
$this->fillForm();
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Winnaars Bekend!')
|
||||
->body(count($winners) . ' winnaars zijn geselecteerd!')
|
||||
->send();
|
||||
}
|
||||
}
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Pages\Radio;
|
||||
|
||||
use App\Models\RadioGiveaway;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
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 GiveawayManagement extends Page implements HasForms
|
||||
{
|
||||
use InteractsWithForms;
|
||||
|
||||
#[\Override]
|
||||
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-gift';
|
||||
|
||||
#[\Override]
|
||||
protected static string|\UnitEnum|null $navigationGroup = 'Radio';
|
||||
|
||||
#[\Override]
|
||||
protected static ?string $navigationLabel = null;
|
||||
|
||||
#[\Override]
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return __('Giveaways');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected static ?string $title = 'Winacties Beheer';
|
||||
|
||||
#[\Override]
|
||||
protected string $view = 'filament.pages.radio.giveaway-management';
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
public array $data = [];
|
||||
|
||||
public RadioGiveaway $currentGiveaway;
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->fillForm();
|
||||
}
|
||||
|
||||
protected function fillForm(): void
|
||||
{
|
||||
$giveaways = RadioGiveaway::orderBy('created_at', 'desc')->get();
|
||||
|
||||
$this->data['giveaways'] = $giveaways->toArray();
|
||||
$this->data['active_giveaway'] = $giveaways->firstWhere('is_active', true)?->id;
|
||||
}
|
||||
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Section::make('Nieuwe Winactie Aanmaken')
|
||||
->description('Maak een nieuwe winactie aan voor luisteraars')
|
||||
->columns(1)
|
||||
->headerActions([
|
||||
Action::make('create_giveaway')
|
||||
->label('Winactie Aanmaken')
|
||||
->action('createGiveaway')
|
||||
->color('success'),
|
||||
])
|
||||
->schema([
|
||||
TextInput::make('giveaway.title')
|
||||
->label('Titel')
|
||||
->required()
|
||||
->placeholder('Bijv. Win VIP voor 1 maand!'),
|
||||
Textarea::make('giveaway.description')
|
||||
->label('Beschrijving')
|
||||
->rows(3)
|
||||
->placeholder('Beschrijf de winactie en de prijs...'),
|
||||
TextInput::make('giveaway.prize')
|
||||
->label('Prijs')
|
||||
->required()
|
||||
->placeholder('Bijv. VIP Lifetime'),
|
||||
TextInput::make('giveaway.prize_value')
|
||||
->label('Prijs Waarde (EUR)')
|
||||
->numeric()
|
||||
->placeholder('Bijv. 25.00'),
|
||||
DateTimePicker::make('giveaway.starts_at')
|
||||
->label('Start Datum/Tijd')
|
||||
->required()
|
||||
->default(now()),
|
||||
DateTimePicker::make('giveaway.ends_at')
|
||||
->label('Eind Datum/Tijd')
|
||||
->required()
|
||||
->default(now()->addDays(7)),
|
||||
]),
|
||||
Section::make('Actieve Winacties')
|
||||
->description('Beheer lopende winacties')
|
||||
->columns(1)
|
||||
->schema([
|
||||
Select::make('selected_giveaway')
|
||||
->label('Selecteer Winactie')
|
||||
->options(RadioGiveaway::where('is_active', true)->pluck('title', 'id'))
|
||||
->placeholder('Kies een winactie...')
|
||||
->live()
|
||||
->afterStateUpdated(function ($state) {
|
||||
if ($state) {
|
||||
$this->currentGiveaway = RadioGiveaway::find($state);
|
||||
}
|
||||
}),
|
||||
]),
|
||||
Section::make('Acties')
|
||||
->description('Winactie beheer')
|
||||
->columns(2)
|
||||
->schema([
|
||||
Action::make('export_participants')
|
||||
->label('Deelnemers Exporteren')
|
||||
->action('exportParticipants')
|
||||
->color('info'),
|
||||
Action::make('pick_winner')
|
||||
->label('Winnaar Trekken')
|
||||
->action('pickWinner')
|
||||
->color('warning')
|
||||
->requiresConfirmation(),
|
||||
Action::make('end_giveaway')
|
||||
->label('Winactie Beëindigen')
|
||||
->action('endGiveaway')
|
||||
->color('danger')
|
||||
->requiresConfirmation(),
|
||||
]),
|
||||
Section::make('Afgelopen Winacties')
|
||||
->description('Bekijk resultaten van afgelopen winacties')
|
||||
->columns(1)
|
||||
->schema([
|
||||
Select::make('ended_giveaway')
|
||||
->label('Selecteer Afgelopen Winactie')
|
||||
->options(RadioGiveaway::where('is_ended', true)->pluck('title', 'id'))
|
||||
->placeholder('Kies een winactie...'),
|
||||
]),
|
||||
])
|
||||
->statePath('data');
|
||||
}
|
||||
|
||||
public function createGiveaway(): void
|
||||
{
|
||||
$data = $this->data['giveaway'] ?? [];
|
||||
|
||||
$giveaway = RadioGiveaway::create([
|
||||
'title' => $data['title'],
|
||||
'description' => $data['description'] ?? '',
|
||||
'prize' => $data['prize'],
|
||||
'prize_value' => $data['prize_value'] ?? 0,
|
||||
'starts_at' => $data['starts_at'] ?? now(),
|
||||
'ends_at' => $data['ends_at'] ?? now()->addDays(7),
|
||||
'is_active' => true,
|
||||
'is_ended' => false,
|
||||
'winner_announced' => false,
|
||||
]);
|
||||
|
||||
$this->fillForm();
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Winactie Aangemaakt')
|
||||
->body("Winactie '{$giveaway->title}' is succesvol aangemaakt!")
|
||||
->send();
|
||||
}
|
||||
|
||||
public function pickWinner(): void
|
||||
{
|
||||
$giveawayId = $this->data['selected_giveaway'] ?? null;
|
||||
|
||||
if (! $giveawayId) {
|
||||
Notification::make()
|
||||
->warning()
|
||||
->title('Geen Winactie Geselecteerd')
|
||||
->body('Selecteer eerst een winactie.')
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$giveaway = RadioGiveaway::find($giveawayId);
|
||||
|
||||
if (! $giveaway) {
|
||||
Notification::make()
|
||||
->danger()
|
||||
->title('Winactie Niet Gevonden')
|
||||
->body('De geselecteerde winactie bestaat niet meer.')
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$participants = $giveaway->participants()->with('user')->get();
|
||||
|
||||
if ($participants->isEmpty()) {
|
||||
Notification::make()
|
||||
->warning()
|
||||
->title('Geen Deelnemers')
|
||||
->body('Er zijn nog geen deelnemers voor deze winactie.')
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$winner = $participants->random();
|
||||
|
||||
$giveaway->announceWinner($winner->user);
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Winnaar Gekozen!')
|
||||
->body("Gefeliciteerd {$winner->user->username}! Je hebt {$giveaway->prize} gewonnen!")
|
||||
->send();
|
||||
|
||||
$this->fillForm();
|
||||
}
|
||||
|
||||
public function endGiveaway(): void
|
||||
{
|
||||
$giveawayId = $this->data['selected_giveaway'] ?? null;
|
||||
|
||||
if (! $giveawayId) {
|
||||
Notification::make()
|
||||
->warning()
|
||||
->title('Geen Winactie Geselecteerd')
|
||||
->body('Selecteer eerst een winactie.')
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$giveaway = RadioGiveaway::find($giveawayId);
|
||||
|
||||
$giveaway->update(['is_ended' => true, 'is_active' => false]);
|
||||
|
||||
$this->fillForm();
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Winactie Beëindigd')
|
||||
->body("Winactie '{$giveaway->title}' is beëindigd.")
|
||||
->send();
|
||||
}
|
||||
|
||||
public function exportParticipants(): void
|
||||
{
|
||||
Notification::make()
|
||||
->info()
|
||||
->title('Export Gestart')
|
||||
->body('Deelnemerslijst wordt gedownload...')
|
||||
->send();
|
||||
}
|
||||
}
|
||||
Executable
+245
@@ -0,0 +1,245 @@
|
||||
<?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::where('radio_points', '>', 0)->update(['radio_points' => 0]);
|
||||
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;
|
||||
}
|
||||
}
|
||||
Executable
+1630
File diff suppressed because it is too large
Load Diff
+310
@@ -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;
|
||||
}
|
||||
}
|
||||
+446
@@ -0,0 +1,446 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Pages\Radio;
|
||||
|
||||
use App\Models\Miscellaneous\WebsiteSetting;
|
||||
use App\Services\ContentModerationService;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\Repeater;
|
||||
use Filament\Forms\Components\Select;
|
||||
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;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
final class WordFilterSettings extends Page implements HasForms
|
||||
{
|
||||
use InteractsWithForms;
|
||||
|
||||
#[\Override]
|
||||
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-shield-check';
|
||||
|
||||
#[\Override]
|
||||
protected static string|\UnitEnum|null $navigationGroup = 'Radio';
|
||||
|
||||
#[\Override]
|
||||
protected static ?string $navigationLabel = null;
|
||||
|
||||
#[\Override]
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return __('Word Filter');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected static ?string $title = 'AI Woord Filter';
|
||||
|
||||
#[\Override]
|
||||
protected string $view = 'filament.pages.radio.word-filter-settings';
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
public array $data = [];
|
||||
|
||||
/** @var array<mixed> */
|
||||
public array $blockedWords = [];
|
||||
|
||||
private ContentModerationService $moderationService;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->moderationService = new ContentModerationService;
|
||||
}
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->fillForm();
|
||||
}
|
||||
|
||||
protected function fillForm(): void
|
||||
{
|
||||
$this->data = [
|
||||
'ai_filter_enabled' => $this->getSettingBool('ai_filter_enabled'),
|
||||
'ai_filter_auto_reject' => $this->getSettingBool('ai_filter_auto_reject'),
|
||||
'ai_filter_sensitivity' => (float) $this->getSetting('ai_filter_sensitivity', '0.7'),
|
||||
'ai_filter_method' => $this->getSetting('ai_filter_method', 'local'),
|
||||
'ai_filter_shouts' => $this->getSettingBool('ai_filter_shouts'),
|
||||
'ai_filter_chat' => $this->getSettingBool('ai_filter_chat'),
|
||||
'ai_filter_applications' => $this->getSettingBool('ai_filter_applications'),
|
||||
'ai_filter_requests' => $this->getSettingBool('ai_filter_requests'),
|
||||
'ai_filter_log_rejected' => $this->getSettingBool('ai_filter_log_rejected'),
|
||||
'openai_api_key' => $this->getSetting('openai_api_key', ''),
|
||||
];
|
||||
|
||||
$this->blockedWords = array_map(fn ($word) => ['word' => $word], $this->moderationService->getBlockedWords());
|
||||
}
|
||||
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Section::make('Algemene Instellingen')
|
||||
->description('Basis configuratie voor het AI woordfilter')
|
||||
->columns(2)
|
||||
->afterHeader([
|
||||
Action::make('test_filter')
|
||||
->label('Filter Testen')
|
||||
->action('testFilter')
|
||||
->color('info'),
|
||||
Action::make('save_general')
|
||||
->label('Opslaan')
|
||||
->action('saveGeneral')
|
||||
->color('primary'),
|
||||
])
|
||||
->schema([
|
||||
Toggle::make('ai_filter_enabled')
|
||||
->label('Filter Inschakelen')
|
||||
->columnSpanFull()
|
||||
->helperText('Schakel AI-gebaseerde inhoudsfiltratie in voor alle radio gerelateerde content'),
|
||||
Toggle::make('ai_filter_auto_reject')
|
||||
->label('Auto Afwijzen')
|
||||
->helperText('Inhoud automatisch afwijzen zonder handmatige goedkeuring'),
|
||||
Select::make('ai_filter_method')
|
||||
->label('Filter Methode')
|
||||
->options([
|
||||
'local' => 'Lokaal (Woordenlijst)',
|
||||
'openai' => 'OpenAI API (AI-gebaseerd)',
|
||||
'both' => 'Beide Gecombineerd',
|
||||
])
|
||||
->default('local'),
|
||||
Slider::make('ai_filter_sensitivity')
|
||||
->label('Gevoeligheid')
|
||||
->minValue(0.1)
|
||||
->maxValue(1.0)
|
||||
->step(0.05)
|
||||
->default(0.7)
|
||||
->helperText('Hogere waarde = strenger filter (0.1 = lax, 1.0 = strikt)'),
|
||||
]),
|
||||
Section::make('OpenAI API Configuratie')
|
||||
->description('Configureer OpenAI voor AI-gebaseerde detectie')
|
||||
->columns(1)
|
||||
->afterHeader([
|
||||
Action::make('test_openai')
|
||||
->label('Test API')
|
||||
->action('testOpenAI')
|
||||
->color('success'),
|
||||
])
|
||||
->schema([
|
||||
TextInput::make('openai_api_key')
|
||||
->label('OpenAI API Key')
|
||||
->password()
|
||||
->placeholder('sk-...')
|
||||
->helperText('Gratis moderatie endpoint beschikbaar via OpenAI. Haal je key op bij platform.openai.com'),
|
||||
]),
|
||||
Section::make('Te Filteren Inhoud')
|
||||
->description('Selecteer welke types content gefilterd moeten worden')
|
||||
->columns(2)
|
||||
->afterHeader([
|
||||
Action::make('save_content')
|
||||
->label('Opslaan')
|
||||
->action('saveContent')
|
||||
->color('primary'),
|
||||
])
|
||||
->schema([
|
||||
Toggle::make('ai_filter_shouts')
|
||||
->label('Shouts/Chat Berichten')
|
||||
->helperText('Filter alle shouts en chat berichten'),
|
||||
Toggle::make('ai_filter_chat')
|
||||
->label('Live Chat')
|
||||
->helperText('Filter live chat berichten in real-time'),
|
||||
Toggle::make('ai_filter_applications')
|
||||
->label('DJ Aanmeldingen')
|
||||
->helperText('Filter DJ sollicitatie formulieren'),
|
||||
Toggle::make('ai_filter_requests')
|
||||
->label('Song Verzoeken')
|
||||
->helperText('Filter song request berichten'),
|
||||
Toggle::make('ai_filter_log_rejected')
|
||||
->label('Log Afwijzingen')
|
||||
->helperText('Bewaar een logboek van afgewezen berichten'),
|
||||
]),
|
||||
Section::make('Geblokkeerde Woorden')
|
||||
->description('Beheer de lokale woordenlijst voor directe filtering')
|
||||
->columns(1)
|
||||
->afterHeader([
|
||||
Action::make('add_word')
|
||||
->label('Woord Toevoegen')
|
||||
->action('addWord')
|
||||
->color('success'),
|
||||
Action::make('clear_all')
|
||||
->label('Alles Wissen')
|
||||
->action('clearAllWords')
|
||||
->color('danger')
|
||||
->requiresConfirmation(),
|
||||
Action::make('save_words')
|
||||
->label('Opslaan')
|
||||
->action('saveWords')
|
||||
->color('primary'),
|
||||
])
|
||||
->schema([
|
||||
Repeater::make('blocked_words')
|
||||
->label('Geblokkeerde Woorden')
|
||||
->schema([
|
||||
TextInput::make('word')
|
||||
->label('Woord')
|
||||
->required()
|
||||
->placeholder('vul een woord in'),
|
||||
])
|
||||
->addActionLabel('Woord toevoegen')
|
||||
->defaultItems(0),
|
||||
]),
|
||||
Section::make('Bulk Acties')
|
||||
->description('Snelle acties voor de woordenlijst')
|
||||
->columns(2)
|
||||
->schema([
|
||||
Action::make('add_common_words')
|
||||
->label('Veelvoorkomende Woorden')
|
||||
->action('addCommonWords')
|
||||
->color('secondary')
|
||||
->requiresConfirmation(),
|
||||
Action::make('export_words')
|
||||
->label('Exporteren')
|
||||
->action('exportWords')
|
||||
->color('secondary'),
|
||||
]),
|
||||
Section::make('Filter Statistieken')
|
||||
->description('Overzicht van filter activiteit')
|
||||
->columns(2)
|
||||
->schema([
|
||||
Action::make('view_stats')
|
||||
->label('Bekijk Statistieken')
|
||||
->action('viewStats')
|
||||
->color('info'),
|
||||
Action::make('reset_stats')
|
||||
->label('Resetten')
|
||||
->action('resetStats')
|
||||
->color('warning')
|
||||
->requiresConfirmation(),
|
||||
]),
|
||||
])
|
||||
->statePath('data');
|
||||
}
|
||||
|
||||
public function testFilter(): void
|
||||
{
|
||||
$testPhrases = [
|
||||
'Dit is een normale zin',
|
||||
'Dit bevat slecht_woord',
|
||||
];
|
||||
|
||||
$results = [];
|
||||
|
||||
foreach ($testPhrases as $phrase) {
|
||||
$result = $this->moderationService->moderate($phrase);
|
||||
$results[] = [
|
||||
'phrase' => $phrase,
|
||||
'approved' => $result['approved'],
|
||||
'score' => $result['score'],
|
||||
];
|
||||
}
|
||||
|
||||
Notification::make()
|
||||
->title('Filter Test')
|
||||
->body(json_encode($results, JSON_PRETTY_PRINT))
|
||||
->success()
|
||||
->send();
|
||||
}
|
||||
|
||||
public function testOpenAI(): void
|
||||
{
|
||||
$apiKey = $this->data['openai_api_key'] ?? '';
|
||||
|
||||
if (empty($apiKey)) {
|
||||
Notification::make()
|
||||
->warning()
|
||||
->title('API Key Ontbreekt')
|
||||
->body('Voer eerst een OpenAI API key in.')
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::withHeaders([
|
||||
'Authorization' => 'Bearer ' . $apiKey,
|
||||
'Content-Type' => 'application/json',
|
||||
])->post('https://api.openai.com/v1/moderations', [
|
||||
'input' => 'Test message',
|
||||
]);
|
||||
|
||||
if ($response->successful()) {
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('OpenAI API Werkt!')
|
||||
->body('API verbinding succesvol.')
|
||||
->send();
|
||||
} else {
|
||||
Notification::make()
|
||||
->danger()
|
||||
->title('API Fout')
|
||||
->body('Status: ' . $response->status())
|
||||
->send();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Notification::make()
|
||||
->danger()
|
||||
->title('Verbindingsfout')
|
||||
->body($e->getMessage())
|
||||
->send();
|
||||
}
|
||||
}
|
||||
|
||||
public function addWord(): void
|
||||
{
|
||||
Notification::make()
|
||||
->info()
|
||||
->title('Woord Toevoegen')
|
||||
->body('Gebruik de repeater om woorden toe te voegen.')
|
||||
->send();
|
||||
}
|
||||
|
||||
public function addCommonWords(): void
|
||||
{
|
||||
$commonWords = [
|
||||
'slecht', 'vervelend', 'stom', 'idiot', 'debiel', 'kanker', 'hoer',
|
||||
'kut', 'godver', 'verdomme', 'fuck', 'shit', 'bitch', 'asshole',
|
||||
];
|
||||
|
||||
foreach ($commonWords as $word) {
|
||||
$this->moderationService->addBlockedWord(trim($word));
|
||||
}
|
||||
|
||||
$this->fillForm();
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Woorden Toegevoegd')
|
||||
->body(count($commonWords) . ' woorden toegevoegd.')
|
||||
->send();
|
||||
}
|
||||
|
||||
public function clearAllWords(): void
|
||||
{
|
||||
foreach ($this->moderationService->getBlockedWords() as $word) {
|
||||
$this->moderationService->removeBlockedWord($word);
|
||||
}
|
||||
|
||||
$this->fillForm();
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Wissen Succesvol')
|
||||
->body('Alle woorden verwijderd.')
|
||||
->send();
|
||||
}
|
||||
|
||||
public function saveGeneral(): void
|
||||
{
|
||||
$this->saveSettings([
|
||||
'ai_filter_enabled', 'ai_filter_auto_reject', 'ai_filter_sensitivity',
|
||||
'ai_filter_method', 'openai_api_key',
|
||||
]);
|
||||
}
|
||||
|
||||
public function saveContent(): void
|
||||
{
|
||||
$this->saveSettings([
|
||||
'ai_filter_shouts', 'ai_filter_chat', 'ai_filter_applications',
|
||||
'ai_filter_requests', 'ai_filter_log_rejected',
|
||||
]);
|
||||
}
|
||||
|
||||
public function saveWords(): void
|
||||
{
|
||||
foreach ($this->blockedWords as $item) {
|
||||
if (! in_array(trim($item['word'] ?? ''), ['', '0'], true)) {
|
||||
$this->moderationService->addBlockedWord(trim((string) $item['word']));
|
||||
}
|
||||
}
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title(__('Saved'))
|
||||
->body('Woordenlijst bijgewerkt.')
|
||||
->send();
|
||||
}
|
||||
|
||||
public function exportWords(): void
|
||||
{
|
||||
$words = $this->moderationService->getBlockedWords();
|
||||
|
||||
$filename = 'blocked_words_' . date('Y-m-d') . '.json';
|
||||
|
||||
response()->streamDownload(function () use ($words) {
|
||||
echo json_encode($words, JSON_PRETTY_PRINT);
|
||||
}, $filename)->send();
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Export Gestart')
|
||||
->body('Download is gestart.')
|
||||
->send();
|
||||
}
|
||||
|
||||
public function viewStats(): void
|
||||
{
|
||||
$stats = $this->moderationService->getStats();
|
||||
|
||||
Notification::make()
|
||||
->title('Filter Statistieken')
|
||||
->body(json_encode($stats, JSON_PRETTY_PRINT))
|
||||
->info()
|
||||
->send();
|
||||
}
|
||||
|
||||
public function resetStats(): void
|
||||
{
|
||||
WebsiteSetting::where('key', 'like', 'filter_stats_%')->delete();
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Gereset')
|
||||
->body('Statistieken zijn gewist.')
|
||||
->send();
|
||||
}
|
||||
|
||||
private function saveSettings(array $keys): void
|
||||
{
|
||||
foreach ($keys as $key) {
|
||||
$value = $this->data[$key] ?? '';
|
||||
|
||||
$boolKeys = [
|
||||
'ai_filter_enabled', 'ai_filter_auto_reject', 'ai_filter_shouts',
|
||||
'ai_filter_chat', 'ai_filter_applications', 'ai_filter_requests',
|
||||
'ai_filter_log_rejected',
|
||||
];
|
||||
|
||||
$dbValue = in_array($key, $boolKeys) ? ($value ? '1' : '0') : (string) $value;
|
||||
|
||||
WebsiteSetting::updateOrCreate(['key' => $key], ['value' => $dbValue]);
|
||||
}
|
||||
|
||||
$this->fillForm();
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title(__('Saved'))
|
||||
->body('Instellingen zijn opgeslagen!')
|
||||
->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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user