feat: reset password user dari admin

- Tombol key (oranye) di samping edit user
- Klik → SweetAlert2 modal: input password baru + konfirmasi
- Validasi: min 6 karakter, harus cocok
- Admin tidak bisa reset password sendiri (lewat profil)
This commit is contained in:
Bro
2026-07-24 19:08:40 +07:00
parent dddb98d04c
commit 6f33f7712d
3 changed files with 62 additions and 1 deletions
@@ -89,4 +89,22 @@ class UserController extends Controller
return redirect()->route('users.index')
->with('success', 'User berhasil dihapus.');
}
public function resetPassword(Request $request, User $user): RedirectResponse
{
if ($user->id === auth()->id() && $user->role === 'admin') {
return back()->with('error', 'Ganti password admin lewat profil.');
}
$validated = $request->validate([
'new_password' => ['required', 'string', 'min:6'],
]);
$user->update([
'password' => Hash::make($validated['new_password']),
]);
return redirect()->route('users.index')
->with('success', 'Password untuk ' . $user->name . ' berhasil direset.');
}
}
+43 -1
View File
@@ -111,9 +111,13 @@
<td class="px-5 py-4 text-right">
<div class="flex items-center justify-end space-x-1">
<button @click="openEdit({{ $user->id }}, '{{ addslashes($user->name) }}', '{{ $user->username }}', '{{ $user->email }}', '{{ $user->role }}', {{ $user->is_active ? 'true' : 'false' }})"
class="p-2 text-blue-600 hover:bg-blue-50 rounded-lg transition">
class="p-2 text-blue-600 hover:bg-blue-50 rounded-lg transition" title="Edit">
<i class="fa-solid fa-pen-to-square"></i>
</button>
<button onclick="resetPassword({{ $user->id }}, '{{ addslashes($user->name) }}')"
class="p-2 text-amber-600 hover:bg-amber-50 rounded-lg transition" title="Reset Password">
<i class="fa-solid fa-key"></i>
</button>
@if($user->id !== auth()->id())
<form action="{{ route('users.destroy', $user->id) }}" method="POST" class="inline"
x-data x-on:submit.prevent="if(await window.confirmSwal({text:'Hapus user ini?'})) $el.submit()">
@@ -258,6 +262,44 @@ function userManager() {
}
};
}
function resetPassword(userId, userName) {
Swal.fire({
title: 'Reset Password untuk ' + userName,
html: '<input type="password" id="new-password" class="swal2-input" placeholder="Password baru (min. 6 karakter)" minlength="6">' +
'<input type="password" id="confirm-password" class="swal2-input" placeholder="Konfirmasi password">',
confirmButtonText: '<i class="fa-solid fa-floppy-disk"></i> Simpan',
showCancelButton: true,
cancelButtonText: 'Batal',
preConfirm: () => {
const pwd = document.getElementById('new-password').value;
const confirm = document.getElementById('confirm-password').value;
if (!pwd || pwd.length < 6) {
Swal.showValidationMessage('Password minimal 6 karakter');
return false;
}
if (pwd !== confirm) {
Swal.showValidationMessage('Password tidak cocok');
return false;
}
return pwd;
}
}).then((result) => {
if (result.isConfirmed) {
fetch('{{ url('users') }}/' + userId + '/reset-password', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
'Accept': 'application/json',
},
body: JSON.stringify({ new_password: result.value }),
}).then(r => {
if (r.redirected) window.location.href = r.url;
else location.reload();
});
}
});
}
</script>
@endpush
@endsection
+1
View File
@@ -137,6 +137,7 @@ Route::middleware('auth')->group(function () {
Route::post('/users', [UserController::class, 'store'])->name('users.store');
Route::put('/users/{user}', [UserController::class, 'update'])->name('users.update');
Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('users.destroy');
Route::post('/users/{user}/reset-password', [UserController::class, 'resetPassword'])->name('users.reset-password');
Route::get('/settings/permissions', [\App\Http\Controllers\Admin\PermissionController::class, 'index'])->name('settings.permissions');
Route::post('/settings/permissions', [\App\Http\Controllers\Admin\PermissionController::class, 'update'])->name('settings.permissions.update');