Sindbad~EG File Manager

Current Path : /home/copmadinaarea/thecopmadinaarea.org/reports/dashboard/
Upload File :
Current File : /home/copmadinaarea/thecopmadinaarea.org/reports/dashboard/audit.php

<?php
session_start();
require_once '../config/database.php';
require_once '../includes/functions.php';

if (!isset($_SESSION['user_id'])) {
    header('Location: ../login.php');
    exit();
}

// Check permission for audit access
if (!checkPermission('admin') && $_SESSION['user_level'] !== 'superuser') {
    header('Location: ' . $_SESSION['user_level'] . '.php?error=access_denied');
    exit();
}

$page_title = 'Audit Logs';
$page_description = 'System activity and change tracking';

// Get filters
$user_filter = isset($_GET['user']) ? (int)$_GET['user'] : 0;
$action_filter = isset($_GET['action']) ? sanitizeInput($_GET['action']) : '';
$date_from = isset($_GET['date_from']) ? sanitizeInput($_GET['date_from']) : '';
$date_to = isset($_GET['date_to']) ? sanitizeInput($_GET['date_to']) : '';

// Pagination
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$per_page = 50;
$offset = ($page - 1) * $per_page;

// Build query conditions
$where_conditions = [];
$params = [];

if ($user_filter > 0) {
    $where_conditions[] = "al.user_id = :user_id";
    $params[':user_id'] = $user_filter;
}

if (!empty($action_filter)) {
    $where_conditions[] = "al.action = :action";
    $params[':action'] = $action_filter;
}

if (!empty($date_from)) {
    $where_conditions[] = "DATE(al.created_at) >= :date_from";
    $params[':date_from'] = $date_from;
}

if (!empty($date_to)) {
    $where_conditions[] = "DATE(al.created_at) <= :date_to";
    $params[':date_to'] = $date_to;
}

// Apply user level restrictions
if ($_SESSION['user_level'] !== 'superuser') {
    if ($_SESSION['user_level'] === 'area') {
        $where_conditions[] = "u.area_id = :area_id";
        $params[':area_id'] = $_SESSION['area_id'];
    } elseif ($_SESSION['user_level'] === 'district') {
        $where_conditions[] = "u.district_id = :district_id";
        $params[':district_id'] = $_SESSION['district_id'];
    } elseif ($_SESSION['user_level'] === 'assembly') {
        $where_conditions[] = "u.assembly_id = :assembly_id";
        $params[':assembly_id'] = $_SESSION['assembly_id'];
    }
}

$where_clause = !empty($where_conditions) ? 'WHERE ' . implode(' AND ', $where_conditions) : '';

// Count total records
$count_query = "SELECT COUNT(*) as total 
                FROM audit_logs al 
                JOIN users u ON al.user_id = u.id 
                $where_clause";
$count_stmt = $db->prepare($count_query);
foreach ($params as $key => $value) {
    $count_stmt->bindValue($key, $value);
}
$count_stmt->execute();
$total_records = $count_stmt->fetch(PDO::FETCH_ASSOC)['total'];
$total_pages = ceil($total_records / $per_page);

// Get audit logs
$audit_query = "SELECT al.*, u.first_name, u.last_name, u.username, u.user_level 
                FROM audit_logs al 
                JOIN users u ON al.user_id = u.id 
                $where_clause 
                ORDER BY al.created_at DESC 
                LIMIT :offset, :per_page";

$audit_stmt = $db->prepare($audit_query);
foreach ($params as $key => $value) {
    $audit_stmt->bindValue($key, $value);
}
$audit_stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$audit_stmt->bindValue(':per_page', $per_page, PDO::PARAM_INT);
$audit_stmt->execute();
$audit_logs = $audit_stmt->fetchAll(PDO::FETCH_ASSOC);

