['except' => ''], 'discordId' => ['except' => ''], 'email' => ['except' => ''], 'roleFilter' => ['except' => []], 'sortField' => ['except' => 'created_at'], 'sortDirection' => ['except' => 'desc'], 'perPage' => ['except' => 20], ]; protected $allowedSortFields = ['id', 'name', 'email', 'discord_id', 'created_at', 'updated_at']; protected $allowedPerPages = [10, 20, 50, 100]; public function updatedPerPage(): void { $this->resetPage(); } public function updatedPage(): void { $this->selectPage = false; $this->selected = []; } public function updatedSelectPage($value): void { if ($value) { $this->selected = $this->users->pluck('id')->map(fn ($id) => (string) $id)->toArray(); } else { $this->selected = []; } } public function sortBy(string $field): void { if (! in_array($field, $this->allowedSortFields)) { return; } if ($this->sortField === $field) { $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc'; } else { $this->sortField = $field; $this->sortDirection = 'asc'; } } public function clearFilters(): void { $this->search = ''; $this->discordId = ''; $this->email = ''; $this->roleFilter = []; $this->sortField = 'created_at'; $this->sortDirection = 'desc'; $this->perPage = 20; $this->resetPage(); } public function viewUser(int $userId): void { $this->modalUser = User::find($userId); if ($this->modalUser) { $this->modalUserComments = $this->modalUser->comments() ->orderBy('created_at', 'desc') ->limit(10) ->get(); $this->showUserModal = true; } } public function closeModal(): void { $this->showUserModal = false; $this->modalUser = null; $this->modalUserComments = []; } public function banUser(int $userId): void { $user = User::findOrFail($userId); $user->addRole(UserRole::BANNED); cache()->flush(); $this->dispatch('notify', type: 'success', message: "{$user->name} has been banned."); if ($this->showUserModal && $this->modalUser?->id === $userId) { $this->modalUser->refresh(); } } public function unbanUser(int $userId): void { $user = User::findOrFail($userId); $user->removeRole(UserRole::BANNED); cache()->flush(); $this->dispatch('notify', type: 'success', message: "{$user->name} has been unbanned."); if ($this->showUserModal && $this->modalUser?->id === $userId) { $this->modalUser->refresh(); } } public function grantModerator(int $userId): void { $user = User::findOrFail($userId); $user->addRole(UserRole::MODERATOR); cache()->flush(); $this->dispatch('notify', type: 'success', message: "{$user->name} has been granted Moderator role."); if ($this->showUserModal && $this->modalUser?->id === $userId) { $this->modalUser->refresh(); } } public function revokeModerator(int $userId): void { $user = User::findOrFail($userId); $user->removeRole(UserRole::MODERATOR); cache()->flush(); $this->dispatch('notify', type: 'success', message: "Moderator role revoked from {$user->name}."); if ($this->showUserModal && $this->modalUser?->id === $userId) { $this->modalUser->refresh(); } } public function deleteUserComments(int $userId): void { $user = User::findOrFail($userId); Comment::where('user_id', $user->id)->delete(); cache()->flush(); $this->dispatch('notify', type: 'success', message: "All comments from {$user->name} have been deleted."); if ($this->showUserModal && $this->modalUser?->id === $userId) { $this->modalUserComments = collect(); } } public function bulkBan(): void { $count = 0; foreach ($this->selected as $userId) { $user = User::find($userId); if ($user && ! $user->hasRole(UserRole::BANNED)) { $user->addRole(UserRole::BANNED); $count++; } } cache()->flush(); $this->selected = []; $this->selectPage = false; $this->dispatch('notify', type: 'success', message: "{$count} user(s) have been banned."); } public function bulkUnban(): void { $count = 0; foreach ($this->selected as $userId) { $user = User::find($userId); if ($user && $user->hasRole(UserRole::BANNED)) { $user->removeRole(UserRole::BANNED); $count++; } } cache()->flush(); $this->selected = []; $this->selectPage = false; $this->dispatch('notify', type: 'success', message: "{$count} user(s) have been unbanned."); } public function bulkDeleteComments(): void { $count = 0; foreach ($this->selected as $userId) { $deleted = Comment::where('user_id', (int) $userId)->delete(); if ($deleted > 0) { $count++; } } cache()->flush(); $this->selected = []; $this->selectPage = false; $this->dispatch('notify', type: 'success', message: "Deleted comments from {$count} user(s)."); } public function getUsersProperty() { return User::query() ->when($this->search !== '', fn ($query) => $query->where('name', 'like', '%'.$this->search.'%')) ->when($this->discordId !== '', fn ($query) => $query->where('discord_id', '=', $this->discordId)) ->when($this->email !== '', fn ($query) => $query->where('email', 'like', '%'.$this->email.'%')) ->when(! empty($this->roleFilter), function ($query) { foreach ($this->roleFilter as $role) { $query->whereJsonContains('roles', $role); } }) ->orderBy($this->sortField, $this->sortDirection) ->paginate((int) $this->perPage); } public function render() { return view('livewire.admin-user-search', [ 'users' => $this->users, ]); } }