meldestelle/docs/06_Frontend/Guidelines/Empty-States_Spezifikation_v1.md
Stefan Mogeritsch 52f2a54e0b feat(docs): finalize editing forms guideline and define empty state specification
- Marked `Editier-Formulare_Dialog-vs-Fullscreen_v1.md` as APPROVED with finalized mapping for all edit screens.
- Created `Empty-States_Spezifikation_v1.md` to outline design, behavior, and implementation plan for empty states across 10 screens.
- Logged session outcomes in `2026-04-03_UIUX_B1_B4_Editier-Formulare_Empty-States_Curator_Log.md`.
- Updated `UIUX_Roadmap.md` to reflect Sprint B completion and tasks for Sprint C-1.

Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
2026-04-03 11:54:44 +02:00

15 KiB

type status owner last_update related
Frontend Guideline APPROVED đŸ–Œïž UI/UX Designer 2026-04-03
docs/06_Frontend/Guidelines/Editier-Formulare_Dialog-vs-Fullscreen_v1.md
docs/04_Agents/Roadmaps/UIUX_Roadmap.md
docs/04_Agents/Roadmaps/Frontend_Roadmap.md

Empty States — Design-Spezifikation & Richtlinie

Ziel: Konsistente, hilfreiche Leer-ZustĂ€nde fĂŒr alle Listenansichten im Meldestelle-Desktop. Leitsatz: Ein leerer Zustand ist kein Fehler — er ist eine Einladung zur ersten Aktion.


1. Warum Empty States wichtig sind

  • Erster Start / Onboarding: Neue Nutzer sehen leere Listen — ohne Hinweis wirkt die App kaputt.
  • Nach Filterung: Kein Treffer bei Suche/Filter muss klar kommuniziert werden (≠ Ladefehler).
  • Nach Löschung: Letzte EntitĂ€t gelöscht → leere Liste braucht Orientierung.
  • Vertrauen: Klare Kommunikation verhindert Unsicherheit ("Ist das ein Bug?").

2. Empty-State-Typen

Typ Auslöser PrimÀre Aktion
EMPTY_LIST Liste ist leer (noch keine Daten angelegt) CTA: Ersten Eintrag anlegen
NO_RESULTS Suche/Filter liefert keine Treffer CTA: Filter zurĂŒcksetzen
ERROR Ladefehler (Netzwerk, Backend nicht erreichbar) CTA: Erneut versuchen
LOADING Daten werden geladen (Skeleton/Spinner) Kein CTA

LOADING wird durch MsLoadingIndicator abgedeckt — kein separater Empty State nötig.


3. Visuelle Anatomie — MsEmptyState

┌─────────────────────────────────────────────────────────┐
│                                                         │
│                    [  Icon / 48dp  ]                    │
│                                                         │
│              Titel (MaterialTheme.titleMedium)          │
│                                                         │
│     Beschreibung (MaterialTheme.bodyMedium, zentriert,  │
│     max. 2 Zeilen, gedimmt: onSurface 60%)              │
│                                                         │
│              [ PrimĂ€rer CTA-Button ]  (optional)        │
│                                                         │
└─────────────────────────────────────────────────────────┘

Maße & AbstĂ€nde

Element Wert
Icon-GrĂ¶ĂŸe 48 dp
Icon-Farbe MaterialTheme.colorScheme.onSurface @ 38% Alpha
Abstand Icon→Titel 16 dp
Abstand Titel→Beschreibung 8 dp
Abstand Beschreibung→Button 24 dp
Max. Breite Textblock 360 dp (zentriert)
Padding gesamt 32 dp rundum

Typografie

Element Style
Titel MaterialTheme.typography.titleMedium
Beschreibung MaterialTheme.typography.bodyMedium, Alpha 60%
Button Standard MsButton (outlined fĂŒr sekundĂ€re Aktionen)

4. Icon-Konzept

Wir verwenden Material Symbols (Outlined) — konsistent mit dem restlichen Design-System. Kein Custom-Illustration-Set fĂŒr MVP (zu aufwĂ€ndig, zu wenig Mehrwert bei High-Density-Desktop).

