From 7a6982570e5c1ed57202c82c66253771e626f7f6 Mon Sep 17 00:00:00 2001 From: pesu98 Date: Mon, 11 May 2026 11:18:25 +0800 Subject: [PATCH 1/6] user listing with pagination --- app/Http/Controllers/UserController.php | 16 ++++++ resources/views/layouts/navigation.blade.php | 6 +++ resources/views/users/index.blade.php | 56 ++++++++++++++++++++ routes/web.php | 2 + 4 files changed, 80 insertions(+) create mode 100644 app/Http/Controllers/UserController.php create mode 100644 resources/views/users/index.blade.php diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php new file mode 100644 index 0000000..3201ed4 --- /dev/null +++ b/app/Http/Controllers/UserController.php @@ -0,0 +1,16 @@ +paginate(10); + + return view('users.index', compact('users')); + } +} diff --git a/resources/views/layouts/navigation.blade.php b/resources/views/layouts/navigation.blade.php index c64bf64..703d97d 100644 --- a/resources/views/layouts/navigation.blade.php +++ b/resources/views/layouts/navigation.blade.php @@ -15,6 +15,9 @@ {{ __('Dashboard') }} + + {{ __('Users') }} + @@ -70,6 +73,9 @@ {{ __('Dashboard') }} + + {{ __('Users') }} + diff --git a/resources/views/users/index.blade.php b/resources/views/users/index.blade.php new file mode 100644 index 0000000..ab5255d --- /dev/null +++ b/resources/views/users/index.blade.php @@ -0,0 +1,56 @@ + + +

+ {{ __('Users') }} +

+
+ +
+
+
+
+ + + + + + + + + + @foreach ($users as $user) + + + + + + @endforeach + +
+ {{ __('Name') }} + + {{ __('Email') }} + + {{ __('Joined') }} +
+ {{ $user->name }} + + {{ $user->email }} + + {{ $user->created_at->format('M j, Y') }} +
+ + @if ($users->isEmpty()) +

{{ __('No users found.') }}

