|
Server : LiteSpeed System : Linux terra.hostitbro.com 5.14.0-611.54.3.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 7 16:31:24 EDT 2026 x86_64 User : outerorb ( 1091) PHP Version : 8.1.34 Disable Function : mail Directory : /home2/outerorb/emp.outerorbittech.in/admin/ | |
|
Path: /home2/outerorb/emp.outerorbittech.in/admin/activity-logs.php
Size: 14.27 KB
Permissions: 0666
<?php
require_once '../config/config.php';
require_once '../includes/helpers.php';
// Check if user is logged in and is admin
session_start();
if (!isset($_SESSION['employee_id']) || $_SESSION['role'] !== 'admin') {
header('Location: ../index.php');
exit;
}
$admin_profile = get_employee_profile($_SESSION['employee_id']);
// Get filter parameters
$action_filter = $_GET['action'] ?? '';
$limit = min(100, (int)($_GET['limit'] ?? 50));
// Get activity logs
$logs = get_activity_logs($limit, $action_filter ?: null);
// Get unique actions for filter dropdown
$pdo = db();
$stmt = $pdo->query("SELECT DISTINCT action FROM activity_logs WHERE deleted_at IS NULL ORDER BY action");
$available_actions = $stmt->fetchAll(PDO::FETCH_COLUMN);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Activity Logs - Admin Panel</title>
<link rel="stylesheet" href="../assets/css/style.css">
<link rel="stylesheet" href="../assets/css/polish.css">
<style>
.logs-filters {
display: flex;
gap: 1rem;
margin-bottom: 2rem;
flex-wrap: wrap;
align-items: flex-end;
}
.logs-filters .form-group {
flex: 0 0 auto;
min-width: 200px;
}
.logs-filters .form-group label {
display: block;
margin-bottom: 0.5rem;
color: #cbd5e1;
}
.logs-table {
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.1);
overflow-x: auto;
}
.logs-table table {
width: 100%;
border-collapse: collapse;
min-width: 100%;
}
.logs-table thead {
background: rgba(255, 255, 255, 0.08);
}
.logs-table th {
padding: 1rem;
text-align: left;
color: #cbd5e1;
font-size: 0.875rem;
font-weight: 600;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
white-space: nowrap;
}
.logs-table td {
padding: 1rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
color: #e2e8f0;
}
.logs-table tbody tr:hover {
background: rgba(255, 255, 255, 0.03);
}
.action-badge {
display: inline-block;
padding: 0.25rem 0.75rem;
border-radius: 6px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.action-create {
background: rgba(16, 185, 129, 0.2);
color: #10b981;
}
.action-update {
background: rgba(37, 99, 235, 0.2);
color: #2563eb;
}
.action-delete {
background: rgba(239, 68, 68, 0.2);
color: #ef4444;
}
.action-login {
background: rgba(245, 158, 11, 0.2);
color: #f59e0b;
}
.action-view {
background: rgba(168, 85, 247, 0.2);
color: #a855f7;
}
.log-timestamp {
color: #a0aec0;
font-size: 0.875rem;
white-space: nowrap;
}
.log-user {
color: #cbd5e1;
}
.log-description {
color: #a0aec0;
font-size: 0.875rem;
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.log-ip {
font-family: monospace;
color: #2563eb;
font-size: 0.875rem;
}
.empty-state {
text-align: center;
padding: 3rem;
color: #a0aec0;
}
.log-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
margin-bottom: 2rem;
}
.stat-item {
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
padding: 1.5rem;
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.1);
text-align: center;
}
.stat-label {
color: #a0aec0;
font-size: 0.875rem;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.stat-value {
font-size: 1.75rem;
font-weight: bold;
color: #2563eb;
margin-top: 0.5rem;
}
@media (max-width: 768px) {
.logs-filters {
flex-direction: column;
}
.logs-filters .form-group {
min-width: 100%;
}
.logs-table table {
font-size: 0.875rem;
}
.logs-table th,
.logs-table td {
padding: 0.75rem;
}
.log-description {
display: none;
}
}
</style>
</head>
<body>
<div class="main-container">
<!-- Sidebar -->
<aside class="sidebar">
<div class="sidebar-header">
<h2>HR Admin</h2>
</div>
<nav class="sidebar-nav">
<a href="dashboard.php" class="nav-link">
<span><i class="fas fa-chart-line"></i> Dashboard</span>
</a>
<a href="users.php" class="nav-link">
<span><i class="fas fa-users"></i> User Management</span>
</a>
<a href="settings.php" class="nav-link">
<span>Γ’Ε‘β’Γ―ΒΈΒ Settings</span>
</a>
<a href="backups.php" class="nav-link">
<span><i class="fas fa-database"></i> Backups</span>
</a>
<a href="activity-logs.php" class="nav-link active">
<span><i class="fas fa-book"></i> Activity Logs</span>
</a>
<a href="logout.php" class="nav-link">
<span><i class="fas fa-sign-out-alt"></i> Logout</span>
</a>
</nav>
</aside>
<!-- Main Content -->
<div class="main-content">
<!-- Top Bar -->
<div class="top-bar">
<div class="top-bar-left">
<h1>Activity Logs</h1>
</div>
<div class="top-bar-right">
<div class="notification-bell">
<button id="notificationBell" class="bell-button">
<i class="fas fa-bell"></i>
<span class="badge" id="unreadCount">0</span>
</button>
<div id="notificationDropdown" class="notification-dropdown" style="display: none;">
<div class="dropdown-header">Notifications</div>
<div id="notificationList" class="notification-list">
<div class="notification-item">Loading...</div>
</div>
</div>
</div>
<span class="user-greeting">Welcome, <?php echo htmlspecialchars($admin_profile['first_name']); ?></span>
</div>
</div>
<!-- Content Area -->
<div class="content">
<!-- Filters -->
<div class="logs-filters">
<div class="form-group">
<label for="action_filter">Filter by Action:</label>
<select id="action_filter" class="form-control" onchange="filterLogs()">
<option value="">All Actions</option>
<?php foreach ($available_actions as $action): ?>
<option value="<?php echo htmlspecialchars($action); ?>" <?php echo $action_filter === $action ? 'selected' : ''; ?>>
<?php echo ucfirst(str_replace('_', ' ', $action)); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="form-group">
<label for="limit_filter">Show Records:</label>
<select id="limit_filter" class="form-control" onchange="filterLogs()">
<option value="20" <?php echo $limit === 20 ? 'selected' : ''; ?>>Last 20</option>
<option value="50" <?php echo $limit === 50 ? 'selected' : ''; ?>>Last 50</option>
<option value="100" <?php echo $limit === 100 ? 'selected' : ''; ?>>Last 100</option>
</select>
</div>
<a href="activity-logs.php" style="margin-top: auto;" class="btn btn-secondary">
<i class=\"fas fa-file\"></i> Reset Filters
</a>
</div>
<!-- Activity Logs Table -->
<div class="logs-table">
<?php if (count($logs) > 0): ?>
<table>
<thead>
<tr>
<th>Timestamp</th>
<th>User</th>
<th>Action</th>
<th>Entity</th>
<th>Description</th>
<th>IP Address</th>
</tr>
</thead>
<tbody>
<?php foreach ($logs as $log): ?>
<tr>
<td>
<div class="log-timestamp">
<?php echo date('d M Y H:i:s', strtotime($log['created_at'])); ?>
</div>
</td>
<td>
<div class="log-user">
<?php
$user = get_user_by_id($log['user_id']);
echo $user ? htmlspecialchars($user['first_name'] . ' ' . $user['last_name']) : 'System';
?>
</div>
</td>
<td>
<span class="action-badge action-<?php echo strtolower($log['action']); ?>">
<?php echo ucfirst(str_replace('_', ' ', $log['action'])); ?>
</span>
</td>
<td>
<?php echo htmlspecialchars($log['entity_type']); ?>
<?php if ($log['entity_id']): ?>
#<?php echo $log['entity_id']; ?>
<?php endif; ?>
</td>
<td>
<div class="log-description" title="<?php echo htmlspecialchars($log['description'] ?? ''); ?>">
<?php echo htmlspecialchars($log['description'] ?? '-'); ?>
</div>
</td>
<td>
<div class="log-ip">
<?php echo htmlspecialchars($log['ip_address']); ?>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<div class="empty-state">
<p>No activity logs found.</p>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
<script src="../assets/js/app.js"></script>
<script>
function filterLogs() {
const action = document.getElementById('action_filter').value;
const limit = document.getElementById('limit_filter').value;
let url = 'activity-logs.php';
const params = [];
if (action) params.push('action=' + encodeURIComponent(action));
if (limit && limit !== '50') params.push('limit=' + encodeURIComponent(limit));
if (params.length > 0) {
url += '?' + params.join('&');
}
window.location.href = url;
}
// Load notifications
const notificationBell = document.getElementById('notificationBell');
const notificationDropdown = document.getElementById('notificationDropdown');
notificationBell.addEventListener('click', function(e) {
e.stopPropagation();
notificationDropdown.style.display = notificationDropdown.style.display === 'none' ? 'block' : 'none';
});
document.addEventListener('click', function() {
notificationDropdown.style.display = 'none';
});
</script>
</body>
</html>