query('search', '')); $users = User::query() ->with('roles') ->when($search !== '', static function ($query) use ($search): void { $query->where(fn ($query) => $query ->where('name', 'like', '%'.$search.'%') ->orWhere('email', 'like', '%'.$search.'%')); }) ->orderBy('name') ->paginate(5) ->withQueryString(); return view('modules.user-management.index', compact('users', 'search')); } public function create(): View { return view('modules.user-management.create', ['roles' => Role::query()->orderBy('name')->get()]); } public function store(Request $request): RedirectResponse { $data = $this->validatedUser($request); $user = User::query()->create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), 'email_verified_at' => now(), 'helpdesk_agent' => $request->boolean('helpdesk_agent') || $request->boolean('helpdesk_admin'), 'helpdesk_admin' => $request->boolean('helpdesk_admin'), ]); $user->roles()->sync($request->input('roles', [])); return redirect()->route('user-management.edit', $user)->with('status', 'User created successfully.'); } public function edit(User $user): View { $user->load('roles'); return view('modules.user-management.edit', [ 'user' => $user, 'roles' => Role::query()->orderBy('name')->get(), ]); } public function update(Request $request, User $user): RedirectResponse { $data = $this->validatedUser($request, $user); $user->name = $data['name']; $user->email = $data['email']; $user->helpdesk_admin = $request->boolean('helpdesk_admin'); $user->helpdesk_agent = $user->helpdesk_admin || $request->boolean('helpdesk_agent'); if (filled($data['password'] ?? null)) { $user->password = Hash::make($data['password']); } $user->save(); $user->roles()->sync($request->input('roles', [])); return back()->with('status', 'User updated successfully.'); } public function destroy(Request $request, User $user): RedirectResponse { abort_if((int) $request->user()->id === (int) $user->id, 422, 'You cannot delete your own account.'); if ($user->isHelpdeskAdmin() && User::query()->where('helpdesk_admin', true)->count() <= 1) { return back()->withErrors(['user' => 'The last Helpdesk administrator cannot be deleted.']); } $user->delete(); return redirect()->route('user-management.index')->with('status', 'User deleted.'); } public function roles(): View { $roles = Role::query() ->withCount(['users', 'permissions']) ->orderBy('name') ->paginate(5, ['*'], 'roles_page') ->withQueryString(); $permissions = Permission::query() ->withCount('roles') ->orderBy('name') ->paginate(5, ['*'], 'permissions_page') ->withQueryString(); return view('modules.user-management.roles', compact('roles', 'permissions')); } public function createRole(): View { return view('modules.user-management.role-form', [ 'role' => new Role, 'permissions' => Permission::query()->orderBy('name')->get(), ]); } public function storeRole(Request $request): RedirectResponse { $data = $this->validatedRole($request); $role = Role::query()->create($data); $role->permissions()->sync($request->input('permissions', [])); return redirect()->route('user-management.roles')->with('status', 'Role created.'); } public function editRole(Role $role): View { $role->load('permissions'); return view('modules.user-management.role-form', [ 'role' => $role, 'permissions' => Permission::query()->orderBy('name')->get(), ]); } public function updateRole(Request $request, Role $role): RedirectResponse { $role->update($this->validatedRole($request, $role)); $role->permissions()->sync($request->input('permissions', [])); return redirect()->route('user-management.roles')->with('status', 'Role updated.'); } public function destroyRole(Role $role): RedirectResponse { if ($role->is_system) { return back()->withErrors(['role' => 'System roles cannot be deleted.']); } $role->delete(); return back()->with('status', 'Role deleted.'); } public function createPermission(): View { return view('modules.user-management.permission-form', ['permission' => new Permission]); } public function storePermission(Request $request): RedirectResponse { Permission::query()->create($this->validatedPermission($request)); return redirect()->route('user-management.roles')->with('status', 'Permission created.'); } public function editPermission(Permission $permission): View { return view('modules.user-management.permission-form', compact('permission')); } public function updatePermission(Request $request, Permission $permission): RedirectResponse { $permission->update($this->validatedPermission($request, $permission)); return redirect()->route('user-management.roles')->with('status', 'Permission updated.'); } public function destroyPermission(Permission $permission): RedirectResponse { $permission->delete(); return back()->with('status', 'Permission deleted.'); } private function validatedUser(Request $request, ?User $user = null): array { return $request->validate([ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'email', 'max:255', Rule::unique('users', 'email')->ignore($user?->id)], 'password' => [$user ? 'nullable' : 'required', 'string', 'min:8', 'confirmed'], 'helpdesk_agent' => ['sometimes', 'boolean'], 'helpdesk_admin' => ['sometimes', 'boolean'], 'roles' => ['array'], 'roles.*' => ['integer', 'exists:user_management_roles,id'], ]); } private function validatedRole(Request $request, ?Role $role = null): array { $data = $request->validate([ 'name' => ['required', 'string', 'max:255'], 'slug' => ['nullable', 'string', 'max:255', Rule::unique('user_management_roles', 'slug')->ignore($role?->id)], 'description' => ['nullable', 'string', 'max:2000'], 'permissions' => ['array'], 'permissions.*' => ['integer', 'exists:user_management_permissions,id'], ]); $data['slug'] = filled($data['slug'] ?? null) ? Str::slug($data['slug']) : Str::slug($data['name']); unset($data['permissions']); return $data; } private function validatedPermission(Request $request, ?Permission $permission = null): array { $data = $request->validate([ 'name' => ['required', 'string', 'max:255'], 'slug' => ['nullable', 'string', 'max:255', Rule::unique('user_management_permissions', 'slug')->ignore($permission?->id)], 'description' => ['nullable', 'string', 'max:2000'], ]); $data['slug'] = filled($data['slug'] ?? null) ? Str::slug($data['slug'], '.') : Str::slug($data['name'], '.'); return $data; } }