From 2c74b38ffcc9e14f8b3a193a453755f6e15f3bb0 Mon Sep 17 00:00:00 2001 From: Doar Mihai Date: Sat, 21 Feb 2026 14:27:38 +0200 Subject: [PATCH] admin user management --- .../Admin/UserManagementController.php | 130 +++++++++ resources/views/admin/users/edit.blade.php | 268 ++++++++++++++++++ resources/views/admin/users/index.blade.php | 184 ++++++++++++ .../views/components/layout/navbar.blade.php | 54 ++-- routes/web.php | 10 +- 5 files changed, 627 insertions(+), 19 deletions(-) create mode 100644 app/Http/Controllers/Admin/UserManagementController.php create mode 100644 resources/views/admin/users/edit.blade.php create mode 100644 resources/views/admin/users/index.blade.php diff --git a/app/Http/Controllers/Admin/UserManagementController.php b/app/Http/Controllers/Admin/UserManagementController.php new file mode 100644 index 0000000..6f0b5cd --- /dev/null +++ b/app/Http/Controllers/Admin/UserManagementController.php @@ -0,0 +1,130 @@ +filled('search')) { + $search = $request->search; + $query->where(function ($q) use ($search) { + $q->where('name', 'like', "%{$search}%") + ->orWhere('email', 'like', "%{$search}%"); + }); + } + + // Filter by role + if ($request->filled('role')) { + $query->whereHas('roles', function ($q) use ($request) { + $q->where('slug', $request->role); + }); + } + + $users = $query->latest()->paginate(20); + $roles = Role::all(); + + return view('admin.users.index', compact('users', 'roles')); + } + + /** + * Show the form for editing a user. + */ + public function edit(User $user) + { + $roles = Role::all(); + return view('admin.users.edit', compact('user', 'roles')); + } + + /** + * Update the specified user. + */ + public function update(Request $request, User $user) + { + $validated = $request->validate([ + 'name' => ['required', 'string', 'max:255'], + 'email' => ['required', 'string', 'email', 'max:255', Rule::unique('users')->ignore($user->id)], + 'password' => ['nullable', 'string', 'min:8', 'confirmed'], + 'roles' => ['required', 'array', 'min:1'], + 'roles.*' => ['exists:roles,id'], + 'bio' => ['nullable', 'string', 'max:500'], + 'website' => ['nullable', 'url', 'max:255'], + 'twitter' => ['nullable', 'string', 'max:255'], + 'github' => ['nullable', 'string', 'max:255'], + 'linkedin' => ['nullable', 'string', 'max:255'], + ]); + + // Update user data + $user->name = $validated['name']; + $user->email = $validated['email']; + $user->bio = $validated['bio'] ?? null; + $user->website = $validated['website'] ?? null; + $user->twitter = $validated['twitter'] ?? null; + $user->github = $validated['github'] ?? null; + $user->linkedin = $validated['linkedin'] ?? null; + + // Update password if provided + if ($request->filled('password')) { + $user->password = Hash::make($validated['password']); + } + + $user->save(); + + // Sync roles + $user->roles()->sync($validated['roles']); + + return redirect()->route('admin.users.index') + ->with('success', 'User updated successfully.'); + } + + /** + * Remove the specified user. + */ + public function destroy(User $user) + { + // Prevent self-deletion + if ($user->id === auth()->id()) { + return redirect()->route('admin.users.index') + ->with('error', 'You cannot delete your own account.'); + } + + // Delete user's related data or handle as needed + $user->delete(); + + return redirect()->route('admin.users.index') + ->with('success', 'User deleted successfully.'); + } + + /** + * Toggle user's role. + */ + public function toggleRole(User $user, Role $role) + { + if ($user->roles->contains($role)) { + // Check if removing the last role + if ($user->roles->count() === 1) { + return back()->with('error', 'User must have at least one role.'); + } + $user->roles()->detach($role->id); + $message = "Role '{$role->name}' removed from user."; + } else { + $user->roles()->attach($role->id); + $message = "Role '{$role->name}' added to user."; + } + + return back()->with('success', $message); + } +} diff --git a/resources/views/admin/users/edit.blade.php b/resources/views/admin/users/edit.blade.php new file mode 100644 index 0000000..8a22100 --- /dev/null +++ b/resources/views/admin/users/edit.blade.php @@ -0,0 +1,268 @@ +@extends('layouts.app') + +@section('content') +
+
+ +
+
+
+

