b2in/public/_cabinet/_docs/CABINET_PROJECT.md
2026-04-10 17:18:17 +02:00

274 lines
11 KiB
Markdown

# CABINET Digital Signage System - Projektdokumentation
**Stand:** Februar 2026 | **Version:** 1.3
---
## 1. Projektübersicht
Das CABINET Digital Signage System ist ein In-Store-Display-System für den CABINET Store in Bielefeld. Es besteht aus zwei eigenständigen Modulen, die auf hochkant montierten Displays (9:16 Seitenverhältnis, 1080x1920px) im Store laufen:
| Modul | Datei | Live-URL | Zweck |
|-------|-------|----------|-------|
| **Video-Display** | `index.html` | `cabinet.b2in.eu` | Zeigt eine Endlos-Playlist von Videos mit rotierenden Footer-Inhalten (Headline, Subline, QR-Code) |
| **Angebots-Display** | `offers/player.html` | (noch nicht live) | Zeigt statische Produkt-Slides (Angebote, Preise, Details) als Slide-Rotation |
| **Info-Tablet** | (in Planung) | `cabinet.b2in.eu/info` | Zeigt Store-Status, Öffnungszeiten, Termine im Schaufenster |
Alle Inhalte werden uber das B2in-Backend (Admin-Portal unter `portal.b2in.test`) gepflegt.
---
## 2. Architektur
```
public/_cabinet/
├── index.html # LIVE: Video-Display (Hauptseite)
├── index_1.html # Ältere Version
├── index_2.html # Ältere Version
├── index-dynamic.html # Dynamische Variante
├── index-static-backup.html # Statisches Fallback
├── index copy.html # Kopie/Backup
├── offer.html # Prototyp: Angebots-Slides (all-in-one)
├── offers/ # NEU: Modulares Angebots-System
│ ├── player.html # Slide-Player (lädt config.json + iFrames)
│ ├── config.json # Slide-Konfiguration (Reihenfolge, Dauer, Inhalte)
│ ├── shared-styles.css # Gemeinsame CSS-Styles für alle Slides
│ ├── slide-0-intro.html # Intro-Slide (Store-Vorstellung)
│ ├── slide-1-goya-hero.html # Produkt-Slide: GOYA Sideboard (Hero)
│ ├── slide-2-goya-details.html# Produkt-Slide: GOYA Details/Konditionen
│ └── slide-3-tando.html # Produkt-Slide: TANDO Spiegel (Impuls)
├── assets/ # Medien-Dateien
│ ├── *.mp4 # Videos (Saison-Spots)
│ ├── *.jpg # Produkt-/Hintergrundbilder
│ └── cabinet-intro.jpg # Intro-Bild
├── go.php # QR-Code Redirect + Klick-Tracking
├── logger.php # Remote-Logging-Endpoint (CORS-fähig)
├── view-logs.php # Web-basierter Log-Viewer
├── setup-logging.sh # Logging-Setup-Skript
├── test-logging.html # Test-Seite für Logging
├── logs/ # Log-Dateien (nach Level + Datum)
├── clicks.log # QR-Code-Klick-Log
├── logo-cabinet-300.png # CABINET Logo (300px)
├── logo-cabinet.png.webp # CABINET Logo (WebP)
├── .htaccess.example # Apache-Konfigurationsvorlage
├── infotablet.md # Konzept: Info-Tablet für Schaufenster
├── offer.md # Notizen zum Angebots-System
├── QUICK_START.md # Bedienungsanleitung
├── KIOSK_MODE_SETUP.md # Anleitung Kiosk-Modus (Fully Browser)
├── LOGGING_README.md # Logging-Dokumentation
├── VIDEO_OPTIMIZATION_README.md# Video-Optimierungstipps
└── CABINET_PROJECT.md # Diese Datei
```
---
## 3. Modul A: Video-Display (`index.html`)
### Funktionsweise
- Lädt die Konfiguration (Video-Playlist + Footer-Inhalte) per API vom Backend
- Spielt Videos nacheinander in einer Endlosschleife ab
- Footer rotiert unabhängig alle 30 Sekunden (Headline + Subline + QR-Code)
### API-Anbindung
- **Endpoint:** `GET /api/display/config` (auf `b2in.eu`)
- **Response:**
```json
{
"videoPlaylist": [
{ "src": "assets/fruehjahr_2025.mp4", "position": 25 }
],
"footerContent": [
{ "headline": "Text", "subline": "Subtext", "url": "https://..." }
]
}
```
- **Polling:** Alle 5 Minuten wird die Config neu geladen
- **Präventiver Reload:** Alle 6 Stunden kompletter Page-Reload
### Robustheit
- **Video-Watchdog:** Prüft alle 5 Sek. ob Video läuft, Recovery bei Stuck
- **Start-Timeout:** 10 Sek. Timeout, dann Skip zum nächsten Video
- **Memory-Management:** Cleanup nach jedem Video, Monitoring alle 10 Min.
- **Error-Recovery:** Nach 3 aufeinanderfolgenden Fehlern → Page-Reload
- **Remote-Logging:** Alle Events werden an `logger.php` gesendet
### Layout
```
┌─────────────────┐
│ │
│ VIDEO-BEREICH │ flex-grow: 1 (nimmt restliche Höhe ein)
│ (object-fit: │
│ cover) │
│ │
├──────────────────┤
│ ▬▬▬ Progress ▬▬ │ 3px Progress-Bar
│ CTA-TEXT │ QR │ ~10% Höhe
│ Headline │Code │ Footer mit rotierendem Inhalt
│ Subline │ │
└─────────────────┘
```
---
## 4. Modul B: Angebots-Display (`offers/`)
### Funktionsweise
- `player.html` ist der Haupt-Player
- Lädt `config.json` für Slide-Konfiguration
- Jeder Slide ist ein eigenständiges HTML-Dokument, eingebettet per iFrame
- Slides rotieren automatisch mit konfigurierbarer Dauer (8-12 Sek.)
- Fade-Transition (0.6s) zwischen Slides
### Slide-Typen
| Typ | Beschreibung | Beispiel |
|-----|-------------|---------|
| `intro` | Store-Vorstellung, allgemeiner Willkommenstext | slide-0-intro.html |
| `product-hero` | Produkt mit Hero-Bild, Preis, UVP | slide-1-goya-hero.html |
| `product-details` | Produkt-Details mit Bullet-Liste | slide-2-goya-details.html |
| `product-impulse` | Impulskauf-Produkt ("Jetzt mitnehmen") | slide-3-tando.html |
### Slide-Layout (shared-styles.css)
```
┌─────────────────────────────┐
│ HEADER │ Logo + Tagline
│ [CABINET Logo] [Tagline] │
├─────────────────────────────┤
│ │
│ HERO-BILD │ flex: 1 (nimmt Hauptfläche ein)
│ (Produktfoto) │
│ [Badge] │
│ │
├──────────────┬──────────────┤
│ INFO-BOX │ QR-BOX │ Unterer Bereich
│ Eyebrow │ Titel │
│ Titel │ QR-Code │
│ Preis/UVP │ Kontakt │
│ Bullets │ │
└──────────────┴──────────────┘
```
### Design-System
- **Schrift:** IBM Plex Sans (Google Fonts)
- **Akzentfarbe:** `#009FE3` (Cabinet Blau)
- **Safe-Area:** 64px Padding
- **Max. Auflösung:** 1080x1920px (9:16)
- **QR-Codes:** Werden live per `api.qrserver.com` generiert
### Status
Die Angebots-Slides sind **fertig entwickelt aber noch nicht live**. Die Inhalte (Produkte, Preise, Bilder) sind statisch in den HTML-Dateien hinterlegt. Eine Backend-Anbindung (wie beim Video-Display) fehlt noch.
---
## 5. Modul C: Info-Tablet (in Planung)
Konzept dokumentiert in `infotablet.md`. Ein kleines Tablet im Schaufenster zeigt:
- Store-Status (Geöffnet/Hinweis/Geschlossen)
- Öffnungszeiten (Wochenansicht, heutiger Tag hervorgehoben)
- Nächster freier Beratungstermin
- Kontakt + QR-Code
**API geplant:** `GET /api/cabinet-tablet/status`
---
## 6. Backend-Anbindung
### Datenbank-Tabellen
**`display_videos`** - Video-Playlist
| Spalte | Typ | Beschreibung |
|--------|-----|-------------|
| id | bigint | Primary Key |
| filename | varchar | Dateiname (z.B. `fruehjahr_2025.mp4`) |
| title | varchar | Anzeige-Titel (optional) |
| position | int | Vertikale Position des Videos (0-100, für `object-position`) |
| sort_order | int | Reihenfolge in der Playlist |
| is_active | tinyint | Aktiv/Inaktiv |
**`display_footer_contents`** - Footer-Inhalte (CTA-Texte + QR-Codes)
| Spalte | Typ | Beschreibung |
|--------|-----|-------------|
| id | bigint | Primary Key |
| headline | varchar | Überschrift (z.B. "JETZT TERMIN BUCHEN") |
| subline | varchar | Unterzeile (z.B. "Beratung vor Ort...") |
| url | varchar | Ziel-URL für QR-Code (optional) |
| short_code | varchar | 6-stelliger Code für Redirect (unique) |
| clicks | int | Klick-Zähler (via go.php) |
| sort_order | int | Reihenfolge |
| is_active | tinyint | Aktiv/Inaktiv |
### Backend-Komponenten
| Komponente | Pfad | Funktion |
|-----------|------|----------|
| API-Controller | `app/Http/Controllers/Api/DisplayConfigController.php` | Liefert JSON-Config für Video-Display |
| Video-Model | `app/Models/DisplayVideo.php` | Eloquent-Model mit `active()` Scope |
| Footer-Model | `app/Models/DisplayFooterContent.php` | Model mit Short-Code-Generierung + Short-URL |
| Admin-Seite | `app/Livewire/Admin/Cms/CabinetDisplay.php` | Livewire-Verwaltung für Videos + Footer |
| Admin-Route | `/admin/cms/cabinet` | Admin-Portal-Seite |
| API-Route | `GET /api/display/config` | Öffentlicher API-Endpoint |
### QR-Code / Redirect-System
1. Backend generiert automatisch einen 6-stelligen `short_code` pro Footer-Inhalt
2. QR-Code im Display zeigt URL wie `cabinet.b2in.eu/go.php?z=abc123`
3. `go.php` schlägt den Code in der DB nach, erhöht den Klick-Zähler, und leitet weiter
4. Fallback: Alte Legacy-Codes (t, t1, p, i, f) für Rückwärtskompatibilität
---
## 7. Logging & Monitoring
### Remote-Logging (`logger.php`)
- Empfängt POST-Requests mit JSON-Logdaten vom Display
- CORS-aktiviert für Cross-Origin-Zugriff
- Speichert Logs in drei Formaten:
- Pro Level: `logs/info_2026-02-27.log`, `logs/error_2026-02-27.log`
- Alle zusammen: `logs/all_2026-02-27.log`
- JSON: `logs/json_2026-02-27.log`
- Automatische Log-Rotation: Dateien > 30 Tage werden gelöscht
### Was wird geloggt
- Video-Lifecycle: Start, Ende, Error, Stuck, Timeout
- Heartbeat alle 5 Minuten ("Display läuft")
- Memory-Status alle 10 Minuten
- Online/Offline-Status
- JavaScript-Fehler (global error handler)
- Resource-Loading-Fehler (Bilder, Videos)
### Log-Viewer (`view-logs.php`)
Web-basierte Oberfläche zum Lesen der Logs mit Auto-Refresh und Farbcodierung.
---
## 8. Deployment & Betrieb
### Live-System
- **Domain:** `cabinet.b2in.eu` (Subdomain von b2in.eu)
- **Assets-URL:** `https://b2in.eu/_cabinet/assets/`
- **API-URL:** `https://b2in.eu/api/display/config`
### Test-System
- **URL:** `b2in.test/_cabinet/`
- **API:** `b2in.test/api/display/config`
### Kiosk-Modus
Empfohlen: **Fully Kiosk Browser** (Android) - Details in `KIOSK_MODE_SETUP.md`
- Auto-Start bei Boot
- Vollbild ohne Statusbar
- Auto-Restart bei Crash
- Zeitsteuerung (22:00 Standby, 07:00 Aufwachen)
---
## 9. Offene Punkte / TODO
- [ ] **Offers-System Backend-Anbindung**: `offers/` Slides haben noch keine API-Anbindung - Inhalte sind statisch im HTML
- [ ] **Offers live schalten**: Player + Slides auf Live-System deployen
- [ ] **Info-Tablet umsetzen**: Konzept steht (infotablet.md), Implementierung offen
- [ ] **Offers Config aus DB**: `config.json` sollte dynamisch vom Backend generiert werden
- [ ] **Bilder-Upload**: Produktbilder für Offers werden noch manuell in `assets/` abgelegt