Files
signage/templates/help.html
2026-09-23 19:55:53 +02:00

356 lines
26 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>CANCOM Simple Signage – Hilfe</title>
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
<script>
(() => {
const stored = window.localStorage.getItem("signage-theme");
const theme = stored === "dark" || stored === "light" ? stored : "light";
document.documentElement.setAttribute("data-bs-theme", theme);
})();
</script>
<link rel="stylesheet"
href="https://unpkg.com/@tabler/core@1.0.0-beta20/dist/css/tabler.min.css">
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@latest/tabler-icons.min.css">
<script defer
src="https://unpkg.com/@tabler/core@1.0.0-beta20/dist/js/tabler.min.js"></script>
{% include "_styles.html" %}
</head>
<body>
<div class="page">
{% set brand_subtitle = "Hilfe" %}
{% set site_dropdown_url_prefix = "/admin/" %}
{% include "_header.html" %}
<div class="navbar-expand-md">
<div class="collapse navbar-collapse show">
<div class="navbar navbar-dark nav-surface">
<div class="container-xl">
<div class="d-flex flex-wrap gap-2 py-2">
<a class="btn btn-white" href="/admin/{{ current_site }}"><i class="ti ti-arrow-left me-1"></i>Zurück</a>
<a class="btn btn-white active" href="/admin/help"><i class="ti ti-help me-1"></i>Hilfe</a>
</div>
</div>
</div>
</div>
</div>
<div class="page-wrapper">
<div class="container-xl mt-4">
<div class="row g-4">
<!-- Sidebar Navigation -->
<div class="col-md-3">
<div class="card" style="position:sticky;top:1rem;">
<div class="card-header"><h4 class="card-title" style="font-size:0.9rem;"><i class="ti ti-menu-2 me-1"></i>Themen</h4></div>
<div class="card-body p-2">
<nav class="nav flex-column">
<a class="nav-link py-1 px-2 small" href="#help-standort"><i class="ti ti-building-community me-1"></i>Standort</a>
<a class="nav-link py-1 px-2 small" href="#help-screen"><i class="ti ti-devices me-1"></i>Screen</a>
<a class="nav-link py-1 px-2 small" href="#help-playlist"><i class="ti ti-list me-1"></i>Playlist</a>
<a class="nav-link py-1 px-2 small" href="#help-zeitsteuerung"><i class="ti ti-clock me-1"></i>Zeitsteuerung</a>
<a class="nav-link py-1 px-2 small" href="#help-priority"><i class="ti ti-player-play me-1"></i>Priority</a>
<a class="nav-link py-1 px-2 small" href="#help-actions"><i class="ti ti-external-link me-1"></i>Action Button</a>
<a class="nav-link py-1 px-2 small" href="#help-voice"><i class="ti ti-robot me-1"></i>Voice Agent</a>
<a class="nav-link py-1 px-2 small" href="#help-einstellungen"><i class="ti ti-settings me-1"></i>Einstellungen</a>
<a class="nav-link py-1 px-2 small" href="#help-info"><i class="ti ti-info-circle me-1"></i>Info-Tab</a>
<a class="nav-link py-1 px-2 small" href="#help-willkommen"><i class="ti ti-users me-1"></i>Willkommen</a>
<a class="nav-link py-1 px-2 small" href="#help-userverwaltung"><i class="ti ti-shield me-1"></i>User</a>
<a class="nav-link py-1 px-2 small" href="#help-dashboard"><i class="ti ti-dashboard me-1"></i>Dashboard</a>
<a class="nav-link py-1 px-2 small" href="#help-darkmode"><i class="ti ti-moon me-1"></i>Dark Mode</a>
<a class="nav-link py-1 px-2 small" href="#help-passwort"><i class="ti ti-key me-1"></i>Passwort</a>
<a class="nav-link py-1 px-2 small" href="#help-mfa"><i class="ti ti-shield-lock me-1"></i>MFA</a>
</nav>
</div>
</div>
</div>
<!-- Main Content -->
<div class="col-md-9">
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-standort"><i class="ti ti-building-community me-1"></i>Standort anlegen</h3></div>
<div class="card-body">
<p>Ein Standort (Site) gruppiert mehrere Screens, z.&thinsp;B. <code>stuttgart</code> oder <code>karlsruhe</code>.</p>
<ol>
<li><strong>+ Button</strong> im Header (neben dem Standort-Dropdown) klicken</li>
<li>Namen des neuen Standorts eingeben (z.&thinsp;B. <code>berlin</code>)</li>
<li>Der Standort wird sofort angelegt und im Dropdown sichtbar</li>
</ol>
<p class="text-muted small mb-0"><i class="ti ti-info-circle me-1"></i>Nur Admins können Standorte anlegen oder löschen (Löschen über den Button im Standort-Dashboard).</p>
</div>
</div>
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-screen"><i class="ti ti-devices me-1"></i>Screen hinzufügen</h3></div>
<div class="card-body">
<p>Ein Screen ist ein einzelner Player (z.&thinsp;B. <code>lobby</code>, <code>casino</code>), der eine Playlist abspielt.</p>
<ol>
<li>Im Admin-Bereich des Standorts (<code>/admin/&lt;standort&gt;</code>) das <strong>+</strong>-Symbol oben rechts klicken</li>
<li>Namen des Screens eingeben (z.&thinsp;B. <code>lobby</code>)</li>
<li>Der Screen erscheint als neue Card mit Tabs: Playlist, Einstellungen, Aktionen, Digital Voice Agent, Medien</li>
</ol>
<p class="text-muted small mb-0"><i class="ti ti-info-circle me-1"></i>Der Screen-Name wird automatisch in Kleinbuchstaben umgewandelt.</p>
</div>
</div>
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-playlist"><i class="ti ti-list me-1"></i>Playlist verwalten</h3></div>
<div class="card-body">
<p>Jeder Screen hat eine eigene Playlist mit Medien und URLs.</p>
<ul>
<li><strong>Medien hochladen:</strong> Im Tab "Medien" eine Datei auswählen und hochladen. Unterstützt werden Bilder (JPG, PNG) und Videos (MP4).</li>
<li><strong>URL hinzufügen:</strong> Im Tab "Playlist" eine URL eingeben und optional den Zoom-Faktor anpassen.</li>
<li><strong>Sortieren:</strong> Per Drag & Drop die Reihenfolge der Playlist-Einträge ändern (Ziehgriff links).</li>
<li><strong>Deaktivieren:</strong> Mit der Checkbox einzelne Einträge temporär ausblenden. Die Checkbox ist ein reiner Schalter und hat mit der Zeitsteuerung nichts zu tun: Bei einem zeitgesteuerten Eintrag bleibt der Haken gesetzt, auch wenn der Eintrag gerade nicht läuft. Ob er läuft, zeigt das Zeit-Badge – <span class="badge bg-info text-white">Zeit</span> blau = läuft gerade, <span class="badge bg-secondary-lt">Zeit</span> grau = ausserhalb des Zeitfensters. Abgespielt wird nur, was <em>beides</em> erfüllt: Haken gesetzt und im Zeitfenster.</li>
<li><strong>Löschen:</strong> Über den roten Papierkorb-Button. Die Datei wird dabei entfernt <em>und</em> der Eintrag aus der Playlist genommen.</li>
<li><strong>Bearbeiten:</strong> Der <em>Edit</em>-Button öffnet einen Dialog. Bei URLs lassen sich dort Adresse, Zoom, Query-Parameter-Passthrough und Zeitsteuerung ändern; bei Bildern, Videos und HTML-Seiten die Zeitsteuerung.</li>
<li><strong>Zeitsteuerung:</strong> Einträge können nur zu bestimmten Zeiten laufen – siehe <a href="#help-zeitsteuerung">Zeitsteuerung</a>. Ein Badge <span class="badge bg-info text-white">Zeit</span> in der Playlist-Zeile zeigt an, dass ein Eintrag zeitgesteuert ist; der Tooltip nennt die Einstellung im Klartext.</li>
<li><strong>Query-Parameter-Passthrough:</strong> Per URL-Edit-Button (Stift-Icon) im Playlist-Eintrag kann pro URL gesteuert werden, ob Query-Parameter von der Player-URL an die Playlist-URL übergeben werden. Standardmäßig <strong>aus</strong> – Checkbox "Query-Parameter an diese URL übergeben" aktivieren wenn gewünscht. Ein Link-Icon in der Playlist-Zeile zeigt den Status: <i class="ti ti-link"></i> = an, <i class="ti ti-link-off"></i> = aus.</li>
</ul>
<p class="text-muted small mb-0"><i class="ti ti-info-circle me-1"></i>Änderungen an der Playlist werden automatisch gespeichert. Der Player lädt die Seite automatisch neu (via Hash-Prüfung).</p>
</div>
</div>
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-zeitsteuerung"><i class="ti ti-clock me-1"></i>Zeitsteuerung</h3></div>
<div class="card-body">
<p>Jeder Playlist-Eintrag – URL, Bild, Video oder HTML-Seite – kann nur zu bestimmten Zeiten laufen. Das gilt für die Playlist eines Screens genauso wie für die Priority-Playlist.</p>
<p><strong>Einstellen:</strong> beim Anlegen im Tab "Medien" unter <em>Zeitsteuerung</em>, oder nachträglich über den <em>Edit</em>-Button des Eintrags. Häkchen bei "Zeitgesteuerte Wiedergabe" setzen und einen Modus wählen:</p>
<table class="table table-sm">
<thead>
<tr><th style="width:110px">Modus</th><th>Bedeutung</th><th>Felder</th></tr>
</thead>
<tbody>
<tr>
<td><strong>Einmalig</strong></td>
<td>Läuft einmal in einem zusammenhängenden Zeitraum – auch über mehrere Tage am Stück.</td>
<td>Start und Ende jeweils mit Datum <em>und</em> Uhrzeit</td>
</tr>
<tr>
<td><strong>Täglich</strong></td>
<td>Läuft jeden Tag im selben Zeitfenster.</td>
<td>Von / Bis als Uhrzeit, optional "Gültig von / bis"</td>
</tr>
<tr>
<td><strong>Wöchentlich</strong></td>
<td>Wie täglich, aber nur an den angehakten Wochentagen.</td>
<td>Von / Bis als Uhrzeit, Wochentage, optional "Gültig von / bis"</td>
</tr>
</tbody>
</table>
<p><strong>Gültig von / bis</strong> ist optional und begrenzt, an welchen <em>Tagen</em> das Zeitfenster überhaupt greift. Beide Grenzen lassen sich einzeln setzen und zählen den genannten Tag mit. Ohne Angabe läuft die Wiedergabe unbefristet.</p>
<p class="mb-1"><strong>Beispiele:</strong></p>
<ul>
<li>Täglich, 08:00 bis 12:00, ohne Gültigkeitszeitraum → jeden Vormittag, unbefristet.</li>
<li>Täglich, 08:00 bis 12:00, gültig vom 10.09. bis 20.09. → nur an diesen elf Tagen.</li>
<li>Wöchentlich, 09:00 bis 17:00, Mo/Mi/Fr → nur an diesen drei Tagen während der Bürozeit.</li>
<li>Täglich, 22:00 bis 02:00 → abends bis in die Nacht hinein, über Mitternacht hinweg.</li>
</ul>
<p class="mb-1"><strong>Gut zu wissen:</strong></p>
<ul>
<li>Bei "Täglich" und "Wöchentlich" zählt nur die <em>Uhrzeit</em> – ein Datum wird ausschliesslich unter "Gültig von / bis" angegeben.</li>
<li>Bei "Täglich" gilt automatisch jeder Wochentag; die Auswahl der Wochentage erscheint deshalb nur bei "Wöchentlich".</li>
<li>Ein Fenster über Mitternacht gehört zum Tag seines <em>Starts</em>: "Mi 22:00–02:00" läuft Mittwochabend bis Donnerstagfrüh.</li>
<li>Die Checkbox links im Playlist-Eintrag wirkt weiterhin unabhängig davon – ein deaktivierter Eintrag läuft auch innerhalb seines Zeitfensters nicht.</li>
<li>Der Player merkt von selbst, wenn ein Zeitfenster beginnt oder endet, und lädt neu. Ein manueller Eingriff am Screen ist nicht nötig.</li>
</ul>
<p class="text-muted small mb-0"><i class="ti ti-info-circle me-1"></i>Es gilt die Uhrzeit des Servers, nicht die des Players.</p>
</div>
</div>
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-priority"><i class="ti ti-player-play me-1"></i>Priority-Playlist</h3></div>
<div class="card-body">
<p>Die Priority-Playlist gilt <strong>pro Standort</strong>. Ihre Inhalte werden auf <em>allen</em> Screens dieses Standorts eingeblendet – zwischen den normalen Playlist-Einträgen.</p>
<ul>
<li>Aufruf über <code>/admin/&lt;standort&gt;/priority</code></li>
<li>Medien und URLs dieses Standorts verwalten, ebenfalls per Drag & Drop</li>
<li>Priority muss für den Standort aktiviert sein (<code>config.json → sites.&lt;standort&gt;.priority.enabled</code>)</li>
<li>Die <a href="#help-zeitsteuerung">Zeitsteuerung</a> steht hier genauso zur Verfügung wie in den Screen-Playlists</li>
<li>Jeder Standort hat seine <strong>eigene</strong> Priority-Playlist – Inhalte eines Standorts erscheinen nie auf den Screens eines anderen.</li>
<li><strong>Vorschau in den Screen-Playlisten:</strong> Die Priority-Einträge werden zusätzlich oberhalb jeder normalen Playlist angezeigt – ausgegraut und mit rotem <span class="badge bg-red text-red-fg">Prio</span>-Badge. Das ist eine <em>reine Anzeige</em>: Sie lässt sich dort nicht sortieren, bearbeiten oder löschen. So ist beim Bearbeiten einer Screen-Playlist sofort sichtbar, was dem Screen ohnehin noch vorweg läuft, ohne dass man in den anderen Menüpunkt wechseln muss. Geändert wird weiterhin ausschliesslich auf der Priority-Seite.</li>
</ul>
</div>
</div>
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-actions"><i class="ti ti-external-link me-1"></i>Action Button (Custom-URL)</h3></div>
<div class="card-body">
<p>Der Action Button ist ein konfigurierbarer Button im Player, der eine frei wählbare URL öffnet.</p>
<ul>
<li><strong>Konfiguration:</strong> Im Tab <strong>Aktionen</strong> der Screen-Card</li>
<li><strong>URL:</strong> Beliebige Webadresse (z.&thinsp;B. Intranet-Seite, Dashboard)</li>
<li><strong>Label:</strong> Text, der auf dem Button angezeigt wird (z.&thinsp;B. "Infos")</li>
<li><strong>Position:</strong> 9 mögliche Positionen (oben/mitte/unten × links/mitte/rechts)</li>
<li><strong>Ziel:</strong>
<ul>
<li><code>overlay</code> – URL wird in einem iframe-Overlay geöffnet, Zurück-Button schließt es</li>
<li><code>redirect</code> – direkte Weiterleitung zur URL</li>
</ul>
</li>
</ul>
<p class="text-muted small mb-0"><i class="ti ti-info-circle me-1"></i>Der Button erscheint nur, wenn "Aktiviert" eingeschaltet ist. Bei Positionen unten weicht er automatisch 16px über dem Newsticker aus.</p>
</div>
</div>
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-voice"><i class="ti ti-robot me-1"></i>Digital Voice Agent</h3></div>
<div class="card-body">
<p>Der Digital Voice Agent zeigt einen Button im Player, der eine Typewriter-Animation mit wechselnden mehrsprachigen Texten anzeigt.</p>
<ul>
<li><strong>Globale URL:</strong> Die Ziel-URL wird in <code>config.json</code> (Feld <code>voice_agent_url</code>) gesetzt und ist im Admin sichtbar, aber nicht änderbar</li>
<li><strong>Konfiguration pro Screen:</strong> Im Tab <strong>Digital Voice Agent</strong> der Screen-Card</li>
<li><strong>Label:</strong> Button-Beschriftung (Default: "Digitaler Assistent")</li>
<li><strong>Position:</strong> Wie Action Button – 9 Positionen wählbar</li>
<li><strong>Bild:</strong> Optional kann über dem Button ein Bild (dva.png) angezeigt werden (Beta-Feature)</li>
<li><strong>Typewriter-Tagline:</strong> 11 Phrasen in 5 Sprachen wechseln alle 2,5 Sekunden mit Buchstaben-für-Buchstaben-Effekt</li>
<li><strong>Animierte Balken:</strong> 5 rote Audiobalken neben dem Button signalisieren Aktivität</li>
</ul>
</div>
</div>
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-einstellungen"><i class="ti ti-settings me-1"></i>Screen-Einstellungen</h3></div>
<div class="card-body">
<p>Im Tab <strong>Einstellungen</strong> können pro Screen konfiguriert werden:</p>
<ul>
<li><strong>Intervall:</strong> Anzeigedauer pro Playlist-Eintrag in Sekunden</li>
<li><strong>Bilder / Videos anzeigen:</strong> Jeweils ein-/ausschaltbar</li>
<li><strong>Newsticker:</strong> Text (max. 200 Zeichen) und Aktivierung des Laufbands</li>
<li><strong>Stay on First:</strong> Wenn aktiviert, bleibt der Player auf dem ersten Playlist-Element stehen (kein Durchlauf)</li>
</ul>
</div>
</div>
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-info"><i class="ti ti-info-circle me-1"></i>Info-Tab im Screen</h3></div>
<div class="card-body">
<p>Jeder Screen hat einen <strong>Info-Tab</strong> (Tab 6), der detaillierte Client-Informationen zum aktuell verbundenen Player anzeigt:</p>
<ul>
<li><strong>IP-Adresse</strong> des Players</li>
<li><strong>Browser</strong> (User-Agent) des Players</li>
<li><strong>Bildschirmauflösung</strong> (Breite × Höhe)</li>
<li><strong>Zuletzt gesehen</strong> – Zeitstempel des letzten Heartbeats</li>
</ul>
<p class="text-muted small mb-0"><i class="ti ti-info-circle me-1"></i>Die Daten werden alle 5 Sekunden vom Player gesendet und im Heartbeat-JSON gespeichert. Der Online-Status (grüner/roter Button im Screen-Header) basiert auf dem gleichen Mechanismus.</p>
</div>
</div>
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-willkommen"><i class="ti ti-users me-1"></i>Willkommensseite</h3></div>
<div class="card-body">
<p>Auf der Willkommensseite können bis zu 3 Kundennamen eingegeben werden. Die Logos werden automatisch via OpenAI + Brandfetch gesucht.</p>
<p class="text-muted small"><i class="ti ti-lock-open me-1"></i><strong>Ohne Anmeldung nutzbar:</strong> Das Formular kann auch ohne Benutzerkonto aufgerufen werden – etwa am Empfang. Wer angemeldet ist, sieht weiterhin nur die eigenen Standorte; ohne Anmeldung stehen alle zur Auswahl. Im Aktivitätsverlauf erscheinen solche Einträge als „nicht angemeldet".</p>
<ul>
<li>Aufruf über <code>/willkommen?site=&lt;standort&gt;</code> (oder Menüpunkt)</li>
<li><strong>Zielscreens:</strong> Die generierte <code>welcome.html</code> wird automatisch an den Anfang der Playlist <em>jedes</em> Screens gesetzt, bei dem im Tab "Einstellungen" die Option <em>Willkommensseite hier anzeigen</em> aktiv ist. So lässt sich dieselbe Begrüßung auf mehreren Screens zeigen, ohne sie mehrfach anzulegen. Ist an einem Standort nichts eingestellt, geht sie wie bisher in die Lobby.</li>
<li><strong>Der Schalter wirkt sofort:</strong> Schaltest du ihn bei einem weiteren Screen ein, erscheint eine bereits erzeugte Willkommensseite dort umgehend in der Playlist – ohne dass du sie neu generieren musst. Schaltest du ihn aus, verschwindet sie dort wieder.</li>
<li><strong>Anzeigen bis:</strong> Optionales Datum im Formular. Ist es gesetzt, verschwindet die Willkommensseite nach diesem Tag auf allen Screens von selbst – kein manuelles Aufräumen nach dem Besuch. Ohne Angabe bleibt sie stehen.</li>
<li><strong>Logo hochladen:</strong> Findet die automatische Suche kein Logo oder passt es nicht, kann pro Kunde eine eigene Bilddatei hochgeladen werden. Ein Upload hat immer Vorrang vor der automatischen Suche.</li>
<li><strong>Freistellen:</strong> Der Hintergrund eines hochgeladenen Logos wird automatisch entfernt, damit es auf der Willkommensseite nicht in einem weissen Kasten steht. Das gelingt am besten bei einem Logo auf einfarbigem Grund – ein PNG mit bereits transparentem Hintergrund wird unverändert übernommen. Bei unruhigem Bildrand – oder wenn das Logo farblich zu nah am Hintergrund liegt und beim Freistellen verschwinden würde – bleibt das Bild unangetastet und es erscheint ein Hinweis. Mit „Hintergrund behalten" lässt sich das Freistellen abschalten.</li>
<li><strong>Grösse:</strong> Nach dem Freistellen werden leere Ränder weggeschnitten, damit das hochgeladene Logo auf der Willkommensseite genauso gross erscheint wie ein automatisch gefundenes.</li>
<li>Ein einmal hochgeladenes Logo bleibt beim erneuten Generieren erhalten, solange der Kundenname im selben Feld steht.</li>
<li>Pro Standort kann ein eigenes Hintergrundbild hochgeladen werden (Tab "Medien" im Standort-Dashboard)</li>
<li>Pro Kunde können <strong>Ansprechpartner</strong> eingegeben werden (Markdown-Format):
<ul>
<li><strong>Fett</strong>: <code>**Text**</code></li>
<li><em>Kursiv</em>: <code>*Text*</code></li>
<li><code>Code</code>: <code>`Code`</code></li>
<li>Aufzählungen: <code>- Punkt</code> oder <code>* Punkt</code></li>
<li>Zeilenumbrüche werden automatisch übernommen</li>
</ul>
</li>
<li><strong>Layout:</strong>
<ul>
<li>Landscape: Logos nebeneinander, Texte linksbündig darunter</li>
<li>Portrait: Texte <em>links</em> vom Logo, Abstand 40px</li>
</ul>
</li>
<li>Reset-Button setzt das Formular und die gespeicherten Daten zurück</li>
</ul>
</div>
</div>
{% if current_user.is_admin %}
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-userverwaltung"><i class="ti ti-shield me-1"></i>User-Verwaltung (Admin)</h3></div>
<div class="card-body">
<p>Admins können über <code>/admin/users</code> die User-Verwaltung aufrufen.</p>
<ul>
<li><strong>User anlegen:</strong> E-Mail, Passwort, Rolle (Admin/Superuser/User) und Standort-Zugriff festlegen</li>
<li><strong>User bearbeiten:</strong> E-Mail, Rolle, Standorte, Profilfelder (Vorname, Nachname, Abteilung) ändern</li>
<li><strong>User löschen:</strong> Der letzte Admin kann nicht gelöscht werden</li>
<li><strong>Passwort-Reset:</strong> Setzt ein temporäres Passwort, der User muss es beim nächsten Login ändern</li>
<li><strong>Rollen:</strong>
<ul>
<li><strong>Admin</strong> – Zugriff auf alle Standorte + Userverwaltung</li>
<li><strong>Superuser</strong> – Zugriff auf alle Standorte, keine Userverwaltung</li>
<li><strong>User</strong> – Zugriff nur auf zugewiesene Standorte</li>
</ul>
</li>
</ul>
</div>
</div>
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-dashboard"><i class="ti ti-dashboard me-1"></i>Admin Dashboard</h3></div>
<div class="card-body">
<p>Das Admin Dashboard (<code>/admin/dashboard</code>) bietet eine Übersicht über das gesamte System:</p>
<ul>
<li><strong>Statistik-Cards:</strong> Anzahl Standorte, Screens, User, Admins und Superuser</li>
<li><strong>Sparkline:</strong> Kleine Liniendiagramme zeigen den Verlauf der letzten Änderungen</li>
<li><strong>Trend:</strong> Pfeil nach oben/unten mit Netto-Änderung aus den letzten 30 Aktionen</li>
<li><strong>Aktivitätsverlauf:</strong> Alle Erstell-, Lösch-, Änderungsaktionen sowie An-/Abmeldungen werden protokolliert</li>
<li><strong>Blättern:</strong> Der Verlauf zeigt 50 Einträge je Seite; über die Leiste unter der Liste lässt sich weiter zurückblättern. Aufbewahrt werden die letzten 1000 Einträge. Statistik-Cards, Sparklines und Trendpfeile beziehen sich dabei immer auf die jüngsten 30 Aktionen und ändern sich beim Blättern nicht.</li>
</ul>
</div>
</div>
{% endif %}
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-darkmode"><i class="ti ti-moon me-1"></i>Dark Mode</h3></div>
<div class="card-body">
<p>Der Dark Mode kann über den Mond-Button im Header umgeschaltet werden. Die Einstellung wird im Browser gespeichert (localStorage) und bleibt auch nach Seitenwechsel erhalten.</p>
</div>
</div>
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-passwort"><i class="ti ti-key me-1"></i>Passwort ändern</h3></div>
<div class="card-body">
<p>Das Passwort kann über das User-Menü (oben rechts) → <strong>Passwort ändern</strong> geändert werden. Nach einem Admin-Reset muss der User beim ersten Login ein neues Passwort vergeben.</p>
</div>
</div>
<div class="card mb-3">
<div class="card-header"><h3 class="card-title" id="help-mfa"><i class="ti ti-shield-lock me-1"></i>MFA (Multi-Faktor-Authentifizierung)</h3></div>
<div class="card-body">
<p>MFA bietet eine optionale zweite Sicherheitsstufe per TOTP (Google Authenticator, Authy).</p>
<ul>
<li><strong>Aktivierung:</strong> Über das User-Menü → <strong>MFA einrichten</strong> → QR-Code mit einer Authenticator-App scannen → 6-stelligen Code eingeben → Bestätigen</li>
<li><strong>Recovery-Codes:</strong> Nach erfolgreicher Aktivierung werden 8 Recovery-Codes (einmalig) angezeigt. Jeder Code kann nur einmal verwendet werden. Nach Einsatz eines Recovery-Codes muss MFA neu eingerichtet werden.</li>
<li><strong>Login mit MFA:</strong> Nach Eingabe von E-Mail + Passwort erscheint ein zweites Formular für den TOTP-Code. Erst nach erfolgreichem Code wird der Zugriff gewährt.</li>
<li><strong>Deaktivierung:</strong> Über <code>/mfa/setup</code> → Button "MFA deaktivieren" → aktuelles Passwort eingeben</li>
<li><strong>MFA-Status:</strong> In der Userliste (<code>/admin/users</code>) wird der MFA-Status als grünes "Aktiv"-Badge oder "–" angezeigt.</li>
</ul>
</div>
</div>
</div> <!-- /col-md-9 main -->
</div> <!-- /row -->
</div> <!-- /container-xl -->
</div> <!-- /page-wrapper -->
{% include "_footer.html" %}
</div> <!-- /page -->
</body>
</html>