From cd24cc53a0f6a44e9a2de978b1fbe83f271060db Mon Sep 17 00:00:00 2001 From: Agent Date: Sun, 7 Jun 2026 12:43:50 -0400 Subject: [PATCH] Add per-column filters, smart pagination (25/page), and date range filter to audit logs --- public/assets/css/style.css | 73 +++++++++++ src/Controllers/AdminController.php | 25 +++- src/Services/AuditService.php | 16 +++ views/admin/audit.php | 197 ++++++++++++++++++++++++---- 4 files changed, 278 insertions(+), 33 deletions(-) diff --git a/public/assets/css/style.css b/public/assets/css/style.css index c4b6940..042d203 100755 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -2033,6 +2033,79 @@ textarea.form-input { font-family: var(--font-mono); } +.filter-row th { + padding: 0.5rem 0.4rem !important; + vertical-align: middle; +} + +.filter-row .form-input, +.filter-row .form-select { + width: 100%; + padding: 0.35rem 0.5rem; + font-size: 0.78rem; + box-sizing: border-box; +} + +.filter-date-group { + display: flex; + align-items: center; + gap: 0.2rem; +} + +.filter-date-group .form-input { + flex: 1; + min-width: 0; + padding: 0.35rem 0.3rem; + font-size: 0.7rem; +} + +.filter-date-sep { + color: var(--text-muted); + font-size: 0.75rem; + flex-shrink: 0; +} + +.filter-input-wrap { + position: relative; + display: flex; + align-items: center; +} + +.filter-input-wrap .form-input { + padding-right: 1.5rem; +} + +.filter-clear { + position: absolute; + right: 2px; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + color: var(--text-muted); + font-size: 1rem; + line-height: 1; + cursor: pointer; + padding: 2px 4px; + border-radius: 3px; +} + +.filter-clear:hover { + color: var(--text-primary); + background: var(--bg-hover); +} + +.filter-input { + min-width: 80px; +} + +.page-ellipsis { + background: transparent !important; + border: none !important; + color: var(--text-muted) !important; + cursor: default; +} + /* ========================================================================== Security Status ========================================================================== */ diff --git a/src/Controllers/AdminController.php b/src/Controllers/AdminController.php index 9f276e5..eb86d29 100755 --- a/src/Controllers/AdminController.php +++ b/src/Controllers/AdminController.php @@ -168,19 +168,34 @@ class AdminController $page = (int) ($_GET['page'] ?? 1); $action = $_GET['action'] ?? ''; - $userId = $_GET['user_id'] ?? ''; + $username = $_GET['username'] ?? ''; + $ipAddress = $_GET['ip_address'] ?? ''; + $entityType = $_GET['entity_type'] ?? ''; + $details = $_GET['details'] ?? ''; + $dateFrom = $_GET['date_from'] ?? ''; + $dateTo = $_GET['date_to'] ?? ''; $filters = []; - if ($action) $filters['action'] = $action; - if ($userId) $filters['user_id'] = (int) $userId; + if ($action !== '') $filters['action'] = $action; + if ($username !== '') $filters['username'] = $username; + if ($ipAddress !== '') $filters['ip_address'] = $ipAddress; + if ($entityType !== '') $filters['entity_type'] = $entityType; + if ($details !== '') $filters['details'] = $details; + if ($dateFrom !== '') $filters['date_from'] = $dateFrom; + if ($dateTo !== '') $filters['date_to'] = $dateTo; - $logs = $this->auditService->getAuditLogs($page, 50, $filters); + $logs = $this->auditService->getAuditLogs($page, 25, $filters); $this->view->display('admin.audit', [ 'title' => 'Audit Logs - ServerManager', 'logs' => $logs, 'action' => $action, - 'userId' => $userId, + 'username' => $username, + 'ipAddress' => $ipAddress, + 'entityType' => $entityType, + 'details' => $details, + 'dateFrom' => $dateFrom, + 'dateTo' => $dateTo, ]); } diff --git a/src/Services/AuditService.php b/src/Services/AuditService.php index e1c94d3..d9dca24 100755 --- a/src/Services/AuditService.php +++ b/src/Services/AuditService.php @@ -157,11 +157,27 @@ class AuditService $params[] = $filters['user_id']; } + if (!empty($filters['username'])) { + $where[] = '(al.username LIKE ? OR u.username LIKE ?)'; + $params[] = '%' . $filters['username'] . '%'; + $params[] = '%' . $filters['username'] . '%'; + } + if (!empty($filters['entity_type'])) { $where[] = 'al.entity_type = ?'; $params[] = $filters['entity_type']; } + if (!empty($filters['ip_address'])) { + $where[] = 'al.ip_address LIKE ?'; + $params[] = '%' . $filters['ip_address'] . '%'; + } + + if (!empty($filters['details'])) { + $where[] = 'al.details LIKE ?'; + $params[] = '%' . $filters['details'] . '%'; + } + if (!empty($filters['date_from'])) { $where[] = 'al.created_at >= ?'; $params[] = $filters['date_from']; diff --git a/views/admin/audit.php b/views/admin/audit.php index 306ed17..5450c7b 100755 --- a/views/admin/audit.php +++ b/views/admin/audit.php @@ -1,30 +1,29 @@
-
-
- -
-
@@ -37,6 +36,65 @@ $userId = $userId ?? ''; + + + + + + + + @@ -69,22 +127,105 @@ $userId = $userId ?? '';
Details IP Address
+
+ + + +
+
+
+ + + + +
+
+ + + + +
+ + + + +
+
+
+ + + + +
+
- 1): ?> + 1): + $window = 3; + $qs = function (int $p) use ($action, $username, $ipAddress, $entityType, $details, $dateFrom, $dateTo) { + return '?page=' . $p + . ($action !== '' ? '&action=' . urlencode($action) : '') + . ($username !== '' ? '&username=' . urlencode($username) : '') + . ($ipAddress !== '' ? '&ip_address=' . urlencode($ipAddress) : '') + . ($entityType !== '' ? '&entity_type=' . urlencode($entityType) : '') + . ($details !== '' ? '&details=' . urlencode($details) : '') + . ($dateFrom !== '' ? '&date_from=' . urlencode($dateFrom) : '') + . ($dateTo !== '' ? '&date_to=' . urlencode($dateTo) : ''); + }; + ?>
-- 2.43.0