components([ TextInput::make('name') ->required() ->maxLength(255), TextInput::make('email') ->email() ->required() ->maxLength(255), TextInput::make('email_verified_at') ->label('Email Verification Status') ->disabled() ->formatStateUsing(fn ($record) => $record->email_verified_at ?? '' ? 'Verified at '.$record->email_verified_at->toDateTimeString() : 'Not Verified') ->helperText('Shows whether the user has verified their email address.'), TextInput::make('stripe_id') ->label('Stripe ID') ->disabled() ->helperText('Automatically managed by Stripe'), TextInput::make('pm_type') ->label('Payment Method Type') ->disabled(), TextInput::make('pm_last_four') ->label('Card Last 4 Digits') ->disabled(), DatePicker::make('trial_ends_at') ->label('Trial Ends At') ->disabled() ->displayFormat('Y-m-d H:i:s'), Select::make('level') ->label('User Level') ->options([ 0 => 'Normal User', 1 => 'Banned', 9 => 'Super Admin', ]) ->required(), ]); } public static function table(Table $table): Table { return $table ->columns([ TextColumn::make('name')->sortable()->searchable(), TextColumn::make('email')->sortable()->searchable(), IconColumn::make('email_verified_at') ->label('Verified') ->boolean() ->trueIcon('heroicon-o-check-circle') ->falseIcon('heroicon-o-x-circle') ->trueColor('success') ->falseColor('danger') ->getStateUsing(fn ($record) => ! is_null($record->email_verified_at)) ->sortable(), BadgeColumn::make('level') ->label('User Level') ->getStateUsing(function ($record) { return match ($record->level) { 0 => 'Normal User', 1 => 'Banned', 9 => 'Super Admin', default => 'Unknown', // In case some invalid level exists }; }) ->colors([ 'success' => fn ($state) => $state === 'Normal User', 'danger' => fn ($state) => $state === 'Banned', 'warning' => fn ($state) => $state === 'Super Admin', ]) ->sortable(), TextColumn::make('stripe_id')->label('Stripe ID')->copyable(), TextColumn::make('pm_last_four')->label('Card Last 4'), TextColumn::make('trial_ends_at')->label('Trial Ends')->dateTime()->sortable(), ]) ->defaultSort('created_at', 'desc') ->filters([ SelectFilter::make('subscription_status') ->label('Subscription Status') ->options([ 'subscribed' => 'Has Active Subscription', 'not_subscribed' => 'No Active Subscription', ]) ->query(function ($query, array $data) { if ($data['value'] === 'subscribed') { $query->whereHas('subscriptions', function ($query) { $query->where('stripe_status', 'active') ->orWhere('stripe_status', 'trialing'); }); } elseif ($data['value'] === 'not_subscribed') { $query->whereDoesntHave('subscriptions', function ($query) { $query->where('stripe_status', 'active') ->orWhere('stripe_status', 'trialing'); }); } }), SelectFilter::make('email_verified') ->label('Email Verification') ->options([ 'verified' => 'Verified', 'not_verified' => 'Not Verified', ]) ->query(function ($query, array $data) { if ($data['value'] === 'verified') { $query->whereNotNull('email_verified_at'); } elseif ($data['value'] === 'not_verified') { $query->whereNull('email_verified_at'); } }), ]) ->recordActions([ EditAction::make(), ]) ->toolbarActions([ BulkActionGroup::make([ DeleteBulkAction::make(), BulkAction::make('updateLevel') ->label('Update User Level') ->action(function (Collection $records, array $data) { $newLevel = $data['new_level']; if ($newLevel === 9) { throw new Exception('User level cannot be 9 or higher.'); } DB::table('users') ->whereIn('id', $records->pluck('id')) ->update(['level' => $newLevel]); Notification::make() ->title('User Level Updated') ->body('The selected users\' levels have been updated successfully.') ->success() ->send(); }) ->icon('heroicon-o-pencil') ->color('primary') ->modalHeading('Select User Level') ->modalSubheading('Please choose the user level to apply to the selected users.') ->form([ Select::make('new_level') ->label('Select User Level') ->options([ 0 => 'Unban (Normal User)', 1 => 'Ban', ]) ->required(), ]), ]), ]); } public static function getRelations(): array { return [ LogsRelationManager::class, UsageLogsRelationManager::class, ]; } public static function getPages(): array { return [ 'index' => ListUsers::route('/'), 'create' => CreateUser::route('/create'), 'edit' => EditUser::route('/{record}/edit'), ]; } }