Screen / Kontext Icon BegrĂŒndung
Veranstalter-Liste person_off Kein Veranstalter vorhanden
Veranstaltungs-Liste event_busy Keine Veranstaltung
Turnier-Liste emoji_events (durchgestrichen) Kein Turnier
Bewerb-Liste list_alt Keine Bewerbe
Nennungs-Liste assignment_ind Keine Nennungen
Reiter-Liste person_search Kein Reiter gefunden
Pferde-Liste search_off Kein Pferd gefunden
Verein-Liste group_off Kein Verein
FunktionÀr-Liste badge Kein FunktionÀr
Abteilungs-Startliste format_list_numbered Keine Starter
Abteilungs-Ergebnisliste leaderboard Keine Ergebnisse
Suche / Filter (allg.) search_off Kein Treffer
Fehler (allg.) cloud_off Verbindungsfehler

5. Texte je Screen

Allgemeine Regel

  • Titel: Kurz, prĂ€zise, max. 5 Wörter. Keine Ausrufezeichen.
  • Beschreibung: ErklĂ€rt den Zustand UND gibt Handlungshinweis. Max. 2 SĂ€tze.
  • CTA: Verb + Objekt. Klar und direkt.

Texte je Kontext

Veranstalter

Typ Titel Beschreibung CTA
EMPTY_LIST Noch kein Veranstalter Lege den ersten Veranstalter an, um loszulegen. Veranstalter anlegen
NO_RESULTS Kein Veranstalter gefunden Kein Eintrag passt zur Suche. Passe den Suchbegriff an. Suche zurĂŒcksetzen
ERROR Laden fehlgeschlagen Veranstalter konnten nicht geladen werden. Erneut versuchen

Veranstaltungen

Typ Titel Beschreibung CTA
EMPTY_LIST Noch keine Veranstaltung Erstelle die erste Veranstaltung fĂŒr diesen Veranstalter. Veranstaltung anlegen
NO_RESULTS Keine Veranstaltung gefunden Kein Treffer fĂŒr den gewĂ€hlten Filter. Filter zurĂŒcksetzen
ERROR Laden fehlgeschlagen Veranstaltungen konnten nicht geladen werden. Erneut versuchen

Turniere

Typ Titel Beschreibung CTA
EMPTY_LIST Noch kein Turnier FĂŒge das erste Turnier zu dieser Veranstaltung hinzu. Turnier anlegen
NO_RESULTS Kein Turnier gefunden Kein Turnier entspricht dem aktuellen Filter. Filter zurĂŒcksetzen
ERROR Laden fehlgeschlagen Turniere konnten nicht geladen werden. Erneut versuchen

Bewerbe

Typ Titel Beschreibung CTA
EMPTY_LIST Noch kein Bewerb Lege den ersten Bewerb fĂŒr dieses Turnier an. Bewerb anlegen
NO_RESULTS Kein Bewerb gefunden Kein Bewerb entspricht dem aktuellen Filter. Filter zurĂŒcksetzen
ERROR Laden fehlgeschlagen Bewerbe konnten nicht geladen werden. Erneut versuchen

Nennungen

Typ Titel Beschreibung CTA
EMPTY_LIST Noch keine Nennung Es wurden noch keine Nennungen fĂŒr diesen Bewerb erfasst. Nennung erfassen
NO_RESULTS Keine Nennung gefunden Kein Treffer fĂŒr den gewĂ€hlten Filter oder die Suche. Filter zurĂŒcksetzen
ERROR Laden fehlgeschlagen Nennungen konnten nicht geladen werden. Erneut versuchen

Reiter

Typ Titel Beschreibung CTA
EMPTY_LIST Noch kein Reiter Importiere Stammdaten oder lege den ersten Reiter an. Reiter anlegen
NO_RESULTS Kein Reiter gefunden Kein Reiter entspricht dem Suchbegriff. Suche zurĂŒcksetzen
ERROR Laden fehlgeschlagen Reiter konnten nicht geladen werden. Erneut versuchen

Pferde

Typ Titel Beschreibung CTA
EMPTY_LIST Noch kein Pferd Importiere Stammdaten oder lege das erste Pferd an. Pferd anlegen
NO_RESULTS Kein Pferd gefunden Kein Pferd entspricht dem Suchbegriff. Suche zurĂŒcksetzen
ERROR Laden fehlgeschlagen Pferde konnten nicht geladen werden. Erneut versuchen

Vereine

Typ Titel Beschreibung CTA
EMPTY_LIST Noch kein Verein Lege den ersten Verein an. Verein anlegen
NO_RESULTS Kein Verein gefunden Kein Verein entspricht dem Suchbegriff. Suche zurĂŒcksetzen
ERROR Laden fehlgeschlagen Vereine konnten nicht geladen werden. Erneut versuchen

FunktionÀre

