# Preisdatenbank Koblenz – Frontend
**Technologie:** Single-Page HTML/JS (kein Framework), Vanilla JS, CSS Custom Properties
**Datei:** `/opt/preisdb/app/index.html` (lokal: `C:\MoniBase\offen\preisdb\index.html`)
**Port:** 8765 — ausgeliefert direkt vom FastAPI-Backend als statische Datei
**Stand:** v2.1 (2026-06-10)
---
## Seitenaufbau
```
┌─────────────────────────────────────────────────────┐
│ Header: Titel + letzter Import-Zeitstempel + Anzahl │
│ Angebote │
├─────────────────────────────────────────────────────┤
│ Navigation: [Suche] [Sparfuchs] [Admin] │
├─────────────────────────────────────────────────────┤
│ Tab-Inhalt │
│ │
│ │
├─────────────────────────────────────────────────────┤
│ Floating-Bar (Einkaufsliste) — immer sichtbar │
└─────────────────────────────────────────────────────┘
```
---
## Tab: Suche
### Suchformular (3 Felder, horizontal)
| Feld | Typ | Verhalten |
|---|---|---|
| Freitext | Text-Input | Suche in Produktname, Beschreibung, Kategorie |
| Kategorie | Select/Dropdown | Alle Kategorien alphabetisch |
| Lebensmittelgruppe | Select/Dropdown | Alle LG nach `sortierung` |
Felder sind kombinierbar. Mindestens ein Feld muss befüllt sein. Suche startet per Button oder Enter.
### Ergebnistabelle
Spalten (in dieser Reihenfolge):
| Spalte | Quelle |
|---|---|
| Gruppe | `lg_symbol` + `lg_name` aus `Lebensmittelgruppe` |
| Produkt | `produkt` aus `Produkt.name` |
| Beschreibung | `beschreibung` aus `Angebot` |
| Preis | `preis` mit Streichpreis (`alter_preis`) wenn vorhanden |
| Normpreis | `referenz_preis` (Preis/Einheit) |
| Händler | `haendler` |
| Gültig bis | `gueltig_bis` |
| + | Button — fügt Zeile zur Einkaufsliste hinzu |
Sortierung: aufsteigend nach Normpreis (`NULLS LAST`), dann nach Preis. Non-Food wird serverseitig gefiltert.
Badges: Treuekarte-Symbol wenn `requires_loyalty = 1`.
---
## Einkaufsliste (Floating-Bar, global)
Permanente Bar am unteren Bildschirmrand:
- Zeigt Artikelanzahl als Badge
- Klick öffnet Einkaufsliste als Overlay/Panel
- Inhalt: nach Händler gruppiert, innerhalb alphabetisch sortiert
- Pro Artikel: Name, Preis, Entfernen-Button (×)
- Gesamtsumme aller Artikel
- Schaltflächen: „Drucken" und „Alle löschen"
Drucken: löst `window.print()` aus. Print-CSS blendet alles außer der Einkaufsliste aus.
---
## Tab: Sparfuchs
3 Sub-Views, umschaltbar per Button-Leiste:
### Sub-View 1: Ansicht (nach Sparfuchs-Gruppe)
- Dropdown zur Auswahl einer gespeicherten Sparfuchs-Gruppe
- Für jede Kategorie in der Gruppe: Kacheln mit TOP-3-Angeboten (nach Normpreis)
- Karte zeigt: Rang (🥇🥈🥉), Händler, Produktname, Beschreibung, Preis, Normpreis, Streichpreis, Treuekarte-Badge
- „+ Zur Liste"-Button auf jeder Karte
### Sub-View 2: Nach Lebensmittelgruppe
- Dropdown zur Auswahl einer Lebensmittelgruppe
- Gleiche Kachel-Darstellung wie Sub-View 1, aber für alle Kategorien der LG
### Sub-View 3: Verwaltung (Sparfuchs-Gruppen)
- Tabelle aller Sparfuchs-Gruppen
- Neue Gruppe anlegen: Name + Kategorie-Mehrfachauswahl (Checkbox-Liste)
- Gruppe bearbeiten, löschen
- Nur Food-Kategorien werden angeboten
---
## Tab: Admin
5 Sub-Tabs, lazy geladen (erst beim ersten Klick):
```
[🔤 Suchbegriffe] [🏷 Kategorien] [🌾 Lebensmittelgruppen] [🖨 Übersicht] [🏪 Händler]
```
### Sub-Tab: Suchbegriffe
- Tabelle: Begriff | Aktiv | Letzter Import | Letzte Treffer | Aktionen
- Aktiv/Inaktiv per Toggle-Button
- Neuer Begriff: Eingabefeld + Hinzufügen-Button
- Begriff löschen per ×-Button
### Sub-Tab: Kategorien
- Tabelle: Name | Produktanzahl | Food/Non-Food | Lebensmittelgruppe | Aktionen
- Food/Non-Food per Toggle-Button umschalten
- Lebensmittelgruppe per Dropdown-Select zuordnen (sofortige API-Anfrage)
### Sub-Tab: Lebensmittelgruppen
- Tabelle: Symbol | Name | Sortierung | Aktionen
- Neue Gruppe: Symbol (Emoji), Name, Sortierung → Anlegen
- Bestehende umbenennen oder löschen
### Sub-Tab: Übersicht (Druck)
- Hierarchische Liste: **Lebensmittelgruppe** → **Kategorie** → **Artikel**
- Alle Food-Produkte, alphabetisch sortiert (Daten von `/admin/uebersicht`)
- Drucken-Button — Print-CSS zeigt nur diesen Tab-Inhalt
### Sub-Tab: Händler
- Tabelle: Name | marktguru-ID | Angebote (Anzahl) | Status
- Aktiv/Inaktiv per Toggle-Button umschalten
- Inaktive Händler werden beim Import übersprungen
---
## Styling
- CSS Custom Properties für Farben und Abstände
- Responsiv (kein Framework)
- Leichtes, helles Design
- Print-CSS: blendet Navigation, Header und alle Tabs bis auf den aktiven Druck-Inhalt aus
---
[[Hinweise/Impressum|Impressum]] | [[Hinweise/Datenschutzerklärung|Datenschutz]]