Upload via GUI (335 Dateien)

This commit is contained in:
2026-10-24 20:14:41 +00:00
parent f189918dc4
commit 793fe6162e
12 changed files with 1920 additions and 1213 deletions
+110
View File
@@ -0,0 +1,110 @@
<?php
require_once __DIR__ . '/../includes/bootstrap.php';
$admin = require_admin();
$pdo = get_db();
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
verify_csrf();
$action = $_POST['action'] ?? '';
if ($action === 'settings') {
set_setting('status_page_enabled', !empty($_POST['enabled']) ? '1' : '0');
$title = trim(mb_substr((string) ($_POST['title'] ?? ''), 0, 80));
set_setting('status_page_title', $title !== '' ? $title : 'Systemstatus');
audit_log($admin['id'], 'Statusseite: Einstellungen geändert');
flash('success', 'Einstellungen gespeichert.');
} elseif ($action === 'component_save') {
$id = (int) ($_POST['id'] ?? 0) ?: null;
$r = status_save_component($pdo, $id, (string) ($_POST['name'] ?? ''), (string) ($_POST['description'] ?? ''), (int) ($_POST['sort_order'] ?? 0));
if ($r === null) $errors[] = 'Bitte einen Namen angeben.'; else flash('success', 'Dienst gespeichert.');
} elseif ($action === 'component_state') {
status_set_component($pdo, (int) ($_POST['id'] ?? 0), (string) ($_POST['status'] ?? ''));
flash('success', 'Zustand geändert.');
} elseif ($action === 'component_delete') {
status_delete_component($pdo, (int) ($_POST['id'] ?? 0));
flash('success', 'Dienst entfernt.');
} elseif ($action === 'incident_create') {
$cid = (int) ($_POST['component_id'] ?? 0) ?: null;
$r = status_create_incident($pdo, (string) ($_POST['title'] ?? ''), (string) ($_POST['body'] ?? ''), (string) ($_POST['status'] ?? 'investigating'), $cid, ($_POST['component_state'] ?? '') !== '' ? (string) $_POST['component_state'] : null, (int) $admin['id']);
if (!$r['ok']) $errors[] = $r['error']; else { audit_log($admin['id'], 'Statusseite: Meldung veröffentlicht'); flash('success', 'Meldung veröffentlicht.'); }
} elseif ($action === 'incident_update') {
$r = status_update_incident($pdo, (int) ($_POST['id'] ?? 0), (string) ($_POST['status'] ?? ''), (string) ($_POST['body'] ?? ''), (int) $admin['id'], true);
if (!$r['ok']) $errors[] = $r['error']; else flash('success', 'Update veröffentlicht.');
} elseif ($action === 'incident_delete') {
status_delete_incident($pdo, (int) ($_POST['id'] ?? 0));
flash('success', 'Meldung gelöscht.');
}
if (!$errors) redirect('/staff/status_page.php');
}
$components = status_components($pdo);
$incidents = status_incidents($pdo, 60);
$states = status_component_states();
$incStates = status_incident_states();
$pageTitle = 'Statusseite';
$activePage = 'status_page';
require __DIR__ . '/_header.php';
?>
<h1>Statusseite</h1>
<?php foreach ($errors as $err): ?><div class="flash error"><?= e($err) ?></div><?php endforeach; ?>
<p class="muted" style="max-width:820px">Eine öffentliche Seite, auf der Ihre Kunden sehen, ob alles läuft, und über Störungen und Wartungen informiert werden.
<?php if (status_page_enabled()): ?>Adresse: <a href="/status.php" target="_blank"><?= e(base_url()) ?>/status.php</a><?php endif; ?></p>
<form method="post" class="card" style="max-width:820px;margin-bottom:16px">
<?= csrf_field() ?><input type="hidden" name="action" value="settings">
<h3>Einstellungen</h3>
<label style="display:flex;align-items:center;gap:8px;font-weight:400"><input type="checkbox" name="enabled" value="1" style="width:auto" <?= status_page_enabled() ? 'checked' : '' ?>> Statusseite für Kunden anzeigen (Link „Status“ im Kundenbereich)</label>
<label for="title" style="margin-top:8px">Überschrift</label>
<input type="text" id="title" name="title" maxlength="80" value="<?= e((string) get_setting('status_page_title', 'Systemstatus')) ?>" style="max-width:340px">
<div class="btn-row"><button type="submit" class="btn">Speichern</button></div>
</form>
<div class="card" style="max-width:820px;margin-bottom:16px">
<h3>Dienste</h3>
<?php if (!$components): ?><p class="muted">Noch keine Dienste. Legen Sie unten zum Beispiel „Webseite“, „E-Mail“ oder „Telefon“ an.</p><?php endif; ?>
<?php foreach ($components as $c): $st = $states[$c['status']] ?? $states['operational']; ?>
<div style="display:flex;gap:10px;flex-wrap:wrap;align-items:center;padding:8px 0;border-top:1px solid var(--border,#e3e9ee)">
<div style="flex:1;min-width:180px"><strong><?= e($c['name']) ?></strong><?php if ($c['description']): ?><div class="muted" style="font-size:.8rem"><?= e($c['description']) ?></div><?php endif; ?></div>
<form method="post" style="display:flex;gap:6px;align-items:center"><?= csrf_field() ?><input type="hidden" name="action" value="component_state"><input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<select name="status" onchange="this.form.submit()" style="color:<?= e($st[1]) ?>;font-weight:600"><?php foreach ($states as $k => $s): ?><option value="<?= e($k) ?>" <?= $c['status'] === $k ? 'selected' : '' ?>><?= e($s[0]) ?></option><?php endforeach; ?></select></form>
<form method="post" onsubmit="return confirm('Dienst entfernen?')"><?= csrf_field() ?><input type="hidden" name="action" value="component_delete"><input type="hidden" name="id" value="<?= (int) $c['id'] ?>"><button class="btn secondary" type="submit" style="padding:2px 10px;font-size:.78rem">Entfernen</button></form>
</div>
<?php endforeach; ?>
<form method="post" style="display:flex;gap:8px;flex-wrap:wrap;margin-top:12px;border-top:1px solid var(--border,#e3e9ee);padding-top:12px"><?= csrf_field() ?><input type="hidden" name="action" value="component_save">
<input type="text" name="name" placeholder="Neuer Dienst, z. B. Webseite" maxlength="120" required style="flex:1;min-width:180px">
<input type="text" name="description" placeholder="Beschreibung (optional)" maxlength="255" style="flex:1;min-width:180px">
<input type="number" name="sort_order" value="<?= count($components) * 10 + 10 ?>" title="Reihenfolge" style="width:80px">
<button class="btn" type="submit">Hinzufügen</button></form>
</div>
<form method="post" class="card" style="max-width:820px;margin-bottom:16px"><?= csrf_field() ?><input type="hidden" name="action" value="incident_create">
<h3>Neue Meldung (Störung oder Wartung)</h3>
<label for="inc_title">Titel</label><input type="text" id="inc_title" name="title" maxlength="200" required placeholder="z. B. E-Mail-Versand verzögert">
<label for="inc_body" style="margin-top:8px">Beschreibung</label><textarea id="inc_body" name="body" rows="3" maxlength="4000"></textarea>
<div style="display:flex;gap:12px;flex-wrap:wrap;margin-top:8px">
<div><label>Stufe</label><select name="status"><?php foreach ($incStates as $k => $l): ?><option value="<?= e($k) ?>"><?= e($l) ?></option><?php endforeach; ?></select></div>
<div><label>Betrifft</label><select name="component_id"><option value="">– kein bestimmter Dienst –</option><?php foreach ($components as $c): ?><option value="<?= (int) $c['id'] ?>"><?= e($c['name']) ?></option><?php endforeach; ?></select></div>
<div><label>Dienst setzen auf</label><select name="component_state"><option value="">– nicht ändern –</option><?php foreach ($states as $k => $s): ?><option value="<?= e($k) ?>"><?= e($s[0]) ?></option><?php endforeach; ?></select></div>
</div>
<div class="btn-row"><button type="submit" class="btn">Veröffentlichen</button></div>
</form>
<div class="card" style="max-width:820px">
<h3>Meldungen</h3>
<?php if (!$incidents): ?><p class="muted">Keine Meldungen in den letzten 60 Tagen.</p><?php endif; ?>
<?php foreach ($incidents as $i): ?>
<div style="padding:10px 0;border-top:1px solid var(--border,#e3e9ee)">
<strong><?= e($i['title']) ?></strong>
<span class="muted" style="font-size:.8rem">· <?= e(format_dt((string) $i['created_at'])) ?><?= $i['component_name'] ? ' · ' . e($i['component_name']) : '' ?> · <?= e($incStates[$i['status']] ?? $i['status']) ?></span>
<?php foreach ($i['updates'] as $u): ?><div style="font-size:.86rem;margin-top:3px"><span class="muted"><?= e($incStates[$u['status']] ?? $u['status']) ?>:</span> <?= nl2br(e((string) $u['body'])) ?></div><?php endforeach; ?>
<?php if ($i['status'] !== 'resolved'): ?>
<form method="post" style="display:flex;gap:6px;flex-wrap:wrap;margin-top:6px"><?= csrf_field() ?><input type="hidden" name="action" value="incident_update"><input type="hidden" name="id" value="<?= (int) $i['id'] ?>">
<select name="status"><?php foreach ($incStates as $k => $l): ?><option value="<?= e($k) ?>" <?= $k === $i['status'] ? 'selected' : '' ?>><?= e($l) ?></option><?php endforeach; ?></select>
<input type="text" name="body" placeholder="Update für die Kunden" maxlength="4000" style="flex:1;min-width:200px">
<button class="btn secondary" type="submit">Update senden</button></form>
<?php endif; ?>
<form method="post" onsubmit="return confirm('Meldung löschen?')" style="margin-top:4px"><?= csrf_field() ?><input type="hidden" name="action" value="incident_delete"><input type="hidden" name="id" value="<?= (int) $i['id'] ?>"><button class="btn secondary" type="submit" style="padding:2px 10px;font-size:.76rem">Löschen</button></form>
</div>
<?php endforeach; ?>
</div>
<?php require __DIR__ . '/_footer.php'; ?>