Add admin audit log viewer and system settings

Phase 5 (Admin Panel):
- Audit log viewer: searchable with action/date filters, expandable
  rows showing JSON changes, color-coded action chips, user avatars
- System settings: tabbed page (General, API Credentials, Billing,
  Notifications) with masked sensitive values, per-group save
- Settings model with get/set/getGroup/setGroup helpers
- Settings migration for key-value store with groups
- 52 tests passing, build clean

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude Dev
2026-02-09 10:45:31 -05:00
parent d9ec414264
commit 813fde30c2
9 changed files with 1345 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\AuditLog;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
class AuditLogController extends Controller
{
public function index(Request $request): Response
{
$query = AuditLog::query()
->with('user:id,name,email')
->latest();
// Search by user name/email, action, or resource type
if ($search = $request->input('search')) {
$query->where(function ($q) use ($search): void {
$q->where('action', 'like', "%{$search}%")
->orWhere('resource_type', 'like', "%{$search}%")
->orWhere('ip_address', 'like', "%{$search}%")
->orWhereHas('user', function ($userQuery) use ($search): void {
$userQuery->where('name', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%");
});
});
}
// Filter by action
if ($action = $request->input('action')) {
$query->where('action', $action);
}
// Filter by date range
if ($dateFrom = $request->input('date_from')) {
$query->whereDate('created_at', '>=', $dateFrom);
}
if ($dateTo = $request->input('date_to')) {
$query->whereDate('created_at', '<=', $dateTo);
}
$auditLogs = $query->paginate(25)->withQueryString();
// Get distinct actions for the filter dropdown
$actions = AuditLog::query()
->distinct()
->orderBy('action')
->pluck('action');
return Inertia::render('Admin/AuditLogs/Index', [
'auditLogs' => $auditLogs,
'actions' => $actions,
'filters' => [
'search' => $request->input('search', ''),
'action' => $request->input('action', ''),
'date_from' => $request->input('date_from', ''),
'date_to' => $request->input('date_to', ''),
],
]);
}
}