302 lines
12 KiB
PHP
302 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* Pagina Visualizzazione Log Attività
|
|
* Territory Manager
|
|
*/
|
|
|
|
require_once 'config.php';
|
|
require_once 'functions.php';
|
|
require_once 'db.php';
|
|
|
|
requireAdmin(); // Solo gli admin possono visualizzare i log
|
|
|
|
$page_title = 'Log Attività';
|
|
$db = getDB();
|
|
|
|
// Parametri per filtri e paginazione
|
|
$filters = [];
|
|
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
|
|
$per_page = 50;
|
|
|
|
// Applica filtri
|
|
if (!empty($_GET['user_id'])) {
|
|
$filters['user_id'] = intval($_GET['user_id']);
|
|
}
|
|
|
|
if (!empty($_GET['action_type'])) {
|
|
$filters['action_type'] = $_GET['action_type'];
|
|
}
|
|
|
|
if (!empty($_GET['entity_type'])) {
|
|
$filters['entity_type'] = $_GET['entity_type'];
|
|
}
|
|
|
|
if (!empty($_GET['date_from'])) {
|
|
$filters['date_from'] = $_GET['date_from'];
|
|
}
|
|
|
|
if (!empty($_GET['date_to'])) {
|
|
$filters['date_to'] = $_GET['date_to'];
|
|
}
|
|
|
|
if (!empty($_GET['search'])) {
|
|
$filters['search'] = $_GET['search'];
|
|
}
|
|
|
|
// Ottieni log
|
|
$result = getActivityLogs($filters, $page, $per_page);
|
|
$logs = $result['logs'];
|
|
$total = $result['total'];
|
|
$total_pages = $result['pages'];
|
|
|
|
// Ottieni lista utenti per filtro
|
|
$users = $db->fetchAll("SELECT id, username FROM users ORDER BY username");
|
|
|
|
// Ottieni tipi di azione unici
|
|
$action_types = $db->fetchAll("SELECT DISTINCT action_type FROM activity_logs ORDER BY action_type");
|
|
|
|
// Ottieni tipi di entità unici
|
|
$entity_types = $db->fetchAll("SELECT DISTINCT entity_type FROM activity_logs WHERE entity_type IS NOT NULL ORDER BY entity_type");
|
|
|
|
include 'header.php';
|
|
?>
|
|
|
|
<div class="page-header">
|
|
<h1>
|
|
<svg width="24" height="24" fill="currentColor" viewBox="0 0 16 16">
|
|
<path d="M3 2.5a2.5 2.5 0 0 1 5 0 2.5 2.5 0 0 1 5 0v.006c0 .07 0 .27-.038.494H15a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1v7.5a1.5 1.5 0 0 1-1.5 1.5h-11A1.5 1.5 0 0 1 1 14.5V7a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h2.038A2.968 2.968 0 0 1 3 2.506V2.5zm1.068.5H7v-.5a1.5 1.5 0 1 0-3 0c0 .085.002.274.045.43a.522.522 0 0 0 .023.07zM9 3h2.932a.56.56 0 0 0 .023-.07c.043-.156.045-.345.045-.43a1.5 1.5 0 0 0-3 0V3zM1 4v2h6V4H1zm8 0v2h6V4H9zm5 3H9v8h4.5a.5.5 0 0 0 .5-.5V7zm-7 8V7H2v7.5a.5.5 0 0 0 .5.5H7z"/>
|
|
</svg>
|
|
<?php echo $page_title; ?>
|
|
</h1>
|
|
<div class="page-actions">
|
|
<a href="export_logs_pdf.php?<?php echo http_build_query($filters); ?>" class="btn btn-primary" target="_blank">
|
|
<svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
|
<path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
|
|
<path d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
|
|
</svg>
|
|
Esporta PDF
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filtri -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3>Filtri</h3>
|
|
</div>
|
|
<div class="card-body">
|
|
<form method="GET" action="logs.php" class="filter-form">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="search">Cerca</label>
|
|
<input type="text" id="search" name="search" class="form-control"
|
|
placeholder="Cerca nella descrizione o utente..."
|
|
value="<?php echo htmlspecialchars($_GET['search'] ?? ''); ?>">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="user_id">Utente</label>
|
|
<select id="user_id" name="user_id" class="form-control">
|
|
<option value="">Tutti gli utenti</option>
|
|
<?php foreach ($users as $user): ?>
|
|
<option value="<?php echo $user['id']; ?>"
|
|
<?php echo (isset($_GET['user_id']) && $_GET['user_id'] == $user['id']) ? 'selected' : ''; ?>>
|
|
<?php echo htmlspecialchars($user['username']); ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="action_type">Tipo Azione</label>
|
|
<select id="action_type" name="action_type" class="form-control">
|
|
<option value="">Tutte le azioni</option>
|
|
<?php foreach ($action_types as $type): ?>
|
|
<option value="<?php echo htmlspecialchars($type['action_type']); ?>"
|
|
<?php echo (isset($_GET['action_type']) && $_GET['action_type'] == $type['action_type']) ? 'selected' : ''; ?>>
|
|
<?php echo htmlspecialchars($type['action_type']); ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="entity_type">Tipo Entità</label>
|
|
<select id="entity_type" name="entity_type" class="form-control">
|
|
<option value="">Tutte le entità</option>
|
|
<?php foreach ($entity_types as $type): ?>
|
|
<option value="<?php echo htmlspecialchars($type['entity_type']); ?>"
|
|
<?php echo (isset($_GET['entity_type']) && $_GET['entity_type'] == $type['entity_type']) ? 'selected' : ''; ?>>
|
|
<?php echo htmlspecialchars($type['entity_type']); ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="date_from">Data Da</label>
|
|
<input type="date" id="date_from" name="date_from" class="form-control"
|
|
value="<?php echo htmlspecialchars($_GET['date_from'] ?? ''); ?>">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="date_to">Data A</label>
|
|
<input type="date" id="date_to" name="date_to" class="form-control"
|
|
value="<?php echo htmlspecialchars($_GET['date_to'] ?? ''); ?>">
|
|
</div>
|
|
|
|
<div class="form-group" style="align-self: flex-end;">
|
|
<button type="submit" class="btn btn-primary">Filtra</button>
|
|
<a href="logs.php" class="btn btn-secondary">Reset</a>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Risultati -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3>Risultati (<?php echo number_format($total); ?> log)</h3>
|
|
</div>
|
|
<div class="card-body">
|
|
<?php if (empty($logs)): ?>
|
|
<p class="text-muted">Nessun log trovato con i filtri selezionati.</p>
|
|
<?php else: ?>
|
|
<div class="table-responsive">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>Data/Ora</th>
|
|
<th>Utente</th>
|
|
<th>Azione</th>
|
|
<th>Descrizione</th>
|
|
<th>Entità</th>
|
|
<th>IP</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($logs as $log): ?>
|
|
<tr>
|
|
<td><?php echo formatDateTime($log['created_at']); ?></td>
|
|
<td>
|
|
<strong><?php echo htmlspecialchars($log['username']); ?></strong>
|
|
</td>
|
|
<td>
|
|
<span class="badge badge-<?php
|
|
echo match($log['action_type']) {
|
|
'login', 'create' => 'success',
|
|
'update', 'assign' => 'info',
|
|
'delete', 'logout' => 'danger',
|
|
'return' => 'warning',
|
|
default => 'secondary'
|
|
};
|
|
?>">
|
|
<?php echo htmlspecialchars($log['action_type']); ?>
|
|
</span>
|
|
</td>
|
|
<td><?php echo htmlspecialchars($log['action_description']); ?></td>
|
|
<td>
|
|
<?php if ($log['entity_type']): ?>
|
|
<small class="text-muted">
|
|
<?php echo htmlspecialchars($log['entity_type']); ?>
|
|
<?php if ($log['entity_id']): ?>
|
|
#<?php echo $log['entity_id']; ?>
|
|
<?php endif; ?>
|
|
</small>
|
|
<?php else: ?>
|
|
<span class="text-muted">-</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td>
|
|
<small class="text-muted"><?php echo htmlspecialchars($log['ip_address']); ?></small>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Paginazione -->
|
|
<?php if ($total_pages > 1): ?>
|
|
<div class="pagination">
|
|
<?php
|
|
$query_params = $_GET;
|
|
unset($query_params['page']);
|
|
$base_query = !empty($query_params) ? '&' . http_build_query($query_params) : '';
|
|
?>
|
|
|
|
<?php if ($page > 1): ?>
|
|
<a href="?page=1<?php echo $base_query; ?>" class="btn btn-sm btn-secondary">Prima</a>
|
|
<a href="?page=<?php echo $page - 1; ?><?php echo $base_query; ?>" class="btn btn-sm btn-secondary">Precedente</a>
|
|
<?php endif; ?>
|
|
|
|
<span class="pagination-info">
|
|
Pagina <?php echo $page; ?> di <?php echo $total_pages; ?>
|
|
</span>
|
|
|
|
<?php if ($page < $total_pages): ?>
|
|
<a href="?page=<?php echo $page + 1; ?><?php echo $base_query; ?>" class="btn btn-sm btn-secondary">Successiva</a>
|
|
<a href="?page=<?php echo $total_pages; ?><?php echo $base_query; ?>" class="btn btn-sm btn-secondary">Ultima</a>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.filter-form .form-row {
|
|
display: flex;
|
|
gap: 1rem;
|
|
margin-bottom: 1rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.filter-form .form-group {
|
|
flex: 1;
|
|
min-width: 200px;
|
|
}
|
|
|
|
.badge {
|
|
padding: 0.25rem 0.5rem;
|
|
border-radius: 0.25rem;
|
|
font-size: 0.75rem;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.badge-success { background-color: #28a745; color: white; }
|
|
.badge-info { background-color: #17a2b8; color: white; }
|
|
.badge-warning { background-color: #ffc107; color: black; }
|
|
.badge-danger { background-color: #dc3545; color: white; }
|
|
.badge-secondary { background-color: #6c757d; color: white; }
|
|
|
|
.pagination {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
margin-top: 1rem;
|
|
padding-top: 1rem;
|
|
border-top: 1px solid #dee2e6;
|
|
}
|
|
|
|
.pagination-info {
|
|
margin: 0 1rem;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.table-responsive {
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.table tbody tr:hover {
|
|
background-color: #f8f9fa;
|
|
}
|
|
</style>
|
|
|
|
<?php include 'footer.php'; ?>
|