From 8476c5d6432e10d98dd76eff47d3d4d07cdc7350 Mon Sep 17 00:00:00 2001 From: GuavaPopper Date: Wed, 3 Jun 2026 13:51:08 +0700 Subject: [PATCH] =?UTF-8?q?feat:=20Plan=203=20=E2=80=94=20Manajemen=20Peng?= =?UTF-8?q?guna=20(Admin=20User=20Management)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add AdminUserController: CRUD users, assign role, reset password, self-delete guard (403 on own account) - Add admin route group under role:administrator middleware (GET/POST/PUT/DELETE /api/admin/users, PUT /api/admin/users/{id}/password) - Add resources/views/admin/users.blade.php: DaisyUI table + 4 modals (create, edit, reset password, delete confirm), stats grid, toast - Add Admin nav link (administrator-only) to map and data navbars - 9 new tests covering page access, API CRUD, self-delete guard, password reset - Mark Plan 3 complete in missing_features.md; update README page list - Save plan3 to docs/ for reference Co-Authored-By: Claude Sonnet 4.6 --- README.md | 1 + app/Http/Controllers/AdminUserController.php | 85 +++ docs/plan3-admin-user-management.md | 746 +++++++++++++++++++ missing_features.md | 12 +- resources/views/admin/users.blade.php | 443 +++++++++++ resources/views/data.blade.php | 7 + resources/views/map.blade.php | 7 + routes/web.php | 14 + tests/Feature/AdminUserTest.php | 127 ++++ 9 files changed, 1436 insertions(+), 6 deletions(-) create mode 100644 app/Http/Controllers/AdminUserController.php create mode 100644 docs/plan3-admin-user-management.md create mode 100644 resources/views/admin/users.blade.php create mode 100644 tests/Feature/AdminUserTest.php diff --git a/README.md b/README.md index eb21adb..0f9aada 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,7 @@ docker compose exec app php artisan cache:clear 1. **Beranda (`/`)**: Halaman landing dengan latar belakang peta animasi dan navigasi cepat. 2. **Peta Interaktif (`/map`)**: Antarmuka utama untuk melihat sebaran dan melakukan analisis radius. 3. **Data Tabular (`/data`)**: Manajemen data dalam format tabel dengan ringkasan statistik total. +4. **Admin Pengguna (`/admin/users`)**: Manajemen pengguna sistem — tambah, edit, hapus akun, assign role, dan reset password. Hanya dapat diakses oleh Administrator. --- *Dokumentasi ini dibuat untuk menjelaskan kapabilitas sistem WebGIS Pemetaan Kemiskinan versi Laravel.* diff --git a/app/Http/Controllers/AdminUserController.php b/app/Http/Controllers/AdminUserController.php new file mode 100644 index 0000000..eef8f95 --- /dev/null +++ b/app/Http/Controllers/AdminUserController.php @@ -0,0 +1,85 @@ +get()->map(fn($u) => [ + 'id' => $u->id, + 'name' => $u->name, + 'email' => $u->email, + 'role' => $u->getRoleNames()->first() ?? null, + ]); + return response()->json($users); + } + + public function store(Request $request) + { + $validated = $request->validate([ + 'name' => 'required|string|max:255', + 'email' => 'required|email|unique:users,email', + 'password' => 'required|string|min:8', + 'role' => 'required|string|exists:roles,name', + ]); + + $user = User::create([ + 'name' => $validated['name'], + 'email' => $validated['email'], + 'password' => $validated['password'], + ]); + $user->syncRoles([$validated['role']]); + + return response()->json(['success' => true, 'data' => [ + 'id' => $user->id, 'name' => $user->name, + 'email' => $user->email, 'role' => $validated['role'], + ]]); + } + + public function update(Request $request, $id) + { + $user = User::findOrFail($id); + + $validated = $request->validate([ + 'name' => 'required|string|max:255', + 'email' => 'required|email|unique:users,email,' . $id, + 'role' => 'required|string|exists:roles,name', + ]); + + $user->update(['name' => $validated['name'], 'email' => $validated['email']]); + $user->syncRoles([$validated['role']]); + + return response()->json(['success' => true, 'data' => [ + 'id' => $user->id, 'name' => $user->name, + 'email' => $user->email, 'role' => $validated['role'], + ]]); + } + + public function destroy($id) + { + $user = User::findOrFail($id); + + if ($user->id === auth()->id()) { + return response()->json(['message' => 'Tidak dapat menghapus akun sendiri.'], 403); + } + + $user->delete(); + return response()->json(['success' => true]); + } + + public function resetPassword(Request $request, $id) + { + $user = User::findOrFail($id); + + $request->validate([ + 'password' => 'required|string|min:8|confirmed', + ]); + + $user->update(['password' => $request->password]); + return response()->json(['success' => true]); + } +} diff --git a/docs/plan3-admin-user-management.md b/docs/plan3-admin-user-management.md new file mode 100644 index 0000000..746fd93 --- /dev/null +++ b/docs/plan3-admin-user-management.md @@ -0,0 +1,746 @@ +# Plan 3: Manajemen Pengguna (Admin User Management) + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Tambah halaman admin `/admin/users` untuk CRUD pengguna dan assign role — hanya bisa diakses oleh `administrator`. + +**Architecture:** Buat `AdminUserController` dengan 5 endpoint JSON (`index`, `store`, `update`, `destroy`, `resetPassword`). Buat view `resources/views/admin/users.blade.php` dengan pola DaisyUI yang sama persis seperti `data.blade.php` (fetch API, toast, modals, table rows). Tambahkan link "Admin" ke navbar di `map.blade.php` dan `data.blade.php` — muncul hanya untuk role `administrator`. Semua route di-protect dengan `role:administrator`. + +**Tech Stack:** Laravel 13, Spatie Permission v8, Blade, Vanilla JS (fetch + async/await), DaisyUI 4, Tailwind CSS, Font Awesome 6. + +> **Scope note:** Ini adalah Plan 3 dari `missing_features.md` (A-01). Plan 4–6 adalah subsistem terpisah yang masing-masing butuh plan tersendiri. + +--- + +## Progress + +| Task | Status | +|------|--------| +| Task 1: AdminUserController | ✅ Selesai (file dibuat, belum di-commit) | +| Task 2: Routes | ⚠️ Sebagian — `use` statement ditambah, route group belum | +| Task 3: View admin/users.blade.php | ❌ Belum | +| Task 4: Navbar links (map + data) | ❌ Belum | +| Task 5: Tests | ❌ Belum | +| Task 6: Docs | ❌ Belum | + +**Commit dulu sebelum lanjut:** +```bash +git add app/Http/Controllers/AdminUserController.php routes/web.php +git commit -m "feat: add AdminUserController, add use statement to routes" +``` + +--- + +## File Map + +| Action | File | +|--------|------| +| Create | `app/Http/Controllers/AdminUserController.php` | +| Modify | `routes/web.php` | +| Create | `resources/views/admin/users.blade.php` | +| Modify | `resources/views/map.blade.php` | +| Modify | `resources/views/data.blade.php` | +| Create | `tests/Feature/AdminUserTest.php` | +| Modify | `missing_features.md` | +| Modify | `README.md` | + +--- + +## Task 1: Buat AdminUserController ✅ + +File sudah dibuat di `app/Http/Controllers/AdminUserController.php`. + +- [x] **Step 1: Tulis controller** + +```php +get()->map(fn($u) => [ + 'id' => $u->id, + 'name' => $u->name, + 'email' => $u->email, + 'role' => $u->getRoleNames()->first() ?? null, + ]); + return response()->json($users); + } + + public function store(Request $request) + { + $validated = $request->validate([ + 'name' => 'required|string|max:255', + 'email' => 'required|email|unique:users,email', + 'password' => 'required|string|min:8', + 'role' => 'required|string|exists:roles,name', + ]); + + $user = User::create([ + 'name' => $validated['name'], + 'email' => $validated['email'], + 'password' => $validated['password'], + ]); + $user->syncRoles([$validated['role']]); + + return response()->json(['success' => true, 'data' => [ + 'id' => $user->id, 'name' => $user->name, + 'email' => $user->email, 'role' => $validated['role'], + ]]); + } + + public function update(Request $request, $id) + { + $user = User::findOrFail($id); + + $validated = $request->validate([ + 'name' => 'required|string|max:255', + 'email' => 'required|email|unique:users,email,' . $id, + 'role' => 'required|string|exists:roles,name', + ]); + + $user->update(['name' => $validated['name'], 'email' => $validated['email']]); + $user->syncRoles([$validated['role']]); + + return response()->json(['success' => true, 'data' => [ + 'id' => $user->id, 'name' => $user->name, + 'email' => $user->email, 'role' => $validated['role'], + ]]); + } + + public function destroy($id) + { + $user = User::findOrFail($id); + + if ($user->id === auth()->id()) { + return response()->json(['message' => 'Tidak dapat menghapus akun sendiri.'], 403); + } + + $user->delete(); + return response()->json(['success' => true]); + } + + public function resetPassword(Request $request, $id) + { + $user = User::findOrFail($id); + + $request->validate([ + 'password' => 'required|string|min:8|confirmed', + ]); + + $user->update(['password' => $request->password]); + return response()->json(['success' => true]); + } +} +``` + +- [ ] **Step 2: Commit** + +```bash +git add app/Http/Controllers/AdminUserController.php +git commit -m "feat: add AdminUserController with CRUD and password reset" +``` + +--- + +## Task 2: Tambah Routes Admin + +**Files:** +- Modify: `routes/web.php` + +> **STATUS:** `use App\Http\Controllers\AdminUserController;` sudah ditambah di routes/web.php. Tinggal tambahkan route group di Step 1 lalu commit. + +- [ ] **Step 1: Tambah route group admin** + +Di `routes/web.php`, dalam middleware group `auth`, tambahkan **sebelum** kurung tutup `});` terakhir: + +```php + // Admin routes — hanya administrator + Route::middleware('role:administrator')->group(function () { + Route::get('/admin/users', fn() => view('admin.users'))->name('admin.users'); + + Route::prefix('api/admin')->group(function () { + Route::get('/users', [AdminUserController::class, 'index']); + Route::post('/users', [AdminUserController::class, 'store']); + Route::put('/users/{id}', [AdminUserController::class, 'update']); + Route::delete('/users/{id}', [AdminUserController::class, 'destroy']); + Route::put('/users/{id}/password', [AdminUserController::class, 'resetPassword']); + }); + }); +``` + +- [ ] **Step 2: Commit** + +```bash +git add routes/web.php +git commit -m "feat: add admin user management routes" +``` + +--- + +## Task 3: Buat View Admin Users + +**Files:** +- Create: `resources/views/admin/users.blade.php` + +Ikuti pola `data.blade.php` (sticky navbar, DaisyUI, JS fetch, toast, modals). + +- [ ] **Step 1: Tulis view lengkap** + +```html + + + + + + + Manajemen Pengguna - WebGIS + + + + + + + + + + + + +
+ + +
+
+

+ + Manajemen Pengguna +

+

Kelola akun pengguna dan hak akses sistem.

+
+ +
+ + +
+ + +
+ + + + + + + + +
#NamaEmailRoleAksi
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +``` + +- [ ] **Step 2: Commit** + +```bash +git add resources/views/admin/users.blade.php +git commit -m "feat: add admin users management view" +``` + +--- + +## Task 4: Tambah Link Admin ke Navbar + +**Files:** +- Modify: `resources/views/map.blade.php` +- Modify: `resources/views/data.blade.php` + +- [ ] **Step 1: Tambah di map.blade.php** + +Cari `