// Get users for filter dropdown
$users_query = "SELECT id, first_name, last_name, username FROM users WHERE is_active = 1 ORDER BY first_name, last_name";
$users_stmt = $db->prepare($users_query);
$users_stmt->execute();
$users = $users_stmt->fetchAll(PDO::FETCH_ASSOC);

// Get unique actions for filter
$actions_query = "SELECT DISTINCT action FROM audit_logs ORDER BY action";
$actions_stmt = $db->prepare($actions_query);
$actions_stmt->execute();
$actions = $actions_stmt->fetchAll(PDO::FETCH_ASSOC);

include '../includes/header.php';
?>

<!-- Filters -->
<div class="bg-white rounded-lg shadow-sm mb-6">
    <div class="p-6 border-b border-gray-200">
        <h3 class="text-lg font-semibold text-gray-800">Filter Audit Logs</h3>
    </div>
    <div class="p-6">
        <form method="GET" action="" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4">
            <div>
                <label for="user" class="block text-sm font-medium text-gray-700 mb-2">User</label>
                <select id="user" name="user" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-cop-blue focus:border-transparent">
                    <option value="">All Users</option>
                    <?php foreach ($users as $user): ?>
                    <option value="<?php echo $user['id']; ?>" <?php echo $user_filter == $user['id'] ? 'selected' : ''; ?>>
                        <?php echo htmlspecialchars($user['first_name'] . ' ' . $user['last_name']); ?>
                    </option>
                    <?php endforeach; ?>
                </select>
            </div>
            
            <div>
                <label for="action" class="block text-sm font-medium text-gray-700 mb-2">Action</label>
                <select id="action" name="action" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-cop-blue focus:border-transparent">
                    <option value="">All Actions</option>
                    <?php foreach ($actions as $action): ?>
                    <option value="<?php echo htmlspecialchars($action['action']); ?>" <?php echo $action_filter == $action['action'] ? 'selected' : ''; ?>>
                        <?php echo htmlspecialchars($action['action']); ?>
                    </option>
                    <?php endforeach; ?>
                </select>
            </div>
            
            <div>
                <label for="date_from" class="block text-sm font-medium text-gray-700 mb-2">From Date</label>
                <input type="date" 
                       id="date_from" 
                       name="date_from" 
                       value="<?php echo htmlspecialchars($date_from); ?>"
                       class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-cop-blue focus:border-transparent">
            </div>
            
            <div>
                <label for="date_to" class="block text-sm font-medium text-gray-700 mb-2">To Date</label>
                <input type="date" 
                       id="date_to" 
                       name="date_to" 
                       value="<?php echo htmlspecialchars($date_to); ?>"
                       class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-cop-blue focus:border-transparent">
            </div>
            
            <div class="flex items-end">
                <button type="submit" class="w-full px-4 py-2 bg-cop-blue text-white rounded-lg hover:bg-cop-light-blue transition duration-200">
                    <i class="fas fa-search mr-2"></i>Filter
                </button>
            </div>
        </form>
        
        <?php if ($user_filter || $action_filter || $date_from || $date_to): ?>
        <div class="mt-4">
            <a href="audit.php" class="text-sm text-gray-600 hover:text-gray-800">
                <i class="fas fa-times mr-1"></i>Clear Filters
            </a>
        </div>
        <?php endif; ?>
    </div>
</div>

