Files
playwish/server/app/static/admin.html
T
99admandClaude Opus 5.5 3610de7bae Audiofy – Musikwünsche für Partys
Server (Website, Admin-Bereich, Player-API) und Player (raspotify +
Controller) mit Install-Skripten für Debian-Systeme.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 19:16:39 +01:00

177 lines
8.6 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">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="theme-color" content="#121212">
<meta name="robots" content="noindex">
<title>Audiofy – Admin</title>
<link rel="stylesheet" href="/static/app.css">
<link rel="stylesheet" href="/static/admin.css">
<script src="/static/admin.js" defer></script>
</head>
<body>
<main>
<div class="kopf">
<h1>Audiofy Admin</h1>
<button id="abmelden" class="klein" type="button">Abmelden</button>
</div>
<div class="pillen" id="pillen"></div>
<nav class="reiter" role="tablist">
<button type="button" role="tab" data-reiter="wiedergabe" aria-selected="true">Wiedergabe</button>
<button type="button" role="tab" data-reiter="wuensche">Wünsche<span id="zahl-freigabe" class="zahl" hidden></span></button>
<button type="button" role="tab" data-reiter="gaeste">Gäste</button>
<button type="button" role="tab" data-reiter="einstellungen">Einstellungen</button>
<button type="button" role="tab" data-reiter="verlauf">Verlauf</button>
</nav>
<div id="notaus-hinweis" class="notaus-aktiv" hidden>Not-Aus aktiv – der Controller ist angehalten.</div>
<!-- ===== Wiedergabe ===== -->
<section data-seite="wiedergabe">
<div class="karte">
<h2>Läuft gerade</h2>
<div id="jetzt-inhalt" class="titel-zeile"></div>
<div class="fortschritt"><div id="fortschritt-balken"></div></div>
<p id="naechster" class="hinweis klein"></p>
<p id="pi-fehler" class="hinweis klein fehlertext" hidden></p>
<div class="knopfreihe">
<button class="gross mit-symbol" type="button" data-befehl="play"><span class="symbol" aria-hidden="true">▶</span><span>Play</span></button>
<button class="gross mit-symbol" type="button" data-befehl="pause"><span class="symbol" aria-hidden="true">⏸</span><span>Pause</span></button>
<button class="gross mit-symbol" type="button" data-befehl="skip"><span class="symbol" aria-hidden="true">⏭</span><span>Weiter</span></button>
</div>
<div class="lautstaerke">
<span aria-hidden="true">🔊</span>
<input id="lautstaerke" type="range" min="0" max="100" step="5" aria-label="Lautstärke">
<output id="lautstaerke-wert">–</output>
</div>
</div>
<div class="karte">
<h2>Als Nächstes spielen</h2>
<input id="naechstes-suche" type="search" placeholder="Titel suchen …" autocomplete="off" maxlength="100">
<ul id="naechstes-treffer" class="liste"></ul>
</div>
<div class="karte">
<h2>Not-Aus</h2>
<p class="hinweis klein">Stoppt die Wiedergabe und hält den Controller an, bis du wieder freigibst.</p>
<button id="notaus" class="gross mit-symbol gefahr voll" type="button"><span class="symbol" aria-hidden="true">⛔</span><span>Not-Aus</span></button>
</div>
<div class="karte">
<h2>Letzte Befehle</h2>
<ul id="befehle" class="liste kompakt"></ul>
</div>
</section>
<!-- ===== Wünsche ===== -->
<section data-seite="wuensche" hidden>
<div class="karte">
<div class="schalter-zeile">
<div class="text"><span class="t">Wünsche annehmen</span><span class="m">Aus = Gäste sehen „pausiert“</span></div>
<label class="schalter"><input type="checkbox" id="s-annahme"><span></span></label>
</div>
<div class="schalter-zeile">
<div class="text"><span class="t">Moderation</span><span class="m">Wünsche erst nach deiner Freigabe spielen</span></div>
<label class="schalter"><input type="checkbox" id="s-moderation"><span></span></label>
</div>
</div>
<div class="karte" id="freigabe-karte">
<h2>Zur Freigabe</h2>
<ul id="freigabe" class="liste"></ul>
<p id="freigabe-leer" class="hinweis">Nichts zu prüfen.</p>
<p class="legende"><span>✓ freigeben</span><span>✕ ablehnen</span><span>🚫 Gast sperren</span></p>
</div>
<div class="karte">
<h2>Warteschlange</h2>
<ul id="warteschlange" class="liste"></ul>
<p id="warteschlange-leer" class="hinweis">Keine Wünsche in der Warteschlange.</p>
<p class="legende"><span>↑ früher</span><span>↓ später</span><span>✕ löschen</span><span>🚫 Gast sperren</span></p>
</div>
</section>
<!-- ===== Gäste ===== -->
<section data-seite="gaeste" hidden>
<div class="karte">
<h2>Gastzugang</h2>
<div class="schalter-zeile">
<div class="text"><span class="t">Zugang offen</span><span class="m">Aus = niemand kommt auf die Wunschseite</span></div>
<label class="schalter"><input type="checkbox" id="s-zugang"><span></span></label>
</div>
<img id="qr" class="qr" alt="QR-Code zum Einladungslink">
<input id="einladungslink" class="link-feld" type="text" readonly aria-label="Einladungslink">
<div class="knopfreihe zwei">
<button id="link-kopieren" class="gross" type="button">Link kopieren</button>
<a id="qr-png" class="gross" href="/admin/api/access/qr?format=png" download>QR als Bild</a>
</div>
<button id="link-erneuern" class="gross voll" type="button">Neuen Link erzeugen</button>
<p class="hinweis klein">Ein neuer Link macht den alten und alle damit erteilten Zugänge ungültig.</p>
</div>
<div class="karte">
<h2>Limit pro Gast</h2>
<div class="feld-zeile"><span>Wünsche</span><input id="e-limit-anzahl" type="number" min="1" max="50"></div>
<div class="feld-zeile"><span>pro Minuten</span><input id="e-limit-minuten" type="number" min="1" max="1440"></div>
<button class="gross akzent voll" type="button" data-speichern="e-limit-anzahl:wish_limit_count,e-limit-minuten:wish_limit_minutes">Speichern</button>
</div>
<div class="karte">
<h2>Sperrliste</h2>
<div class="schalter-zeile">
<div class="text"><span class="t">Explizite Titel sperren</span></div>
<label class="schalter"><input type="checkbox" id="s-explizit"><span></span></label>
</div>
<input id="sperr-suche" type="search" placeholder="Titel oder Interpret zum Sperren suchen …" autocomplete="off" maxlength="100">
<ul id="sperr-treffer" class="liste"></ul>
<h2 class="abstand">Gesperrt</h2>
<ul id="sperrliste" class="liste"></ul>
<p id="sperrliste-leer" class="hinweis">Nichts gesperrt.</p>
</div>
</section>
<!-- ===== Einstellungen ===== -->
<section data-seite="einstellungen" hidden>
<div class="karte">
<h2>Ablauf</h2>
<div class="feld-zeile"><span>Jeder wievielte Titel ist ein Wunsch (N)</span><input id="e-n" type="number" min="1" max="20"></div>
<div class="feld-zeile"><span>Sperrzeit für Wiederholungen (Min.)</span><input id="e-sperrzeit" type="number" min="0" max="1440"></div>
<button class="gross akzent voll" type="button" data-speichern="e-n:wish_every_n,e-sperrzeit:repeat_block_minutes">Speichern</button>
</div>
<div class="karte">
<h2>Lautsprecher</h2>
<div id="bt-aktuell" class="titel-zeile"></div>
<p class="hinweis klein">Neuen Bluetooth-Lautsprecher vorher in den Kopplungsmodus versetzen (meist Bluetooth-Taste gedrückt halten, bis die LED schnell blinkt). Während der Suche kann die Musik kurz stocken – WLAN und Bluetooth teilen sich oft einen Funkchip.</p>
<button id="bt-suchen" class="gross voll" type="button">Nach Lautsprechern suchen</button>
<p id="bt-status" class="hinweis klein"></p>
<ul id="bt-geraete" class="liste"></ul>
</div>
<div class="karte">
<h2>Grund-Playlist</h2>
<p class="hinweis klein">Aktuell: <a id="playlist-link" target="_blank" rel="noopener noreferrer"></a></p>
<input id="playlist-neu" type="text" placeholder="Spotify-Playlist-Link einfügen" autocomplete="off" maxlength="300">
<div class="knopfreihe zwei">
<button id="playlist-wechseln" class="gross akzent" type="button">Wechseln</button>
<button id="neu-mischen" class="gross" type="button">Neu mischen</button>
</div>
</div>
</section>
<!-- ===== Verlauf ===== -->
<section data-seite="verlauf" hidden>
<div class="karte">
<h2>Verlauf</h2>
<ul id="verlauf" class="liste"></ul>
<p id="verlauf-leer" class="hinweis">Noch nichts gespielt.</p>
</div>
</section>
</main>
<div id="toast" class="toast" role="status" aria-live="assertive" hidden></div>
</body>
</html>