Add superadmin moderation queues
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2026-01-01 18:52:32 +01:00
parent 4fbd0815a4
commit 117250879b
22 changed files with 1324 additions and 5 deletions

View File

@@ -0,0 +1,74 @@
<?php
namespace App\Filament\Clusters\DailyOps\Resources\Photos\Schemas;
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\Schemas\Schema;
class PhotoForm
{
public static function configure(Schema $schema): Schema
{
return $schema
->components([
Select::make('event_id')
->relationship('event', 'name')
->required(),
Select::make('emotion_id')
->relationship('emotion', 'name'),
Select::make('task_id')
->relationship('task', 'title'),
TextInput::make('guest_name')
->required(),
TextInput::make('file_path')
->required(),
TextInput::make('thumbnail_path')
->required(),
TextInput::make('likes_count')
->required()
->numeric()
->default(0),
Toggle::make('is_featured')
->required(),
Textarea::make('metadata')
->columnSpanFull(),
TextInput::make('tenant_id')
->numeric(),
Select::make('media_asset_id')
->relationship('mediaAsset', 'id'),
TextInput::make('security_scan_status')
->required()
->default('pending'),
Textarea::make('security_scan_message')
->columnSpanFull(),
DateTimePicker::make('security_scanned_at'),
Textarea::make('security_meta')
->columnSpanFull(),
TextInput::make('ingest_source')
->required()
->default('guest_pwa'),
TextInput::make('filename'),
TextInput::make('original_name'),
TextInput::make('mime_type'),
TextInput::make('size')
->numeric(),
TextInput::make('width')
->numeric(),
TextInput::make('height')
->numeric(),
TextInput::make('status')
->required()
->default('pending'),
TextInput::make('uploader_id')
->numeric(),
TextInput::make('ip_address'),
Textarea::make('user_agent')
->columnSpanFull(),
TextInput::make('created_by_device_id'),
]);
}
}

View File

@@ -0,0 +1,109 @@
<?php
namespace App\Filament\Clusters\DailyOps\Resources\Photos\Schemas;
use App\Models\Photo;
use Filament\Infolists\Components\ImageEntry;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
class PhotoInfolist
{
public static function configure(Schema $schema): Schema
{
return $schema
->components([
Section::make(__('admin.moderation.sections.photo'))
->columns(3)
->schema([
ImageEntry::make('thumbnail_path')
->label(__('admin.moderation.fields.photo'))
->disk('public')
->visibility('public')
->getStateUsing(fn (Photo $record) => $record->thumbnail_path ?: $record->file_path)
->columnSpanFull(),
TextEntry::make('event.name')
->label(__('admin.moderation.fields.event'))
->placeholder('—'),
TextEntry::make('event.tenant.name')
->label(__('admin.moderation.fields.tenant'))
->placeholder('—'),
TextEntry::make('guest_name')
->label(__('admin.moderation.fields.uploader'))
->placeholder('—'),
TextEntry::make('created_at')
->label(__('admin.moderation.fields.uploaded_at'))
->since()
->placeholder('—'),
TextEntry::make('ingest_source')
->label(__('admin.moderation.fields.ingest_source'))
->formatStateUsing(fn (?string $state) => match ($state) {
Photo::SOURCE_GUEST_PWA => __('admin.moderation.ingest_sources.guest_pwa'),
Photo::SOURCE_TENANT_ADMIN => __('admin.moderation.ingest_sources.tenant_admin'),
Photo::SOURCE_PHOTOBOOTH => __('admin.moderation.ingest_sources.photobooth'),
Photo::SOURCE_SPARKBOOTH => __('admin.moderation.ingest_sources.sparkbooth'),
Photo::SOURCE_UNKNOWN => __('admin.moderation.ingest_sources.unknown'),
default => '—',
}),
]),
Section::make(__('admin.moderation.sections.moderation'))
->columns(2)
->schema([
TextEntry::make('status')
->label(__('admin.moderation.fields.status'))
->badge()
->color(fn (?string $state) => match ($state) {
'approved' => 'success',
'rejected' => 'danger',
'hidden' => 'gray',
default => 'warning',
})
->formatStateUsing(fn (?string $state) => match ($state) {
'pending' => __('admin.moderation.status.pending'),
'approved' => __('admin.moderation.status.approved'),
'rejected' => __('admin.moderation.status.rejected'),
'hidden' => __('admin.moderation.status.hidden'),
default => '—',
}),
TextEntry::make('moderator.name')
->label(__('admin.moderation.fields.moderated_by'))
->placeholder('—'),
TextEntry::make('moderated_at')
->label(__('admin.moderation.fields.moderated_at'))
->dateTime()
->placeholder('—'),
TextEntry::make('moderation_notes')
->label(__('admin.moderation.fields.moderation_notes'))
->placeholder('—')
->columnSpanFull(),
TextEntry::make('security_scan_status')
->label(__('admin.moderation.fields.security_scan_status'))
->badge()
->color(fn (?string $state) => match ($state) {
'clean', 'skipped', 'stripped' => 'success',
'infected' => 'danger',
'error' => 'warning',
default => 'gray',
})
->formatStateUsing(fn (?string $state) => match ($state) {
'pending' => __('admin.moderation.security_scan.pending'),
'clean' => __('admin.moderation.security_scan.clean'),
'infected' => __('admin.moderation.security_scan.infected'),
'skipped' => __('admin.moderation.security_scan.skipped'),
'stripped' => __('admin.moderation.security_scan.stripped'),
'error' => __('admin.moderation.security_scan.error'),
default => '—',
}),
TextEntry::make('security_scan_message')
->label(__('admin.moderation.fields.security_scan_message'))
->placeholder('—')
->columnSpanFull(),
TextEntry::make('security_scanned_at')
->label(__('admin.moderation.fields.security_scanned_at'))
->dateTime()
->placeholder('—'),
]),
]);
}
}