<!-- Audit Logs -->
<div class="bg-white rounded-lg shadow-sm">
    <div class="p-6 border-b border-gray-200">
        <div class="flex items-center justify-between">
            <h3 class="text-lg font-semibold text-gray-800">Audit Logs</h3>
            <div class="text-sm text-gray-600">
                Total: <?php echo number_format($total_records); ?> records
            </div>
        </div>
    </div>
    
    <div class="overflow-x-auto">
        <?php if (empty($audit_logs)): ?>
        <div class="text-center py-12">
            <i class="fas fa-history text-4xl text-gray-400 mb-4"></i>
            <h3 class="text-lg font-medium text-gray-600 mb-2">No audit logs found</h3>
            <p class="text-gray-500">No activities match your current filters.</p>
        </div>
        <?php else: ?>
        <table class="min-w-full divide-y divide-gray-200">
            <thead class="bg-gray-50">
                <tr>
                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">User</th>
                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Action</th>
                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Table</th>
                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Record ID</th>
                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">IP Address</th>
                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date/Time</th>
                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Details</th>
                </tr>
            </thead>
            <tbody class="bg-white divide-y divide-gray-200">
                <?php foreach ($audit_logs as $log): ?>
                <tr class="hover:bg-gray-50">
                    <td class="px-6 py-4 whitespace-nowrap">
                        <div class="flex items-center">
                            <div class="w-8 h-8 bg-gray-200 rounded-full flex items-center justify-center mr-3">
                                <span class="text-xs font-medium text-gray-600">
                                    <?php echo strtoupper(substr($log['first_name'], 0, 1) . substr($log['last_name'], 0, 1)); ?>
                                </span>
                            </div>
                            <div>
                                <div class="text-sm font-medium text-gray-900">
                                    <?php echo htmlspecialchars($log['first_name'] . ' ' . $log['last_name']); ?>
                                </div>
                                <div class="text-sm text-gray-500 capitalize">
                                    <?php echo htmlspecialchars($log['user_level']); ?>
                                </div>
                            </div>
                        </div>
                    </td>
                    <td class="px-6 py-4 whitespace-nowrap">
                        <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full 
                            <?php 
                            echo $log['action'] === 'CREATE' ? 'bg-green-100 text-green-800' : 
                                ($log['action'] === 'UPDATE' ? 'bg-blue-100 text-blue-800' : 
                                ($log['action'] === 'DELETE' ? 'bg-red-100 text-red-800' : 
                                ($log['action'] === 'LOGIN' ? 'bg-purple-100 text-purple-800' : 'bg-gray-100 text-gray-800')));
                            ?>">
                            <?php echo htmlspecialchars($log['action']); ?>
                        </span>
                    </td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
                        <?php echo htmlspecialchars($log['table_name']); ?>
                    </td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
                        <?php echo $log['record_id'] ? htmlspecialchars($log['record_id']) : '-'; ?>
                    </td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
                        <?php echo htmlspecialchars($log['ip_address']); ?>
                    </td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
                        <?php echo formatDateTime($log['created_at']); ?>
                    </td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
                        <?php if ($log['old_values'] || $log['new_values']): ?>
                        <button onclick="showAuditDetails(<?php echo htmlspecialchars(json_encode($log)); ?>)" 
                                class="text-cop-blue hover:text-cop-light-blue">
                            <i class="fas fa-eye"></i>
                        </button>
                        <?php else: ?>
                        -
                        <?php endif; ?>
                    </td>
                </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
        
        <!-- Pagination -->
        <?php if ($total_pages > 1): ?>
        <div class="px-6 py-4 border-t border-gray-200">
            <div class="flex items-center justify-between">
                <div class="text-sm text-gray-600">
                    Showing <?php echo $offset + 1; ?> to <?php echo min($offset + $per_page, $total_records); ?> of <?php echo $total_records; ?> records
                </div>
                
                <div class="flex space-x-2">
                    <?php if ($page > 1): ?>
                    <a href="?page=<?php echo $page - 1; ?>&user=<?php echo $user_filter; ?>&action=<?php echo $action_filter; ?>&date_from=<?php echo $date_from; ?>&date_to=<?php echo $date_to; ?>" 
                       class="px-3 py-2 bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300 transition duration-200">
                        <i class="fas fa-chevron-left"></i>
                    </a>
                    <?php endif; ?>
                    
                    <?php for ($i = max(1, $page - 2); $i <= min($total_pages, $page + 2); $i++): ?>
                    <a href="?page=<?php echo $i; ?>&user=<?php echo $user_filter; ?>&action=<?php echo $action_filter; ?>&date_from=<?php echo $date_from; ?>&date_to=<?php echo $date_to; ?>" 
                       class="px-3 py-2 rounded-lg transition duration-200 <?php echo $i === $page ? 'bg-cop-blue text-white' : 'bg-gray-200 text-gray-700 hover:bg-gray-300'; ?>">
                        <?php echo $i; ?>
                    </a>
                    <?php endfor; ?>
                    
                    <?php if ($page < $total_pages): ?>
                    <a href="?page=<?php echo $page + 1; ?>&user=<?php echo $user_filter; ?>&action=<?php echo $action_filter; ?>&date_from=<?php echo $date_from; ?>&date_to=<?php echo $date_to; ?>" 
                       class="px-3 py-2 bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300 transition duration-200">
                        <i class="fas fa-chevron-right"></i>
                    </a>
                    <?php endif; ?>
                </div>
            </div>
        </div>
        <?php endif; ?>
        <?php endif; ?>
    </div>
