Major changes: - New ThemeManager with Twig templating and SCSS compilation - Dynamic themes system (themes/default, themes/demo) - LogManager with SQLite storage and syslog forwarding - RequestLogger with static helper methods - Admin UI overhaul (Bootstrap 5, dark mode) - Admin config page with logging and theme settings - Admin logs page with filters and search - Removed legacy Mustache templates - Removed test plugin and theme - Composer dependencies: Twig, scssphp, CommonMark, MaxMind GeoIP
80 lines
4.3 KiB
PHP
80 lines
4.3 KiB
PHP
<h2 class="mb-4"><i class="bi bi-journal-text"></i> Logs</h2>
|
|
|
|
<div class="card shadow-sm mb-4">
|
|
<div class="card-body">
|
|
<form method="GET" action="/admin/logs" class="row g-3 align-items-end">
|
|
<div class="col-md-3">
|
|
<label for="filter_event" class="form-label">Gebeurtenis</label>
|
|
<select class="form-select" id="filter_event" name="event">
|
|
<option value="">Alle</option>
|
|
<?php foreach ($eventTypes as $ev): ?>
|
|
<option value="<?= $ev ?>" <?= $filterEvent === $ev ? 'selected' : '' ?>><?= ucfirst($ev) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label for="filter_level" class="form-label">Niveau</label>
|
|
<select class="form-select" id="filter_level" name="level">
|
|
<option value="">Alle</option>
|
|
<?php foreach ($levelTypes as $lv): ?>
|
|
<option value="<?= $lv ?>" <?= $filterLevel === $lv ? 'selected' : '' ?>><?= ucfirst($lv) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label for="filter_search" class="form-label">Zoeken</label>
|
|
<input type="text" class="form-control" id="filter_search" name="search" value="<?= htmlspecialchars($filterSearch) ?>" placeholder="Zoek in bericht...">
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label for="filter_limit" class="form-label">Aantal</label>
|
|
<select class="form-select" id="filter_limit" name="limit">
|
|
<?php foreach ([50, 100, 200, 500, 1000] as $n): ?>
|
|
<option value="<?= $n ?>" <?= $limit === $n ? 'selected' : '' ?>><?= $n ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-12 d-flex justify-content-between">
|
|
<button type="submit" class="btn btn-primary"><i class="bi bi-funnel"></i> Filteren</button>
|
|
<div>
|
|
<a href="/admin/logs?download=1<?= $filterEvent ? '&event=' . urlencode($filterEvent) : '' ?><?= $filterLevel ? '&level=' . urlencode($filterLevel) : '' ?><?= $filterSearch ? '&search=' . urlencode($filterSearch) : '' ?>" class="btn btn-sm btn-outline-secondary"><i class="bi bi-download"></i> Download</a>
|
|
<a href="/admin/logs?clear=1" class="btn btn-sm btn-outline-danger" onclick="return confirm('Log wissen?')"><i class="bi bi-trash"></i> Wissen</a>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
|
<small class="text-muted"><?= count($logEntries) ?> regels</small>
|
|
</div>
|
|
<div class="card shadow-sm">
|
|
<div class="card-body p-0" style="max-height: 600px; overflow-y: auto;">
|
|
<?php if (empty($logEntries)): ?>
|
|
<p class="text-muted p-3 mb-0">Geen logregels gevonden.</p>
|
|
<?php else: ?>
|
|
<table class="table table-sm table-hover mb-0">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>Tijd</th>
|
|
<th>Gebeurtenis</th>
|
|
<th>Niveau</th>
|
|
<th>IP</th>
|
|
<th>Bericht</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($logEntries as $log): ?>
|
|
<tr>
|
|
<td class="text-nowrap small text-muted"><?= htmlspecialchars($log['time']) ?></td>
|
|
<td><span class="badge bg-secondary"><?= htmlspecialchars($log['event']) ?></span></td>
|
|
<td><span class="badge bg-<?= $log['level'] === 'warning' ? 'warning text-dark' : ($log['level'] === 'error' ? 'danger' : 'info') ?>"><?= htmlspecialchars($log['level']) ?></span></td>
|
|
<td><code class="small"><?= htmlspecialchars($log['ip']) ?></code></td>
|
|
<td><?= htmlspecialchars($log['message']) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|