+ @endif + + @if ($users->hasPages()) +
+ {{ $users->links() }} +
+ @endif +
+
+
+
+
diff --git a/routes/web.php b/routes/web.php index 74bb7ca..ce44b28 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,6 +1,7 @@ middleware(['auth', 'verified'])->name('dashboard'); Route::middleware('auth')->group(function () { + Route::get('/users', [UserController::class, 'index'])->name('users.index'); Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit'); Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update'); Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy'); From f290f941edf69e14fd66347d125761052caf6409 Mon Sep 17 00:00:00 2001 From: pesu98 Date: Mon, 11 May 2026 11:41:20 +0800 Subject: [PATCH 2/6] add role feature --- app/Http/Controllers/RoleController.php | 16 ++++++ app/Models/Role.php | 15 +++++ database/factories/RoleFactory.php | 24 ++++++++ .../2026_05_11_032743_create_roles_table.php | 28 ++++++++++ resources/views/layouts/navigation.blade.php | 10 ++++ resources/views/roles/index.blade.php | 56 +++++++++++++++++++ routes/web.php | 4 ++ 7 files changed, 153 insertions(+) create mode 100644 app/Http/Controllers/RoleController.php create mode 100644 app/Models/Role.php create mode 100644 database/factories/RoleFactory.php create mode 100644 database/migrations/2026_05_11_032743_create_roles_table.php create mode 100644 resources/views/roles/index.blade.php diff --git a/app/Http/Controllers/RoleController.php b/app/Http/Controllers/RoleController.php new file mode 100644 index 0000000..f65a9f7 --- /dev/null +++ b/app/Http/Controllers/RoleController.php @@ -0,0 +1,16 @@ +paginate(10); + + return view('roles.index', compact('roles')); + } +} diff --git a/app/Models/Role.php b/app/Models/Role.php new file mode 100644 index 0000000..01a4676 --- /dev/null +++ b/app/Models/Role.php @@ -0,0 +1,15 @@ + */ + use HasFactory; + + protected $fillable = ['name']; +} diff --git a/database/factories/RoleFactory.php b/database/factories/RoleFactory.php new file mode 100644 index 0000000..7b88046 --- /dev/null +++ b/database/factories/RoleFactory.php @@ -0,0 +1,24 @@ + + */ +class RoleFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'name' => fake()->unique()->word(), + ]; + } +} diff --git a/database/migrations/2026_05_11_032743_create_roles_table.php b/database/migrations/2026_05_11_032743_create_roles_table.php new file mode 100644 index 0000000..3f600ed --- /dev/null +++ b/database/migrations/2026_05_11_032743_create_roles_table.php @@ -0,0 +1,28 @@ +id(); + $table->string('name'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('roles'); + } +}; diff --git a/resources/views/layouts/navigation.blade.php b/resources/views/layouts/navigation.blade.php index c64bf64..e35a83b 100644 --- a/resources/views/layouts/navigation.blade.php +++ b/resources/views/layouts/navigation.blade.php @@ -15,6 +15,10 @@ {{ __('Dashboard') }} + + + {{ __('Roles') }} + @@ -70,6 +74,12 @@ {{ __('Dashboard') }} + + {{ __('Users') }} + + + {{ __('Roles') }} + diff --git a/resources/views/roles/index.blade.php b/resources/views/roles/index.blade.php new file mode 100644 index 0000000..fc778d3 --- /dev/null +++ b/resources/views/roles/index.blade.php @@ -0,0 +1,56 @@ + + +

+ {{ __('Roles') }} +

+
+ +
+
+
+
+ + + + + + + + + + @foreach ($roles as $role) + + + + + + @endforeach + +
+ {{ __('ID') }} + + {{ __('Name') }} + + {{ __('Created') }} +
+ {{ $role->id }} + + {{ $role->name }} + + {{ $role->created_at->format('M j, Y') }} +
+ + @if ($roles->isEmpty()) +

{{ __('No roles found.') }}

+ @endif + + @if ($roles->hasPages()) +
+ {{ $roles->links() }} +
+ @endif +
+
+
+
+
diff --git a/routes/web.php b/routes/web.php index 74bb7ca..2e52264 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,6 +1,8 @@ middleware(['auth', 'verified'])->name('dashboard'); Route::middleware('auth')->group(function () { + Route::get('/users', [UserController::class, 'index'])->name('users.index'); + Route::get('/roles', [RoleController::class, 'index'])->name('roles.index'); Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit'); Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update'); Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy'); From 74f52a9e7d70846e41b3f74e2266484d9e964cce Mon Sep 17 00:00:00 2001 From: pesu98 Date: Mon, 11 May 2026 11:46:03 +0800 Subject: [PATCH 3/6] tambah role functionality --- app/Http/Controllers/RoleController.php | 18 ++++++++ app/Http/Controllers/UserController.php | 16 +++++++ resources/views/roles/create.blade.php | 32 ++++++++++++++ resources/views/roles/index.blade.php | 12 ++++++ resources/views/users/index.blade.php | 56 +++++++++++++++++++++++++ routes/web.php | 2 + 6 files changed, 136 insertions(+) create mode 100644 app/Http/Controllers/UserController.php create mode 100644 resources/views/roles/create.blade.php create mode 100644 resources/views/users/index.blade.php diff --git a/app/Http/Controllers/RoleController.php b/app/Http/Controllers/RoleController.php index f65a9f7..348a95e 100644 --- a/app/Http/Controllers/RoleController.php +++ b/app/Http/Controllers/RoleController.php @@ -3,6 +3,8 @@ namespace App\Http\Controllers; use App\Models\Role; +use Illuminate\Http\RedirectResponse; +use Illuminate\Http\Request; use Illuminate\View\View; class RoleController extends Controller @@ -13,4 +15,20 @@ class RoleController extends Controller return view('roles.index', compact('roles')); } + + public function create(): View + { + return view('roles.create'); + } + + public function store(Request $request): RedirectResponse + { + $validated = $request->validate([ + 'name' => ['required', 'string', 'max:255', 'unique:roles,name'], + ]); + + Role::create($validated); + + return redirect()->route('roles.index')->with('success', __('Role created successfully.')); + } } diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php new file mode 100644 index 0000000..3201ed4 --- /dev/null +++ b/app/Http/Controllers/UserController.php @@ -0,0 +1,16 @@ +paginate(10); + + return view('users.index', compact('users')); + } +} diff --git a/resources/views/roles/create.blade.php b/resources/views/roles/create.blade.php new file mode 100644 index 0000000..a0fe162 --- /dev/null +++ b/resources/views/roles/create.blade.php @@ -0,0 +1,32 @@ + + +

+ {{ __('New Role') }} +

+
+ +
+
+
+
+
+ @csrf + +
+ + + +
+ +
+ {{ __('Create Role') }} + + {{ __('Cancel') }} + +
+
+
+
+
+
+
diff --git a/resources/views/roles/index.blade.php b/resources/views/roles/index.blade.php index fc778d3..2f97378 100644 --- a/resources/views/roles/index.blade.php +++ b/resources/views/roles/index.blade.php @@ -9,6 +9,18 @@
+ + + @if (session('success')) +
+ {{ session('success') }} +
+ @endif + diff --git a/resources/views/users/index.blade.php b/resources/views/users/index.blade.php new file mode 100644 index 0000000..ab5255d --- /dev/null +++ b/resources/views/users/index.blade.php @@ -0,0 +1,56 @@ + + +

+ {{ __('Users') }} +

+
+ +
+
+
+
+
+ + + + + + + + + @foreach ($users as $user) + + + + + + @endforeach + +
+ {{ __('Name') }} + + {{ __('Email') }} + + {{ __('Joined') }} +
+ {{ $user->name }} + + {{ $user->email }} + + {{ $user->created_at->format('M j, Y') }} +
+ + @if ($users->isEmpty()) +

{{ __('No users found.') }}

+ @endif + + @if ($users->hasPages()) +
+ {{ $users->links() }} +
+ @endif +
+
+
+ + diff --git a/routes/web.php b/routes/web.php index 2e52264..ab50ce3 100644 --- a/routes/web.php +++ b/routes/web.php @@ -16,6 +16,8 @@ Route::get('/dashboard', function () { Route::middleware('auth')->group(function () { Route::get('/users', [UserController::class, 'index'])->name('users.index'); Route::get('/roles', [RoleController::class, 'index'])->name('roles.index'); + Route::get('/roles/create', [RoleController::class, 'create'])->name('roles.create'); + Route::post('/roles', [RoleController::class, 'store'])->name('roles.store'); Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit'); Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update'); Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy'); From 79b0184d3ae0c6b79cbb9c0dbb0fa363380dd9ec Mon Sep 17 00:00:00 2001 From: pesu98 Date: Mon, 11 May 2026 11:54:09 +0800 Subject: [PATCH 4/6] update edit user functionality --- app/Http/Controllers/UserController.php | 19 ++++++++++++ resources/views/users/edit.blade.php | 39 +++++++++++++++++++++++++ resources/views/users/index.blade.php | 12 ++++++++ routes/web.php | 2 ++ 4 files changed, 72 insertions(+) create mode 100644 resources/views/users/edit.blade.php diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 3201ed4..a6fbeca 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -3,6 +3,8 @@ namespace App\Http\Controllers; use App\Models\User; +use Illuminate\Http\RedirectResponse; +use Illuminate\Http\Request; use Illuminate\View\View; class UserController extends Controller @@ -13,4 +15,21 @@ class UserController extends Controller return view('users.index', compact('users')); } + + public function edit(User $user): View + { + return view('users.edit', compact('user')); + } + + public function update(Request $request, User $user): RedirectResponse + { + $validated = $request->validate([ + 'name' => ['required', 'string', 'max:255'], + 'email' => ['required', 'email', 'max:255', 'unique:users,email,'.$user->id], + ]); + + $user->update($validated); + + return redirect()->route('users.index')->with('success', __('User updated successfully.')); + } } diff --git a/resources/views/users/edit.blade.php b/resources/views/users/edit.blade.php new file mode 100644 index 0000000..2b56d48 --- /dev/null +++ b/resources/views/users/edit.blade.php @@ -0,0 +1,39 @@ + + +

+ {{ __('Edit User') }} +

+
+ +
+
+
+
+
+ @csrf + @method('PATCH') + +
+ + + +
+ +
+ + + +
+ +
+ {{ __('Save Changes') }} + + {{ __('Cancel') }} + +
+
+
+
+
+
+
diff --git a/resources/views/users/index.blade.php b/resources/views/users/index.blade.php index ab5255d..b57a90f 100644 --- a/resources/views/users/index.blade.php +++ b/resources/views/users/index.blade.php @@ -9,6 +9,12 @@
+ @if (session('success')) +
+ {{ session('success') }} +
+ @endif + @@ -21,6 +27,7 @@ + @@ -35,6 +42,11 @@ + @endforeach diff --git a/routes/web.php b/routes/web.php index ce44b28..4e7c043 100644 --- a/routes/web.php +++ b/routes/web.php @@ -14,6 +14,8 @@ Route::get('/dashboard', function () { Route::middleware('auth')->group(function () { Route::get('/users', [UserController::class, 'index'])->name('users.index'); + Route::get('/users/{user}/edit', [UserController::class, 'edit'])->name('users.edit'); + Route::patch('/users/{user}', [UserController::class, 'update'])->name('users.update'); Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit'); Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update'); Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy'); From c7fded1d8f46f99a7f024589f4eff36fb80bc5e2 Mon Sep 17 00:00:00 2001 From: pesu98 Date: Mon, 11 May 2026 12:29:41 +0800 Subject: [PATCH 5/6] tambah namaste --- app/Http/Controllers/UserController.php | 10 +++++-- app/Models/Role.php | 6 ++++ app/Models/User.php | 6 ++++ ...26_05_11_040641_create_role_user_table.php | 28 +++++++++++++++++++ resources/views/users/edit.blade.php | 19 +++++++++++++ resources/views/welcome.blade.php | 2 +- 6 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 database/migrations/2026_05_11_040641_create_role_user_table.php diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index a6fbeca..cbdc55d 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Models\Role; use App\Models\User; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; @@ -18,7 +19,9 @@ class UserController extends Controller public function edit(User $user): View { - return view('users.edit', compact('user')); + $roles = Role::orderBy('name')->get(); + + return view('users.edit', compact('user', 'roles')); } public function update(Request $request, User $user): RedirectResponse @@ -26,9 +29,12 @@ class UserController extends Controller $validated = $request->validate([ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'email', 'max:255', 'unique:users,email,'.$user->id], + 'roles' => ['nullable', 'array'], + 'roles.*' => ['integer', 'exists:roles,id'], ]); - $user->update($validated); + $user->update(['name' => $validated['name'], 'email' => $validated['email']]); + $user->roles()->sync($validated['roles'] ?? []); return redirect()->route('users.index')->with('success', __('User updated successfully.')); } diff --git a/app/Models/Role.php b/app/Models/Role.php index 01a4676..86b8213 100644 --- a/app/Models/Role.php +++ b/app/Models/Role.php @@ -5,6 +5,7 @@ namespace App\Models; use Database\Factories\RoleFactory; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; class Role extends Model { @@ -12,4 +13,9 @@ class Role extends Model use HasFactory; protected $fillable = ['name']; + + public function users(): BelongsToMany + { + return $this->belongsToMany(User::class); + } } diff --git a/app/Models/User.php b/app/Models/User.php index f6ba1d2..ee6a6d4 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -7,6 +7,7 @@ use Database\Factories\UserFactory; use Illuminate\Database\Eloquent\Attributes\Fillable; use Illuminate\Database\Eloquent\Attributes\Hidden; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; @@ -29,4 +30,9 @@ class User extends Authenticatable 'password' => 'hashed', ]; } + + public function roles(): BelongsToMany + { + return $this->belongsToMany(Role::class); + } } diff --git a/database/migrations/2026_05_11_040641_create_role_user_table.php b/database/migrations/2026_05_11_040641_create_role_user_table.php new file mode 100644 index 0000000..bc623bd --- /dev/null +++ b/database/migrations/2026_05_11_040641_create_role_user_table.php @@ -0,0 +1,28 @@ +foreignId('user_id')->constrained()->cascadeOnDelete(); + $table->foreignId('role_id')->constrained()->cascadeOnDelete(); + $table->primary(['user_id', 'role_id']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('role_user'); + } +}; diff --git a/resources/views/users/edit.blade.php b/resources/views/users/edit.blade.php index 2b56d48..910da9b 100644 --- a/resources/views/users/edit.blade.php +++ b/resources/views/users/edit.blade.php @@ -25,6 +25,25 @@ +
+ +
+ @foreach ($roles as $role) + + @endforeach +
+ +
+
{{ __('Joined') }}
{{ $user->created_at->format('M j, Y') }} + + {{ __('Edit') }} + +