From 0a77627adb7372bc2c8620d0583a5d067b098fd4 Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 8 Jan 2026 13:56:38 +0100 Subject: [PATCH] feat: hunt steps --- .../Resources/Hunts/HuntsResource.php | 17 +++- .../Resources/Hunts/Pages/CreateHunts.php | 7 ++ .../ParticipantsRelationManager.php | 60 ++++++++++++++ .../RelationManagers/StepsRelationManager.php | 81 +++++++++++++++++++ 4 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 app/Filament/Resources/Hunts/RelationManagers/ParticipantsRelationManager.php create mode 100644 app/Filament/Resources/Hunts/RelationManagers/StepsRelationManager.php diff --git a/app/Filament/Resources/Hunts/HuntsResource.php b/app/Filament/Resources/Hunts/HuntsResource.php index abc4849..162e0e4 100644 --- a/app/Filament/Resources/Hunts/HuntsResource.php +++ b/app/Filament/Resources/Hunts/HuntsResource.php @@ -22,9 +22,21 @@ use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Textarea; use Filament\Forms\Components\Select; use Filament\Forms\Components\DateTimePicker; +use Illuminate\Database\Eloquent\Builder; +use App\Enums\UserRole; class HuntsResource extends Resource { + public static function getEloquentQuery(): Builder + { + $query = parent::getEloquentQuery(); + + if (auth()->check() && auth()->user()->role === UserRole::ORGA) { + $query->where('creator_id', auth()->id()); + } + + return $query; + } protected static ?string $model = Hunts::class; protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-map'; @@ -44,6 +56,8 @@ class HuntsResource extends Resource Select::make('difficulty') ->options(HuntDifficulty::class) ->required(), + TextInput::make('slug') + ->required(), TextInput::make('city') ->required() ->maxLength(255), @@ -91,7 +105,8 @@ class HuntsResource extends Resource public static function getRelations(): array { return [ - // + RelationManagers\StepsRelationManager::class, + RelationManagers\ParticipantsRelationManager::class, ]; } diff --git a/app/Filament/Resources/Hunts/Pages/CreateHunts.php b/app/Filament/Resources/Hunts/Pages/CreateHunts.php index b35b2e0..c844901 100644 --- a/app/Filament/Resources/Hunts/Pages/CreateHunts.php +++ b/app/Filament/Resources/Hunts/Pages/CreateHunts.php @@ -8,4 +8,11 @@ use Filament\Resources\Pages\CreateRecord; class CreateHunts extends CreateRecord { protected static string $resource = HuntsResource::class; + + protected function mutateFormDataBeforeCreate(array $data): array + { + $data['creator_id'] = auth()->id(); + + return $data; + } } diff --git a/app/Filament/Resources/Hunts/RelationManagers/ParticipantsRelationManager.php b/app/Filament/Resources/Hunts/RelationManagers/ParticipantsRelationManager.php new file mode 100644 index 0000000..4f0bd53 --- /dev/null +++ b/app/Filament/Resources/Hunts/RelationManagers/ParticipantsRelationManager.php @@ -0,0 +1,60 @@ +components([ + Forms\Components\TextInput::make('username') + ->required() + ->maxLength(255), + ]); + } + + public function table(Table $table): Table + { + return $table + ->recordTitleAttribute('username') + ->columns([ + Tables\Columns\TextColumn::make('username'), + Tables\Columns\TextColumn::make('email'), + Tables\Columns\TextColumn::make('pivot.status') + ->label('Status') + ->badge() + ->color(fn (string $state): string => match ($state) { + 'completed' => 'success', + 'in_progress' => 'warning', + default => 'gray', + }), + Tables\Columns\TextColumn::make('pivot.created_at') + ->label('Joined At') + ->dateTime(), + ]) + ->filters([ + // + ]) + ->headerActions([ + // Usually participants join via app, but maybe allow manual attach? + // Tables\Actions\AttachAction::make(), + ]) + ->actions([ + // Tables\Actions\DetachAction::make(), + ]) + ->bulkActions([ + // Tables\Actions\BulkActionGroup::make([ + // Tables\Actions\DetachBulkAction::make(), + // ]), + ]); + } +} diff --git a/app/Filament/Resources/Hunts/RelationManagers/StepsRelationManager.php b/app/Filament/Resources/Hunts/RelationManagers/StepsRelationManager.php new file mode 100644 index 0000000..75aa32c --- /dev/null +++ b/app/Filament/Resources/Hunts/RelationManagers/StepsRelationManager.php @@ -0,0 +1,81 @@ +components([ + TextInput::make('step_number') + ->required() + ->numeric(), + TextInput::make('title') + ->required() + ->maxLength(255), + Textarea::make('description'), + Textarea::make('hint_text') + ->label('Hint'), + TextInput::make('hint_media_url') + ->url() + ->label('Hint Media URL'), + TextInput::make('latitude') + ->numeric() + ->required(), + TextInput::make('longitude') + ->numeric() + ->required(), + TextInput::make('radius_m') + ->numeric() + ->label('Radius (meters)') + ->default(20), + TextInput::make('xp') + ->numeric() + ->default(10), + ]); + } + + public function table(Table $table): Table + { + return $table + ->recordTitleAttribute('title') + ->columns([ + Tables\Columns\TextColumn::make('step_number')->sortable(), + Tables\Columns\TextColumn::make('title'), + Tables\Columns\TextColumn::make('latitude'), + Tables\Columns\TextColumn::make('longitude'), + Tables\Columns\TextColumn::make('xp'), + ]) + ->filters([ + // + ]) + ->headerActions([ + CreateAction::make(), + ]) + ->actions([ + EditAction::make(), + DeleteAction::make(), + ]) + ->bulkActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +}