Files
signage/templates/customer.html
Erik Thiele 848bcf93ab feat: Willkommensseite auf mehreren Screens anzeigen
Die Willkommensseite ging bisher fest in die Lobby-Playlist. Welche
Screens Begruessungsschirme sind, ist aber eine Eigenschaft der
Installation und nicht des einzelnen Kundenbesuchs - deshalb ein Flag
pro Screen statt einer Auswahl bei jedem Vorgang.

- Neue Screen-Einstellung "welcome_enabled" (Checkbox im Tab
  Einstellungen). Die generierte welcome.html wird in jeden markierten
  Screen des Standorts geschrieben und dort an Position 0 gesetzt.
- welcome_target_screens() faellt nur auf "lobby" zurueck, wenn kein
  Screen des Standorts den Schluessel besitzt. Bestehende Standorte
  verhalten sich damit ohne Konfigurationsaufwand unveraendert.
- add_customer_to_playlists() (frueher add_customer_to_lobby_playlist)
  raeumt welcome.html aus allen Screens des Standorts und fuegt sie nur
  in den Zielscreens wieder ein. Ein abgewaehlter Screen bleibt so nicht
  mit einer alten Begruessung stehen.
- Eingefuegt wird ein Dict statt eines Strings, damit der Eintrag
  enabled und schedule tragen kann.
- Optionales "Anzeigen bis" im Formular: setzt eine Zeitsteuerung, die
  Seite verschwindet danach auf allen Screens von selbst.
- Das Formular zeigt die aktuellen Zielscreens an und meldet
  verstaendlich, wenn keiner markiert ist.
- screens.setdefault("lobby", {}) entfernt - das legte an Standorten
  ohne Lobby stillschweigend einen Screen an. Es werden nur noch
  vorhandene Screens bespielt.

Die Seite referenziert alle Bilder absolut (/static/..., /media/...),
ist also ortsunabhaengig; je Screen liegt eine identische Kopie.

README, AGENTS.md und die Hilfeseite nachgezogen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 12:26:22 +02:00

