components([ TextInput::make('name') ->label('Nama Lengkap') ->placeholder('John Doe') ->autocomplete(false) ->autofocus() ->required() ->maxLength(100), Grid::make(1) ->schema([ TextInput::make('email') ->label('Alamat Surel') ->placeholder('johndoe@example.com') ->autocomplete(false) ->required() ->maxLength(254) ->email() ->unique(ignoreRecord: true) ->prefixIcon('heroicon-o-envelope'), TextInput::make('username') ->label('Nama Pengguna') ->placeholder('johndoe') ->autocomplete(false) ->required() ->minLength(5) ->maxLength(20) ->regex('/^[a-zA-Z0-9_.-]+$/') ->unique(ignoreRecord: true) ->prefixIcon('heroicon-o-at-symbol'), Select::make('roles') ->label('Peran') ->required() ->relationship('roles', 'name', function (Builder $query): Builder { return $query->whereNotIn('name', [RoleEnum::DEVELOPER, RoleEnum::PERUSAHAAN]); }) ->multiple() ->preload() ->searchable(), Hidden::make('password') ->default(fn (): string => config('auth.password_default')) ->visibleOn('create'), ]), ]) ->columns(1); } public static function table(Table $table): Table { return $table ->columns([ ...RowIndexColumn::make(), TextColumn::make('name') ->label('Nama') ->searchable() ->sortable(), TextColumn::make('email') ->label('Alamat Surel') ->searchable() ->sortable(), TextColumn::make('username') ->label('Nama Pengguna') ->searchable() ->sortable(), ToggleColumn::make('is_active') ->label('Status') ->sortable() ->getStateUsing(fn (User $record): bool => $record->is_active === IsActive::ACTIVE) ->updateStateUsing(function (User $record, bool $state): void { $record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE; $record->save(); if ($record->is_active === IsActive::INACTIVE) { DB::table('sessions') ->where('user_id', $record->id) ->delete(); } CheerfulNotification::success( $state ? CheerfulNotification::getMessage('Pengguna Diaktifkan! ✅', 'Pengguna Diaktifkan') : CheerfulNotification::getMessage('Pengguna Dinonaktifkan ⛔', 'Pengguna Dinonaktifkan'), $state ? CheerfulNotification::getMessage('Status akun pengguna berhasil diaktifkan kembali. Siap beraksi! 🚀', 'Status akun pengguna telah berhasil diaktifkan kembali.') : CheerfulNotification::getMessage('Status akun pengguna berhasil dinonaktifkan. Istirahat dulu ya... 😴', 'Status akun pengguna telah berhasil dinonaktifkan.') )->send(); }) ->disabled(fn (User $record): bool => $record->hasRole(RoleEnum::PERUSAHAAN->value)), TextColumn::make('roles.name') ->label('Peran') ->searchable() ->badge() ->getStateUsing(fn (User $record): array => $record->roles->pluck('name', 'id')->toArray()), ...TimestampColumns::make(), ]) ->filters([ SelectFilter::make('is_active') ->label('Status') ->options(IsActive::class) ->native(false), SelectFilter::make('roles') ->label('Peran') ->relationship('roles', 'name', function (Builder $query): Builder { return $query->whereNotIn('name', [RoleEnum::DEVELOPER, RoleEnum::PERUSAHAAN]); }) ->multiple() ->preload() ->searchable() ->native(false), TrashedFilter::make() ->native(false) ->visible(fn () => auth()->user()?->hasRole(RoleEnum::DEVELOPER->value)), ]) ->recordActions([ EditAction::make() ->modalWidth(Width::Large), DeleteAction::make(), ForceDeleteAction::make(), RestoreAction::make(), ChangePasswordAction::make('changePassword'), ]) ->toolbarActions([ BulkActionGroup::make([ ...DefaultBulkActions::make('Pengguna'), ]), ]) ->emptyStateIcon(Heroicon::OutlinedUserGroup) ->emptyStateDescription(fn () => CheerfulNotification::getMessage('Belum ada data pengguna nih! Mulai buat data pertama sekarang biar makin rame! 🚀✨', 'Belum ada data yang tersedia saat ini.')) ->defaultSort('created_at', 'desc') ->deferFilters(false) ->paginated([25, 50, 100, 'all']) ->deferLoading(); } public static function getPages(): array { return [ 'index' => ManageUsers::route('/'), ]; } public static function getRecordRouteBindingEloquentQuery(): Builder { return parent::getRecordRouteBindingEloquentQuery() ->withoutGlobalScopes([ SoftDeletingScope::class, ]); } public static function getEloquentQuery(): Builder { return static::getModel()::query()->withoutDeveloper(); } }