Edit User

+

Update user information and roles

+
+ + Back to Users + +
+
+ + +
+ @csrf + @method('PUT') + + +
+
+ @if($user->avatar_url) + {{ $user->name }} + @else +
+ {{ strtoupper(substr($user->name, 0, 1)) }} +
+ @endif +
+

{{ $user->name }}

+

Editing user profile

+
+
+
+ + +
+

Basic Information

+ +
+ +
+ + + @error('name') +

{{ $message }}

+ @enderror +
+ + +
+ + + @error('email') +

{{ $message }}

+ @enderror +
+ + +
+ + + @error('bio') +

{{ $message }}

+ @enderror +
+
+
+ + +
+

Social Links

+ +
+ +
+ + + @error('website') +

{{ $message }}

+ @enderror +
+ + +
+ + + @error('twitter') +

{{ $message }}

+ @enderror +
+ + +
+ + + @error('github') +

{{ $message }}

+ @enderror +
+ + +
+ + + @error('linkedin') +

{{ $message }}

+ @enderror +
+
+
+ + +
+

Change Password

+

Leave blank to keep current password

+ +
+ +
+ + + @error('password') +

{{ $message }}

+ @enderror +
+ + +
+ + +
+
+
+ + +
+

+ Roles * +

+

Select at least one role for this user

+ +
+ @foreach($roles as $role) + + @endforeach +
+ @error('roles') +

{{ $message }}

+ @enderror +
+ + +
+ + Cancel + + +
+
+
+
+@endsection diff --git a/resources/views/admin/users/index.blade.php b/resources/views/admin/users/index.blade.php new file mode 100644 index 0000000..3b12650 --- /dev/null +++ b/resources/views/admin/users/index.blade.php @@ -0,0 +1,184 @@ +@extends('layouts.app') + +@section('content') +
+
+ +
+

User Management

+

Manage all users and their roles

+
+ + + @if(session('success')) +
+ {{ session('success') }} +
+ @endif + + @if(session('error')) +
+ {{ session('error') }} +
+ @endif + + +
+
+ +
+ +
+ + +
+ +
+ + +
+ + @if(request('search') || request('role')) + + Clear + + @endif +
+
+
+ + +
+
+ + + + + + + + + + + @forelse($users as $user) + + + + + + + @empty + + + + @endforelse + +
+ User + + Roles + + Joined + + Actions +
+
+
+ @if($user->avatar_url) + {{ $user->name }} + @else +
+ {{ strtoupper(substr($user->name, 0, 1)) }} +
+ @endif +
+
+
+ {{ $user->name }} +
+
+ {{ $user->email }} +
+
+
+
+
+ @forelse($user->roles as $role) + + {{ $role->name }} + + @empty + No roles + @endforelse +
+
+ {{ $user->created_at->format('M d, Y') }} + +
+ + Edit + + @if($user->id !== auth()->id()) +
+ @csrf + @method('DELETE') + +
+ @endif +
+
+ No users found +
+
+ + + @if($users->hasPages()) +
+ {{ $users->links() }} +
+ @endif +
+
+
+@endsection diff --git a/resources/views/components/layout/navbar.blade.php b/resources/views/components/layout/navbar.blade.php index 31ed08e..89d451a 100644 --- a/resources/views/components/layout/navbar.blade.php +++ b/resources/views/components/layout/navbar.blade.php @@ -19,20 +19,6 @@ class="inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium {{ request()->routeIs('products.*') ? 'border-primary-500 text-gray-900 dark:text-white' : 'border-transparent text-gray-500 dark:text-gray-400 hover:border-gray-300 dark:hover:border-gray-600 hover:text-gray-700 dark:hover:text-gray-300' }}"> Products - @auth - @if(auth()->user()->hasRole('admin')) - - Dashboard - - @endif - @if(auth()->user()->hasAnyRole(['admin', 'moderator'])) - - Manage - - @endif - @endauth @@ -123,6 +109,38 @@ Settings + + @if(auth()->user()->hasRole('admin')) +
+ +
+ + + + Admin Dashboard +
+
+ +
+ + + + Manage Users +
+
+ @endif + @if(auth()->user()->hasAnyRole(['admin', 'moderator'])) + + Manage products + + @endif +
@csrf