237 lines
11 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">
<title>Willkommensseite</title>
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
<!-- ─── Dark Mode: Theme vor dem Rendern setzen ─── -->
<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" %}
<style>
.form-label { font-weight: 600; }
.card { box-shadow: 0 20px 60px rgba(0,0,0,0.08); }
/* ─── Logo-Vorschau-Box (gestrichelte Border) ─── */
.logo-preview-box {
border: 2px dashed var(--ccm-border);
border-radius: 0.75rem;
min-height: 120px;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
background: #ffffff;
}
[data-bs-theme="dark"] .logo-preview-box {
background: #1a1e24;
}
.logo-preview-box img {
max-height: 100px;
max-width: 100%;
object-fit: contain;
background: #ffffff;
padding: 8px;
border-radius: 0.5rem;
}
.logo-preview-box .placeholder {
color: var(--ccm-muted);
font-size: 0.85rem;
text-align: center;
}
</style>
</head>
<body>
<div class="page">
{% set brand_subtitle = "Willkommensseite" %}
{% set site_dropdown_url_prefix = "/willkommen?site=" %}
{% include "_header.html" %}
<!-- ═══════════════════════════════════════════════════
Navigation (zweite Zeile)
═══════════════════════════════════════════════════ -->
<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-layout-dashboard me-1"></i>Übersicht</a>
<a class="btn btn-white" href="/admin/{{ current_site }}/priority"><i class="ti ti-alert-triangle me-1"></i>Priority Playlist</a>
<a class="btn btn-white active" href="/willkommen?site={{ current_site }}"><i class="ti ti-file-plus me-1"></i>Willkommensseite</a>
</div>
</div>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════
CONTENT – Willkommensseite-Formular
Bis zu 3 Kundennamen eingeben → Logos via OpenAI + Brandfetch
→ welcome.html wird generiert und in Lobby-Playlist platziert
═══════════════════════════════════════════════════ -->
<div class="page-wrapper">
<div class="container-xl mt-4">
<div class="card mb-4">
<div class="card-header">
<div class="row align-items-center">
<div class="col">
<div class="page-pretitle">Willkommensseite</div>
<h2 class="page-title">Kundeninformationen eingeben (max. 3)</h2>
</div>
</div>
</div>
<div class="card-body">
{% if error %}
<div class="alert alert-danger">{{ error }}</div>
{% endif %}
{% if success %}
<div class="alert alert-success">{{ success }}</div>
{% endif %}
<!-- ─── Logo-Vorschau (wird nach POST angezeigt) ─── -->
<div class="row g-3 mb-4">
{% for i in range(3) %}
<div class="col-md-4">
<label class="form-label">Logo {{ i + 1 }}</label>
<div class="logo-preview-box">
{% if logo_urls and logo_urls[i] %}
<img src="{{ logo_urls[i] }}" alt="Logo {{ i + 1 }}">
{% else %}
<div class="placeholder">kein Logo</div>
{% endif %}
</div>
</div>
{% endfor %}
</div>
<!-- ─── Eingabeformular (bis zu 3 Kunden) ─── -->
<form method="POST">
<input type="hidden" name="site" value="{{ site }}">
<div class="row g-3 mb-3">
<div class="col-md-4">
<label class="form-label" for="customer_name_1">Kunde 1</label>
<input type="text" class="form-control" id="customer_name_1"
name="customer_name_1" placeholder="z. B. Beispiel GmbH"
value="{{ customer_names[0] if customer_names else '' }}">
<label class="form-label mt-2" for="contact_1">Ansprechpartner (optional)</label>
<textarea class="form-control" id="contact_1" name="contact_1" rows="4"
placeholder="**Max Mustermann**&#10;+49 123 4567890&#10;*E-Mail*: max@beispiel.de">{{ contacts[0] if contacts else '' }}</textarea>
</div>
<div class="col-md-4">
<label class="form-label" for="customer_name_2">Kunde 2 (optional)</label>
<input type="text" class="form-control" id="customer_name_2"
name="customer_name_2" placeholder="z. B. Muster AG"
value="{{ customer_names[1] if customer_names else '' }}">
<label class="form-label mt-2" for="contact_2">Ansprechpartner (optional)</label>
<textarea class="form-control" id="contact_2" name="contact_2" rows="4"
placeholder="**Maria Schmidt**&#10;+49 456 7890123&#10;*E-Mail*: maria@muster.de">{{ contacts[1] if contacts else '' }}</textarea>
</div>
<div class="col-md-4">
<label class="form-label" for="customer_name_3">Kunde 3 (optional)</label>
<input type="text" class="form-control" id="customer_name_3"
name="customer_name_3" placeholder="z. B. Firma GmbH"
value="{{ customer_names[2] if customer_names else '' }}">
<label class="form-label mt-2" for="contact_3">Ansprechpartner (optional)</label>
<textarea class="form-control" id="contact_3" name="contact_3" rows="4"
placeholder="**Sabine Weber**&#10;+49 789 0123456&#10;*E-Mail*: sabine@firma.de">{{ contacts[2] if contacts else '' }}</textarea>
</div>
</div>
<hr class="mt-4 mb-3">
<div class="mb-3">
<label class="form-label" for="valid_until">Anzeigen bis <span class="text-muted">(optional)</span></label>
<input type="date" class="form-control" id="valid_until" name="valid_until"
value="{{ request.form.get('valid_until', '') }}" style="max-width: 260px;">
<div class="form-hint">Ohne Angabe bleibt die Willkommensseite stehen, bis sie von Hand entfernt wird. Mit Datum verschwindet sie nach diesem Tag auf allen Screens von selbst.</div>
</div>
<div class="mb-3 text-muted">
<p class="mb-1">Das System sucht automatisch nach den Kundenlogos</p>
<p class="mb-0">und erstellt eine angepasste Willkommensseite.</p>
<p class="mb-1">Sie erscheint auf allen Screens dieses Standorts, bei denen im Tab „Einstellungen" die Option <em>Willkommensseite hier anzeigen</em> aktiv ist{% if welcome_screens %} – aktuell: <strong>{{ welcome_screens | join(', ') }}</strong>{% else %} – <strong>aktuell keiner</strong>{% endif %}.</p>
<p class="mb-0 small"><i class="ti ti-markdown me-1"></i>Ansprechpartner unterstützen <strong>fett</strong>, <em>kursiv</em>, <code>Code</code>, Aufzählungen (<code>- </code>) sowie Zeilenumbrüche.</p>
</div>
<button type="submit" class="btn btn-primary">
<i class="ti ti-file-plus me-1"></i>Logos &amp; Willkommensseite generieren
</button>
<a href="?reset=1&amp;site={{ site }}" class="btn btn-outline-secondary ms-2">
<i class="ti ti-trash me-1"></i>Zurücksetzen
</a>
</form>
</div>
</div>
<!-- ═══════════════════════════════════════════════════
Karte: Hintergrundbild hochladen (pro Standort)
═══════════════════════════════════════════════════ -->
<div class="card mb-4">
<div class="card-header">
<div class="row align-items-center">
<div class="col">
<div class="page-pretitle">Willkommensseite</div>
<h2 class="page-title">Hintergrund</h2>
</div>
</div>
</div>
<div class="card-body">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Aktuelles Hintergrundbild</label>
<div class="logo-preview-box" style="min-height:200px; background: #f0f0f0;">
<img src="{{ background_url or '/static/wallpaper.png' }}" alt="Hintergrund" style="max-height:180px; width:100%; object-fit:contain; background:transparent; padding:0;">
</div>
</div>
<div class="col-md-6">
<label class="form-label">Neues Hintergrundbild hochladen</label>
<form method="POST" action="/admin/{{ site }}/upload-background" enctype="multipart/form-data">
<input type="file" class="form-control mb-2" name="background" accept=".jpg,.jpeg,.png" required>
<button type="submit" class="btn btn-primary">
<i class="ti ti-upload me-1"></i>Hochladen
</button>
</form>
{% if background_url %}
<form method="POST" action="/admin/{{ site }}/delete-background" class="mt-2">
<button type="submit" class="btn btn-outline-danger">
<i class="ti ti-trash me-1"></i>Zurücksetzen auf Standard
</button>
</form>
{% endif %}
<p class="text-muted mt-2 mb-0 small">
<i class="ti ti-info-circle me-1"></i>
Wenn kein Hintergrundbild hochgeladen ist, wird das Standard-Wallpaper verwendet.
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<footer class="app-footer">
{% include "_footer.html" %}
</footer>
<script>
</script>
</body>
</html>