Initial commit: Struktur aplikasi ilycats
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Role;
|
||||
use App\Traits\LogsActivity;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Gate; // WAJIB DIIMPORT
|
||||
use Illuminate\Validation\Rules;
|
||||
use App\Models\ActivityLog;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Exports\ActivityLogExport;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
use LogsActivity;
|
||||
|
||||
/**
|
||||
* Menampilkan daftar user.
|
||||
* Izin: users (read)
|
||||
*/
|
||||
public function index(Request $request): View
|
||||
{
|
||||
// GANTI: Otorisasi berdasarkan Matriks Permission
|
||||
Gate::authorize('check-access', ['users', 'read']);
|
||||
|
||||
$users = User::query()
|
||||
->with('role')
|
||||
->when($request->search, function ($query, $search) {
|
||||
$query->where('name', 'like', "%{$search}%")
|
||||
->orWhere('email', 'like', "%{$search}%");
|
||||
})
|
||||
->latest()
|
||||
->paginate(10);
|
||||
|
||||
return view('pages.users.index', compact('users'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Form tambah user baru.
|
||||
* Izin: users (create)
|
||||
*/
|
||||
public function create(): View
|
||||
{
|
||||
Gate::authorize('check-access', ['users', 'create']);
|
||||
|
||||
$roles = Role::all();
|
||||
return view('pages.users.create', compact('roles'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Simpan user baru.
|
||||
* Izin: users (create)
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
Gate::authorize('check-access', ['users', 'create']);
|
||||
|
||||
$validated = $request->validate([
|
||||
'name' => 'required|string|max:255',
|
||||
'email' => 'required|string|lowercase|email|max:255|unique:users',
|
||||
'phone' => 'nullable|string|max:15',
|
||||
'role_id' => 'required|exists:roles,id',
|
||||
'password' => ['required', 'confirmed', Rules\Password::defaults()],
|
||||
]);
|
||||
|
||||
$role = Role::find($validated['role_id']);
|
||||
|
||||
$user = User::create([
|
||||
'name' => $validated['name'],
|
||||
'email' => $validated['email'],
|
||||
'phone' => $validated['phone'],
|
||||
'role_id' => $validated['role_id'],
|
||||
'role' => $role->slug,
|
||||
'password' => Hash::make($validated['password']),
|
||||
]);
|
||||
|
||||
// Catat aktivitas (Gunakan parameter model untuk log)
|
||||
$this->logAction('CREATED', $user, "Mendaftarkan user baru: {$user->name} sebagai {$role->name}", 'User');
|
||||
|
||||
return redirect()->route('admin.users.index')->with('success', "User {$user->name} berhasil ditambahkan.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Halaman Edit User.
|
||||
* Izin: users (update)
|
||||
*/
|
||||
public function edit(User $user): View
|
||||
{
|
||||
Gate::authorize('check-access', ['users', 'update']);
|
||||
|
||||
$roles = Role::all();
|
||||
return view('pages.users.edit', compact('user', 'roles'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Data User.
|
||||
* Izin: users (update)
|
||||
*/
|
||||
public function update(Request $request, User $user): RedirectResponse
|
||||
{
|
||||
Gate::authorize('check-access', ['users', 'update']);
|
||||
|
||||
$validated = $request->validate([
|
||||
'name' => 'required|string|max:255',
|
||||
'email' => 'required|email|unique:users,email,' . $user->id,
|
||||
'role_id' => 'required|exists:roles,id',
|
||||
'phone' => 'nullable|string|max:15',
|
||||
]);
|
||||
|
||||
$newRole = Role::find($validated['role_id']);
|
||||
|
||||
// Keamanan Logika: Tetap pertahankan agar user tidak merusak akun sendiri
|
||||
if ($user->id === auth()->id() && $newRole->slug !== 'admin' && auth()->user()->role === 'admin') {
|
||||
return back()->with('error', 'Akses Ditolak! Anda tidak bisa menurunkan otoritas Admin Anda sendiri.');
|
||||
}
|
||||
|
||||
$user->update(array_merge($validated, [
|
||||
'role' => $newRole->slug
|
||||
]));
|
||||
|
||||
$this->logAction('UPDATED', $user, "Memperbarui data profil user: {$user->name}", 'User');
|
||||
|
||||
return redirect()->route('admin.users.index')->with('success', "Data {$user->name} berhasil diperbarui.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Hapus User.
|
||||
* Izin: users (delete)
|
||||
*/
|
||||
public function destroy(User $user): RedirectResponse
|
||||
{
|
||||
Gate::authorize('check-access', ['users', 'delete']);
|
||||
|
||||
if ($user->id === auth()->id()) {
|
||||
return back()->with('error', 'Akses Ditolak! Anda tidak dapat menghapus akun Anda sendiri.');
|
||||
}
|
||||
|
||||
$userName = $user->name;
|
||||
$this->logAction('DELETED', $user, "Menghapus user: {$userName}", 'User');
|
||||
$user->delete();
|
||||
|
||||
return redirect()->route('admin.users.index')->with('success', "User {$userName} telah dihapus.");
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* AUDIT TRAIL / LOGS SECTION */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Daftar Aktivitas.
|
||||
* Izin: logs (read)
|
||||
*/
|
||||
public function activityLogs(Request $request)
|
||||
{
|
||||
Gate::authorize('check-access', ['logs', 'read']);
|
||||
|
||||
$logs = ActivityLog::with('user')
|
||||
->when($request->search, function ($query, $search) {
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('description', 'like', "%{$search}%")
|
||||
->orWhereHas('user', function ($qu) use ($search) {
|
||||
$qu->where('name', 'like', "%{$search}%");
|
||||
});
|
||||
});
|
||||
})
|
||||
->when($request->action, function ($query, $action) {
|
||||
$query->where('action', 'like', "%{$action}%");
|
||||
})
|
||||
->latest()
|
||||
->paginate(20);
|
||||
|
||||
return view('pages.admin.logs', compact('logs'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Export Logs ke Excel.
|
||||
* Izin: logs (read)
|
||||
*/
|
||||
public function exportLogs()
|
||||
{
|
||||
Gate::authorize('check-access', ['logs', 'read']);
|
||||
return Excel::download(new ActivityLogExport, 'audit_trail_'.now()->format('Ymd').'.xlsx');
|
||||
}
|
||||
|
||||
/**
|
||||
* Bersihkan Logs.
|
||||
* Izin: logs (delete)
|
||||
*/
|
||||
public function clearLogs()
|
||||
{
|
||||
Gate::authorize('check-access', ['logs', 'delete']);
|
||||
ActivityLog::truncate();
|
||||
return back()->with('success', 'Seluruh riwayat aktivitas telah dibersihkan.');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user