</div>

<!-- Audit Details Modal -->
<div id="auditModal" class="fixed inset-0 bg-gray-600 bg-opacity-50 hidden z-50">
    <div class="flex items-center justify-center min-h-screen p-4">
        <div class="bg-white rounded-lg shadow-xl max-w-2xl w-full max-h-96 overflow-y-auto">
            <div class="p-6 border-b border-gray-200">
                <div class="flex items-center justify-between">
                    <h3 class="text-lg font-semibold text-gray-800">Audit Details</h3>
                    <button onclick="closeAuditModal()" class="text-gray-400 hover:text-gray-600">
                        <i class="fas fa-times"></i>
                    </button>
                </div>
            </div>
            <div class="p-6">
                <div id="auditDetailsContent"></div>
            </div>
        </div>
    </div>
</div>

<script>
function showAuditDetails(log) {
    const modal = document.getElementById('auditModal');
    const content = document.getElementById('auditDetailsContent');
    
    let html = `
        <div class="space-y-4">
            <div>
                <h4 class="font-medium text-gray-800 mb-2">Action Information</h4>
                <div class="bg-gray-50 rounded-lg p-4">
                    <div class="grid grid-cols-2 gap-4 text-sm">
                        <div><span class="font-medium">User:</span> ${log.first_name} ${log.last_name}</div>
                        <div><span class="font-medium">Action:</span> ${log.action}</div>
                        <div><span class="font-medium">Table:</span> ${log.table_name}</div>
                        <div><span class="font-medium">Record ID:</span> ${log.record_id || 'N/A'}</div>
                        <div><span class="font-medium">IP Address:</span> ${log.ip_address}</div>
                        <div><span class="font-medium">Date/Time:</span> ${new Date(log.created_at).toLocaleString()}</div>
                    </div>
                </div>
            </div>
    `;
    
    if (log.old_values) {
        html += `
            <div>
                <h4 class="font-medium text-gray-800 mb-2">Old Values</h4>
                <div class="bg-red-50 rounded-lg p-4">
                    <pre class="text-sm text-gray-700 whitespace-pre-wrap">${JSON.stringify(JSON.parse(log.old_values), null, 2)}</pre>
                </div>
            </div>
        `;
    }
    
    if (log.new_values) {
        html += `
            <div>
                <h4 class="font-medium text-gray-800 mb-2">New Values</h4>
                <div class="bg-green-50 rounded-lg p-4">
                    <pre class="text-sm text-gray-700 whitespace-pre-wrap">${JSON.stringify(JSON.parse(log.new_values), null, 2)}</pre>
                </div>
            </div>
        `;
    }
    
    html += '</div>';
    content.innerHTML = html;
    modal.classList.remove('hidden');
}

function closeAuditModal() {
    document.getElementById('auditModal').classList.add('hidden');
}

// Close modal when clicking outside
document.getElementById('auditModal').addEventListener('click', function(e) {
    if (e.target === this) {
        closeAuditModal();
    }
});
</script>

<?php include '../includes/footer.php'; ?>

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists