163 lines
4.9 KiB
HTML
163 lines
4.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Logs</title>
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
background: #111;
|
|
color: #eee;
|
|
font-family: Arial, sans-serif;
|
|
padding: 20px;
|
|
}
|
|
h1 { margin-top: 0; }
|
|
a.back { color: #6fbf73; text-decoration: none; font-size: 14px; }
|
|
a.back:hover { text-decoration: underline; }
|
|
|
|
.panel {
|
|
background: #1a1a1a;
|
|
border: 1px solid #333;
|
|
border-radius: 8px;
|
|
padding: 16px;
|
|
margin-top: 16px;
|
|
max-width: 900px;
|
|
}
|
|
|
|
.filter-row { display: flex; gap: 8px; margin-bottom: 14px; align-items: center; }
|
|
select, button {
|
|
background: #222;
|
|
border: 1px solid #444;
|
|
color: #eee;
|
|
padding: 6px 10px;
|
|
border-radius: 4px;
|
|
font-size: 13px;
|
|
}
|
|
button { cursor: pointer; }
|
|
button:hover { opacity: 0.85; }
|
|
|
|
table { width: 100%; border-collapse: collapse; }
|
|
th, td {
|
|
text-align: left;
|
|
padding: 6px 8px;
|
|
border-bottom: 1px solid #2a2a2a;
|
|
font-size: 13px;
|
|
vertical-align: top;
|
|
}
|
|
th { color: #888; font-weight: normal; }
|
|
|
|
.cat-badge {
|
|
display: inline-block;
|
|
border-radius: 4px;
|
|
padding: 2px 8px;
|
|
font-size: 11px;
|
|
white-space: nowrap;
|
|
}
|
|
.cat-ban { background: #5a1a1a; color: #ff8080; }
|
|
.cat-mute { background: #5a4a1a; color: #ffd580; }
|
|
.cat-admin_money, .cat-admin_lock, .cat-admin_duty { background: #2c6a7a; color: #cdeffb; }
|
|
.cat-crime { background: #5a2a2a; color: #e08a8a; }
|
|
.cat-arrest { background: #444; color: #ccc; }
|
|
.cat-gang { background: #4a1a5a; color: #d8a8ff; }
|
|
.cat-job_invite { background: #1a4d2a; color: #6fbf73; }
|
|
.cat-server { background: #333; color: #aaa; }
|
|
|
|
.empty-hint { color: #666; padding: 10px 0; }
|
|
.hidden { display: none !important; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<a class="back" href="/index.html">← zurück zur Startseite</a>
|
|
<h1>📋 Logs</h1>
|
|
|
|
<div class="panel">
|
|
<div class="filter-row">
|
|
<select id="categoryFilter">
|
|
<option value="">Alle Kategorien</option>
|
|
<option value="ban">Bans</option>
|
|
<option value="mute">Mutes</option>
|
|
<option value="admin_money">Admin: Bargeld</option>
|
|
<option value="admin_lock">Admin: Sperren</option>
|
|
<option value="admin_duty">Admin: Dienstmodus</option>
|
|
<option value="crime">Verbrechen</option>
|
|
<option value="arrest">Verhaftungen</option>
|
|
<option value="gang">Banden</option>
|
|
<option value="job_invite">Job-Einladungen</option>
|
|
<option value="server">Server</option>
|
|
</select>
|
|
<button onclick="loadLogs()">Aktualisieren</button>
|
|
</div>
|
|
|
|
<table>
|
|
<thead><tr><th>Zeit</th><th>Kategorie</th><th>Ausgeführt von</th><th>Meldung</th></tr></thead>
|
|
<tbody id="logsTableBody"></tbody>
|
|
</table>
|
|
<div class="empty-hint hidden" id="logsEmpty">Keine Log-Einträge vorhanden.</div>
|
|
</div>
|
|
|
|
<script>
|
|
const token = localStorage.getItem("token");
|
|
const isAdmin = localStorage.getItem("isAdmin") === "true";
|
|
|
|
if (!token || !isAdmin) {
|
|
alert("Kein Admin-Zugriff. Bitte auf der Startseite als Admin einloggen.");
|
|
location.href = "/index.html";
|
|
}
|
|
|
|
async function authFetch(url, options = {}) {
|
|
options.headers = { ...(options.headers || {}), "Authorization": "Bearer " + token };
|
|
const res = await fetch(url, options);
|
|
if (res.status === 401 || res.status === 403) {
|
|
alert("Sitzung abgelaufen oder kein Admin-Zugriff. Bitte erneut einloggen.");
|
|
location.href = "/index.html";
|
|
throw new Error("Nicht autorisiert");
|
|
}
|
|
return res;
|
|
}
|
|
|
|
function escapeHtml(str) {
|
|
const div = document.createElement("div");
|
|
div.textContent = str;
|
|
return div.innerHTML;
|
|
}
|
|
|
|
async function loadLogs() {
|
|
const category = document.getElementById("categoryFilter").value;
|
|
const url = "/api/admin/logs" + (category ? "?category=" + encodeURIComponent(category) : "");
|
|
const res = await authFetch(url);
|
|
const data = await res.json();
|
|
renderLogs(data.logs || []);
|
|
}
|
|
|
|
function renderLogs(logs) {
|
|
const body = document.getElementById("logsTableBody");
|
|
const empty = document.getElementById("logsEmpty");
|
|
body.innerHTML = "";
|
|
|
|
if (logs.length === 0) {
|
|
empty.classList.remove("hidden");
|
|
return;
|
|
}
|
|
empty.classList.add("hidden");
|
|
|
|
logs.forEach(l => {
|
|
const tr = document.createElement("tr");
|
|
const date = new Date(l.created_at).toLocaleString("de-DE");
|
|
tr.innerHTML = `
|
|
<td>${date}</td>
|
|
<td><span class="cat-badge cat-${l.category}">${l.category}</span></td>
|
|
<td>${l.actor ? escapeHtml(l.actor) : "-"}</td>
|
|
<td>${escapeHtml(l.message)}</td>
|
|
`;
|
|
body.appendChild(tr);
|
|
});
|
|
}
|
|
|
|
document.getElementById("categoryFilter").addEventListener("change", loadLogs);
|
|
|
|
loadLogs();
|
|
</script>
|
|
|
|
</body>
|
|
</html> |