columns([ TextColumn::make('id') ->label(__('admin.users.fields.id')) ->searchable() ->copyable() ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('name') ->label(__('admin.users.fields.name')) ->searchable(), TextColumn::make('email') ->label(__('admin.users.fields.email')) ->searchable(), TextColumn::make('role') ->label(__('admin.users.fields.role')) ->badge() ->sortable(), TextColumn::make('email_verified_at') ->label(__('admin.users.fields.email_verified_at')) ->dateTime() ->sortable() ->placeholder(__('admin.users.placeholders.not_verified')), TextColumn::make('account_verified_at') ->label(__('admin.users.fields.account_verified_at')) ->dateTime() ->sortable() ->placeholder(__('admin.users.placeholders.not_verified')) ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('suspended_at') ->label(__('admin.users.fields.suspended_at')) ->dateTime() ->sortable() ->placeholder(__('admin.users.placeholders.not_suspended')), ImageColumn::make('avatar_url') ->label(__('admin.users.fields.avatar')) ->circular(), TextColumn::make('sex') ->label(__('admin.users.fields.sex')) ->badge() ->sortable(), TextColumn::make('date_of_birth') ->label(__('admin.users.fields.date_of_birth')) ->date() ->sortable() ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('height') ->label(__('admin.users.fields.height')) ->numeric(decimalPlaces: 0) ->suffix(' cm') ->sortable() ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('physical_activity_level') ->label(__('admin.users.fields.physical_activity_level_short')) ->badge() ->sortable() ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('weight_goal') ->label(__('admin.users.fields.weight_goal_short')) ->badge() ->sortable() ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('pace_preference') ->label(__('admin.users.fields.pace_preference')) ->badge() ->sortable() ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('daily_calorie_goal') ->label(__('admin.users.fields.daily_calorie_goal')) ->numeric(decimalPlaces: 0) ->suffix(' kcal') ->sortable() ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('daily_protein_goal') ->label(__('admin.users.fields.daily_protein_goal')) ->numeric(maxDecimalPlaces: 2) ->suffix(' g') ->sortable() ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('daily_carbs_goal') ->label(__('admin.users.fields.daily_carbs_goal')) ->numeric(maxDecimalPlaces: 2) ->suffix(' g') ->sortable() ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('daily_fats_goal') ->label(__('admin.users.fields.daily_fats_goal')) ->numeric(maxDecimalPlaces: 2) ->suffix(' g') ->sortable() ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('bio') ->label(__('admin.users.fields.bio')) ->limit(50) ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('created_at') ->label(__('admin.users.fields.created_at')) ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('updated_at') ->label(__('admin.users.fields.updated_at')) ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), ]) ->filters([ SelectFilter::make('role') ->label(__('admin.users.fields.role')) ->options(UserRole::class), SelectFilter::make('sex') ->label(__('admin.users.fields.sex')) ->options(UserSex::class), SelectFilter::make('physical_activity_level') ->label(__('admin.users.fields.physical_activity_level_short')) ->options(PhysicalActivityLevel::class), SelectFilter::make('weight_goal') ->label(__('admin.users.fields.weight_goal_short')) ->options(WeightGoal::class), SelectFilter::make('pace_preference') ->label(__('admin.users.fields.pace_preference')) ->options(PacePreference::class), TernaryFilter::make('email_verified_at') ->label(__('admin.users.filters.email_verified')) ->nullable(), TernaryFilter::make('account_verified_at') ->label(__('admin.users.filters.account_verified')) ->nullable(), TernaryFilter::make('suspended_at') ->label(__('admin.users.filters.suspended')) ->nullable(), ]) ->recordActions([ ViewAction::make(), EditAction::make(), Action::make('suspend') ->label(__('admin.users.actions.suspend')) ->color('danger') ->requiresConfirmation() ->visible(fn (User $record): bool => ! $record->isSuspended() && $record->getKey() !== auth()->id()) ->action(fn (User $record): bool => self::suspendUser($record)), Action::make('unsuspend') ->label(__('admin.users.actions.unsuspend')) ->color('success') ->requiresConfirmation() ->visible(fn (User $record): bool => $record->isSuspended()) ->action(fn (User $record): bool => self::unsuspendUser($record)), ]) ->toolbarActions([ BulkActionGroup::make([ DeleteBulkAction::make(), ]), ]); } private static function suspendUser(User $record): bool { if ($record->getKey() === auth()->id()) { return false; } $record->forceFill([ 'suspended_at' => now(), 'suspended_by' => auth()->id(), 'suspended_reason' => __('admin.users.actions.suspend'), ])->save(); return true; } private static function unsuspendUser(User $record): bool { $record->forceFill([ 'suspended_at' => null, 'suspended_by' => null, 'suspended_reason' => null, ])->save(); return true; } }