feat: Plan 3 — Manajemen Pengguna (Admin User Management)
- 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 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AdminUserController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$users = User::with('roles')->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]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user