You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
5.6 KiB
HTML

2 months ago
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Audit Log</title>
<style>
:root { color-scheme: dark; }
body { margin:0; font-family:system-ui, Arial; background:#0e0f12; color:#e8e8ea; }
header { padding:16px 20px; border-bottom:1px solid #23242a; display:flex; align-items:center; gap:12px; }
h1 { margin:0; font-size:20px; }
.filters { display:flex; gap:10px; flex-wrap:wrap; margin-left:auto; }
.filters input, .filters select {
background:#14151a; color:#e8e8ea; border:1px solid #2a2c33; border-radius:8px; padding:8px 10px; font-size:14px;
}
.filters button {
background:#2b6efe; color:white; border:none; border-radius:8px; padding:8px 12px; cursor:pointer;
}
.filters a { color:#9aa0a6; text-decoration:none; padding-left:6px; }
.wrap { padding:16px 20px; }
table { width:100%; border-collapse:separate; border-spacing:0 10px; }
thead th { font-weight:600; font-size:12px; color:#a9acb3; text-align:left; padding:0 12px 6px; }
tbody tr { background:#14151a; border:1px solid #23242a; }
tbody td { padding:12px; vertical-align:top; }
.badge { display:inline-block; padding:2px 8px; border-radius:999px; font-size:12px; font-weight:600; }
.ad { background:#153e25; color:#67d48a; border:1px solid #1f6b3b; }
.ed { background:#332a16; color:#f0c56a; border:1px solid #6d5a24; }
.del{ background:#3a1e22; color:#f08a94; border:1px solid #6d2b33; }
.meta { color:#a9acb3; font-size:12px; }
.json { background:#0c0d10; border:1px solid #23242a; border-radius:8px; padding:10px; font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:12px; white-space:pre-wrap; max-height:260px; overflow:auto; }
details { margin-top:8px; }
details > summary { cursor:pointer; color:#bfc3cb; }
.pill { display:inline-block; background:#1b1d23; border:1px solid #2a2c33; border-radius:999px; padding:2px 8px; font-size:12px; margin-right:6px; color:#cfd2d8; }
.rowhead { display:flex; align-items:center; gap:10px; }
.pagination { display:flex; gap:8px; align-items:center; margin-top:10px; }
.pagination a, .pagination span {
background:#14151a; border:1px solid #23242a; color:#e8e8ea; padding:6px 10px; border-radius:8px; text-decoration:none; font-size:14px;
}
.pagination .current { background:#1b1d23; }
</style>
</head>
<body>
<header>
<h1>Audit Log</h1>
<form class="filters" method="get">
<input type="number" name="entry_id" placeholder="Entry ID" value="{{ f_entry_id or '' }}">
<select name="action">
<option value="">Any action</option>
{% for a in actions %}
<option value="{{a}}" {% if f_action==a %}selected{% endif %}>{{a}}</option>
{% endfor %}
</select>
<input type="text" name="actor" placeholder="Actor" value="{{ f_actor or '' }}">
<select name="device">
<option value="">Any device</option>
{% for d in devices %}
<option value="{{d}}" {% if f_device==d %}selected{% endif %}>{{d}}</option>
{% endfor %}
</select>
<input type="text" name="q" placeholder="Search old/new/UA" value="{{ f_q or '' }}">
<input type="number" name="per_page" min="10" max="200" value="{{ per_page }}">
<button type="submit">Filter</button>
<a href="{{ url_for('audit_html') }}">Clear</a>
</form>
</header>
<div class="wrap">
<div class="meta">{{ total }} events • page {{ page }} / {{ pages }}</div>
<table>
<thead>
<tr>
<th style="width:180px">Time (UTC)</th>
<th style="width:100px">Action</th>
<th style="width:90px">Entry</th>
<th>Who / Where</th>
<th>Old → New</th>
</tr>
</thead>
<tbody>
{% for r in rows %}
<tr>
<td>{{ r.ts }}</td>
<td>
{% if r.action=='add' %}
<span class="badge ad">add</span>
{% elif r.action=='edit' %}
<span class="badge ed">edit</span>
{% else %}
<span class="badge del">delete</span>
{% endif %}
</td>
<td>
{% if r.entry_id %}
<span class="pill">#{{ r.entry_id }}</span>
<a class="pill" href="{{ url_for('audit_html', entry_id=r.entry_id) }}">history</a>
{% else %}
<span class="pill"></span>
{% endif %}
</td>
<td>
<div class="rowhead">
<span class="pill">{{ r.actor or 'anon' }}</span>
<span class="pill">{{ r.device or 'Unknown' }}</span>
<span class="pill">{{ r.ip or '' }}</span>
</div>
<div class="meta" title="{{ r.user_agent }}">{{ r.user_agent[:80] }}{% if r.user_agent and r.user_agent|length>80 %}…{% endif %}</div>
</td>
<td>
<details>
<summary>Old</summary>
<pre class="json">{{ r.old_pretty }}</pre>
</details>
<details>
<summary>New</summary>
<pre class="json">{{ r.new_pretty }}</pre>
</details>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="pagination">
{% if page > 1 %}
<a href="{{ url_for('audit_html', entry_id=f_entry_id, action=f_action, actor=f_actor, device=f_device, q=f_q, per_page=per_page, page=page-1) }}">← Prev</a>
{% else %}
<span>← Prev</span>
{% endif %}
<span class="current">Page {{ page }}</span>
{% if page < pages %}
<a href="{{ url_for('audit_html', entry_id=f_entry_id, action=f_action, actor=f_actor, device=f_device, q=f_q, per_page=per_page, page=page+1) }}">Next →</a>
{% else %}
<span>Next →</span>
{% endif %}
</div>
</div>
</body>
</html>