Typ Titel Beschreibung CTA
EMPTY_LIST Noch kein FunktionÀr Lege den ersten FunktionÀr an. FunktionÀr anlegen
NO_RESULTS Kein FunktionĂ€r gefunden Kein FunktionĂ€r entspricht dem Suchbegriff. Suche zurĂŒcksetzen
ERROR Laden fehlgeschlagen FunktionÀre konnten nicht geladen werden. Erneut versuchen

Abteilungs-Startliste

Typ Titel Beschreibung CTA
EMPTY_LIST Keine Starter FĂŒr diese Abteilung wurden noch keine Starter zugewiesen. Nennungen prĂŒfen
ERROR Laden fehlgeschlagen Startliste konnte nicht geladen werden. Erneut versuchen

Abteilungs-Ergebnisliste

Typ Titel Beschreibung CTA
EMPTY_LIST Keine Ergebnisse FĂŒr diese Abteilung wurden noch keine Ergebnisse erfasst. —
ERROR Laden fehlgeschlagen Ergebnisliste konnte nicht geladen werden. Erneut versuchen

6. Composable-Spezifikation — MsEmptyState

Ablageort: frontend/core/design-system/src/commonMain/kotlin/at/mocode/frontend/core/designsystem/components/MsEmptyState.kt

API

/**
 * Einheitlicher Empty-State fĂŒr alle Listenansichten.
 *
 * @param icon Material-Symbol (ImageVector) passend zum Kontext.
 * @param title Kurzer Titel (max. 5 Wörter).
 * @param description ErklÀrung + Handlungshinweis (max. 2 SÀtze). Optional.
 * @param actionLabel Text des primÀren CTA-Buttons. Null = kein Button.
 * @param onAction Callback fĂŒr den CTA-Button.
 * @param modifier Modifier fĂŒr Ă€ußeres Layout.
 */
@Composable
fun MsEmptyState(
    icon: ImageVector,
    title: String,
    description: String? = null,
    actionLabel: String? = null,
    onAction: (() -> Unit)? = null,
    modifier: Modifier = Modifier
)

Verhalten

  • Zentriert (horizontal + vertikal) im verfĂŒgbaren Raum.
  • Icon gedimmt (38% Alpha), Beschreibung gedimmt (60% Alpha).
  • Button nur anzeigen wenn actionLabel != null && onAction != null.
  • Button-Stil: OutlinedButton (sekundĂ€re Aktion, nicht zu dominant).
  • Bei ERROR-Typ: Icon cloud_off, Button als FilledButton (Retry ist primĂ€re Aktion).

Verwendungsbeispiel

// In einer LazyColumn / Column wenn items.isEmpty():
if (state.reiter.isEmpty() && !state.isLoading) {
    MsEmptyState(
        icon = Icons.Outlined.PersonSearch,
        title = "Noch kein Reiter",
        description = "Importiere Stammdaten oder lege den ersten Reiter an.",
        actionLabel = "Reiter anlegen",
        onAction = { onIntent(ReiterIntent.OpenCreateDialog) }
    )
}

7. Implementierungs-Reihenfolge (Sprint C-1)

PrioritÀt Screen Typ(en)
1 Veranstalter-Auswahl EMPTY_LIST, NO_RESULTS
2 Veranstaltungs-Übersicht EMPTY_LIST, NO_RESULTS
3 Turnier-Bewerbe-Tab EMPTY_LIST
4 Turnier-Nennungen-Tab EMPTY_LIST, NO_RESULTS
5 Reiter-Liste EMPTY_LIST, NO_RESULTS
6 Pferde-Liste EMPTY_LIST, NO_RESULTS
7 Verein-Liste EMPTY_LIST, NO_RESULTS
8 FunktionÀr-Liste EMPTY_LIST, NO_RESULTS
9 Abteilungs-Startliste EMPTY_LIST
10 Abteilungs-Ergebnisliste EMPTY_LIST
Alle Alle Listen ERROR (einheitlich)

Hinweis: ERROR-State wird einmalig als Default-Variante in MsEmptyState implementiert und kann ĂŒberall mit type = EmptyStateType.ERROR aufgerufen werden.


8. Abgrenzung zu anderen Komponenten

Situation Komponente
Daten werden geladen MsLoadingIndicator
Liste leer / kein Treffer MsEmptyState
Kritischer Fehler (App-Ebene) Eigener Error-Screen
Inline-Validierungsfehler MsValidationWrapper
Status einer EntitÀt MsStatusBadge