7702574904
- Added `PferdReiterEingabe` for horse and rider selection with search functionality and keyboard navigation. - Implemented `NennungenTabelle` to display filtered registrations based on selected horse or rider. - Introduced `NennungsMaske` to combine search, table, and competition views for streamlined user interaction. - Extended types with `Veranstalter` interface and mock data for better context and integration. - Documented ÖTO-compliant tournament structure for frontend reference. Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
26 KiB
26 KiB
UI/UX Design-Dokumentation - UI/UX Designer
🎨 Design-System-Übersicht
Eine kompakte, tastaturoptimierte Desktop-Turnierverwaltungs-Anwendung im Material Design 3 Stil mit Indigo als Primärfarbe.
Design-Philosophie:
- Desktop-First (1440px+)
- Hohe Informationsdichte
- Kompakte Darstellung (10-13px Schriftgrößen)
- Tastatur-Navigation
- Professionell & Funktional
🎯 Design-Prinzipien
1. Desktop-Optimierung
- Zielauflösung: 1440px - 1920px
- Mehrspaltiges Layout
- Hohe Informationsdichte
- Keine mobile Variante (aktuell)
2. Kompaktheit
- Kleine Schriftgrößen (10-13px)
- Reduzierte Abstände
- Kompakte Controls (small size)
- Maximale Nutzung des Bildschirms
3. Effizienz
- Tastatur-Navigation (Tab, Enter, ESC)
- Shortcuts für häufige Aktionen
- Schnelle Dateneingabe
- Minimale Klicks
4. Konsistenz
- Material Design 3 Guidelines
- Einheitliche Komponenten
- Konsistente Farbgebung
- Wiedererkennbare Patterns
🎨 Farb-Palette
Primär-Farben
Indigo (Haupt-Primärfarbe)
├── Main: #3F51B5 RGB(63, 81, 181)
├── Light: #7986CB RGB(121, 134, 203)
├── Dark: #303F9F RGB(48, 63, 159)
└── Ultra: #1A237E RGB(26, 35, 126)
Sekundär-Farben
Deep Orange
├── Main: #FF5722 RGB(255, 87, 34)
├── Light: #FF8A65 RGB(255, 138, 101)
└── Dark: #E64A19 RGB(230, 74, 25)
Graustufen (Background & Text)
├── Grey 50: #FAFAFA → Paper Background
├── Grey 100: #F5F5F5 → Section Background
├── Grey 200: #EEEEEE → Disabled Background
├── Grey 300: #E0E0E0 → Border Color
├── Grey 500: #9E9E9E → Secondary Text
├── Grey 700: #616161 → Primary Text
└── Grey 900: #212121 → Header Text
Semantische Farben
Success (Grün)
├── Main: #4CAF50 → Bestätigt, Bezahlt
├── Light: #81C784
└── Dark: #388E3C
Warning (Orange/Amber)
├── Main: #FF9800 → Warnung, Pending
├── Light: #FFB74D
└── Dark: #F57C00
Error (Rot)
├── Main: #F44336 → Fehler, Offen, Saldo
├── Light: #E57373
└── Dark: #D32F2F
Info (Blau)
├── Main: #2196F3 → Information
├── Light: #64B5F6
└── Dark: #1976D2
Status-Farben (Badges)
Geplant: #2196F3 (Blau)
Laufend: #4CAF50 (Grün)
Abgeschlossen: #9E9E9E (Grau)
Offen: #F44336 (Rot)
Bestätigt: #4CAF50 (Grün)
📝 Typografie
Font Family
Primary: 'Roboto', sans-serif
Monospace: 'Roboto Mono', monospace (für Zahlen/Codes)
Font Sizes (Kompakt für Desktop)
├── Heading 1: 18px (Seiten-Titel)
├── Heading 2: 15px (Bereich-Überschriften)
├── Heading 3: 13px (Unter-Überschriften)
├── Body: 11px (Standard-Text)
├── Small: 10px (Labels, Hilfstext)
└── Tiny: 9px (Fußnoten, Timestamps)
Font Weights
├── Light: 300
├── Regular: 400 (Standard)
├── Medium: 500 (Labels, Buttons)
├── Semi-Bold: 600 (Headings)
└── Bold: 700 (Wichtige Zahlen, Summen)
Line Heights
├── Tight: 1.2 (Kompakte Listen)
├── Normal: 1.5 (Standard-Text)
└── Relaxed: 1.8 (Lange Texte)
Text Styles (Material-UI)
// Typography Variants
variant="h1" → 18px, Semi-Bold
variant="h2" → 15px, Semi-Bold
variant="h3" → 13px, Medium
variant="body1" → 11px, Regular
variant="body2" → 11px, Regular
variant="caption" → 10px, Regular
variant="overline" → 10px, Medium, Uppercase
📐 Spacing & Layout
Spacing Scale
├── xs: 4px (Sehr eng)
├── sm: 8px (Standard-Innenabstand)
├── md: 16px (Zwischen-Abstand)
├── lg: 24px (Bereich-Abstand)
├── xl: 32px (Große Abstände)
└── xxl: 48px (Sehr große Abstände)
Material-UI Spacing (8px-Basis)
sx={{ p: 1 }} // padding: 8px
sx={{ p: 2 }} // padding: 16px
sx={{ py: 1.5 }} // padding-top/bottom: 12px
sx={{ px: 2 }} // padding-left/right: 16px
sx={{ m: 2 }} // margin: 16px
sx={{ gap: 1 }} // gap: 8px
Layout Grid
Desktop (1440px+)
├── Container Max-Width: 1920px
├── Sidebar Width: 240-280px
├── Content Area: Fluid (100%)
├── Gutter: 24px
└── Column Gap: 16px
Component Heights (Kompakt)
├── AppBar: 48px
├── Tab Bar: 36px
├── Table Row: 32px
├── Button (small): 28px
├── TextField (small): 32px
└── Chip/Badge: 20px
🧩 Komponenten-Styles
1. Buttons
// Primary Button
<Button
variant="contained"
size="small"
sx={{
fontSize: '11px',
py: 0.5,
px: 2,
minWidth: 100,
textTransform: 'none',
}}
>
Speichern
</Button>
// Secondary Button
<Button
variant="outlined"
size="small"
sx={{
fontSize: '11px',
py: 0.5,
px: 1.5,
}}
>
Abbrechen
</Button>
// Icon Button
<IconButton size="small" sx={{ p: 0.5 }}>
<EditIcon fontSize="small" />
</IconButton>
Design Specs:
- Font Size: 11px
- Text Transform: none (keine ALL CAPS)
- Padding: 4px 16px (small)
- Min Width: 100px
- Border Radius: 4px
2. Text Fields
<TextField
size="small"
label="Turnier-Name"
fullWidth
sx={{
'& .MuiInputBase-input': {
fontSize: '11px',
py: 0.75,
},
'& .MuiInputLabel-root': {
fontSize: '11px',
},
}}
/>
Design Specs:
- Height: 32px (small)
- Font Size: 11px
- Label Font Size: 11px
- Border Radius: 4px
- Focus Color: Indigo (#3F51B5)
3. Tables
<Table size="small">
<TableHead>
<TableRow>
<TableCell sx={{
fontSize: '11px',
fontWeight: 600,
bgcolor: 'grey.100',
py: 1,
}}>
Name
</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow sx={{
'&:hover': { bgcolor: 'action.hover' },
'&:nth-of-type(odd)': { bgcolor: 'grey.50' },
}}>
<TableCell sx={{ fontSize: '10px', py: 0.5 }}>
Wert
</TableCell>
</TableRow>
</TableBody>
</Table>
Design Specs:
- Row Height: 32px
- Font Size: 10px (Body), 11px (Header)
- Header Background: Grey 100
- Zebra Stripes: Grey 50 (odd rows)
- Hover: Action Hover (#F5F5F5)
4. Tabs
<Tabs
value={activeTab}
onChange={handleChange}
sx={{
borderBottom: 1,
borderColor: 'divider',
'& .MuiTab-root': {
fontSize: '11px',
minHeight: 36,
py: 1,
textTransform: 'none',
},
}}
>
<Tab label="Stammdaten" />
<Tab label="Bewerbe" />
</Tabs>
Design Specs:
- Tab Height: 36px
- Font Size: 11px
- Text Transform: none
- Active Indicator: Indigo, 2px thick
- Hover Background: rgba(63, 81, 181, 0.04)
5. Cards
<Card elevation={1}>
<CardContent sx={{ p: 2 }}>
<Typography variant="h3" sx={{ mb: 1.5 }}>
Titel
</Typography>
<Typography variant="body1">
Inhalt
</Typography>
</CardContent>
</Card>
Design Specs:
- Border Radius: 8px
- Elevation: 1 (Standard), 2 (Hover)
- Padding: 16px
- Background: White
6. Chips / Badges
<Chip
label="Laufend"
size="small"
sx={{
fontSize: '9px',
height: 20,
bgcolor: 'success.main',
color: 'white',
fontWeight: 600,
}}
/>
Design Specs:
- Height: 20px
- Font Size: 9px
- Font Weight: 600
- Border Radius: 10px
- Padding: 0 8px
7. Dialogs
<Dialog
open={open}
maxWidth="md"
fullWidth
>
<DialogTitle sx={{ fontSize: '13px', fontWeight: 600, py: 1.5 }}>
Bewerb erstellen
</DialogTitle>
<DialogContent sx={{ py: 2 }}>
{/* Content */}
</DialogContent>
<DialogActions sx={{ px: 2, py: 1.5, gap: 1 }}>
<Button variant="outlined">Abbrechen</Button>
<Button variant="contained">Speichern</Button>
</DialogActions>
</Dialog>
Design Specs:
- Max Width: 600px (md), 900px (lg)
- Title Font Size: 13px
- Content Padding: 16px
- Actions Padding: 12px 16px
📱 Layout-Patterns
1. Master-Detail Layout (Dashboard)
┌────────────────────────────────────────────┐
│ AppBar (48px) │
├────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────┐ │
│ │ Header mit Filter & Aktionen │ │
│ ├──────────────────────────────────────┤ │
│ │ │ │
│ │ Grid mit Karten │ │
│ │ ┌────┐ ┌────┐ ┌────┐ │ │
│ │ │Card│ │Card│ │Card│ │ │
│ │ └────┘ └────┘ └────┘ │ │
│ │ │ │
│ └──────────────────────────────────────┘ │
└────────────────────────────────────────────┘
2. Tab-Based Layout (Turnier-Ansicht)
┌────────────────────────────────────────────┐
│ AppBar mit Breadcrumbs (48px) │
├────────────────────────────────────────────┤
│ Tab Navigation (36px) │
│ [Stammdaten][Organisation][Bewerbe]... │
├────────────────────────────────────────────┤
│ │
│ Tab Content Area (Scrollable) │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ Formulare / Tabellen / Charts │ │
│ │ │ │
│ │ │ │
│ └──────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────┘
3. Split-Panel Layout (Nennungs-Maske)
┌────────────────────────────────────────────┐
│ Pferd & Reiter (60%) │ Verkauf (40%) │
│ ┌───────────────────┐ │ ┌────────────┐ │
│ │ Suche & Details │ │ │ Buchungen │ │
│ │ │ │ │ │ │
│ └───────────────────┘ │ └────────────┘ │
├────────────────────────────────────────────┤
│ Navigation Buttons (5%) │
├────────────────────────────────────────────┤
│ Nennungen (60%) │ Bewerbe (40%) │
│ ┌───────────────────┐ │ ┌────────────┐ │
│ │ Tabelle │ │ │ Liste │ │
│ │ │ │ │ │ │
│ └───────────────────┘ │ └────────────┘ │
└────────────────────────────────────────────┘
4. Table-Sidebar Layout (Abrechnung)
┌────────────────────────────────────────────┐
│ Buchungen-Tabelle (70%) │ Aktionen (30%)│
│ ┌─────────────────────┐ │ ┌──────────┐ │
│ │ Table mit Buchungen │ │ │ Auswahl │ │
│ │ │ │ ├──────────┤ │
│ │ Soll | Haben | ... │ │ │ Buchen │ │
│ │ │ │ ├──────────┤ │
│ │ Summenzeile │ │ │ Drucken │ │
│ └─────────────────────┘ │ ├──────────┤ │
│ │ │ Zahlung │ │
│ │ └──────────┘ │
└────────────────────────────────────────────┘
🎭 Interaktions-Patterns
1. Hover States
/* Button Hover */
button:hover {
background-color: rgba(63, 81, 181, 0.08);
}
/* Table Row Hover */
tr:hover {
background-color: rgba(0, 0, 0, 0.04);
}
/* Card Hover */
.card:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
transform: translateY(-2px);
transition: all 0.2s ease;
}
2. Focus States
/* Input Focus */
input:focus {
border-color: #3F51B5;
box-shadow: 0 0 0 2px rgba(63, 81, 181, 0.2);
}
/* Button Focus */
button:focus-visible {
outline: 2px solid #3F51B5;
outline-offset: 2px;
}
3. Loading States
<Box sx={{ display: 'flex', justifyContent: 'center', py: 4 }}>
<CircularProgress size={32} />
</Box>
4. Empty States
<Box sx={{
textAlign: 'center',
py: 8,
color: 'text.secondary'
}}>
<InboxIcon sx={{ fontSize: 48, mb: 2 }} />
<Typography variant="body1">
Keine Daten vorhanden
</Typography>
</Box>
5. Error States
<Alert severity="error" sx={{ mb: 2 }}>
<AlertTitle>Fehler</AlertTitle>
Beim Laden der Daten ist ein Fehler aufgetreten.
</Alert>
🖼️ Icon-System
Icon Library: Material Icons
import AddIcon from '@mui/icons-material/Add';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete';
import SaveIcon from '@mui/icons-material/Save';
import CancelIcon from '@mui/icons-material/Cancel';
Icon Sizes
├── Small: 16px (Icon Buttons in Tables)
├── Medium: 20px (Default, Buttons)
├── Large: 24px (Headers)
└── XLarge: 32px (Empty States)
Häufig verwendete Icons
Aktionen:
├── Add: AddIcon
├── Edit: EditIcon
├── Delete: DeleteIcon
├── Save: SaveIcon
├── Cancel: CancelIcon
├── Search: SearchIcon
└── Refresh: RefreshIcon
Navigation:
├── Home: HomeIcon
├── Arrow Back: ArrowBackIcon
├── Arrow Forward: ArrowForwardIcon
└── Menu: MenuIcon
Status:
├── Check Circle: CheckCircleIcon
├── Error: ErrorIcon
├── Warning: WarningIcon
└── Info: InfoIcon
Turnier:
├── Event: EventIcon
├── Trophy: EmojiEventsIcon
├── Person: PersonIcon
├── Horse: (Custom SVG)
├── Receipt: ReceiptIcon
└── Print: PrintIcon
📊 Daten-Visualisierung
1. Status-Badges
// Farb-Mapping
const statusColors = {
geplant: '#2196F3', // Blau
laufend: '#4CAF50', // Grün
abgeschlossen: '#9E9E9E', // Grau
offen: '#F44336', // Rot
bezahlt: '#4CAF50', // Grün
};
<Chip
label="Laufend"
size="small"
sx={{
bgcolor: statusColors.laufend,
color: 'white',
fontSize: '9px',
}}
/>
2. Summen-Zeilen (Tables)
<TableRow sx={{ bgcolor: 'primary.50' }}>
<TableCell sx={{ fontWeight: 700 }}>GESAMT</TableCell>
<TableCell align="right" sx={{ fontWeight: 700 }}>
{total.toFixed(2)} €
</TableCell>
</TableRow>
3. Farb-kodierte Werte
// Saldo-Färbung
<Typography
sx={{
color: saldo > 0 ? 'error.main' : 'success.main',
fontWeight: 600,
}}
>
{saldo.toFixed(2)} €
</Typography>
4. Progress Indicators
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<LinearProgress
variant="determinate"
value={progress}
sx={{ flex: 1, height: 6, borderRadius: 3 }}
/>
<Typography variant="caption">{progress}%</Typography>
</Box>
♿ Accessibility (A11y)
1. Keyboard Navigation
Tab: Nächstes Element
Shift + Tab: Vorheriges Element
Enter: Aktion ausführen / Dialog öffnen
Escape: Dialog schließen / Aktion abbrechen
Space: Checkbox / Radio Button togglen
Arrow Keys: Navigation in Listen / Tabs
2. ARIA Labels
<IconButton
aria-label="Bewerb löschen"
onClick={handleDelete}
>
<DeleteIcon />
</IconButton>
<TextField
aria-label="Turnier-Name"
aria-required="true"
aria-invalid={!!error}
/>
3. Focus Management
// Auto-Focus auf ersten Input im Dialog
<TextField autoFocus />
// Focus Trap in Dialog
<Dialog disableEscapeKeyDown>
<FocusTrap>
{/* Content */}
</FocusTrap>
</Dialog>
4. Color Contrast
WCAG AA Standard (Minimum):
├── Normal Text: 4.5:1
└── Large Text: 3:1
Unsere Farben:
├── Primary (#3F51B5) auf White: 6.9:1 ✅
├── Grey 700 (#616161) auf White: 5.7:1 ✅
├── Grey 500 (#9E9E9E) auf White: 3.3:1 ⚠️ (nur für große Texte)
🎬 Animationen & Transitions
Transition-Timing
/* Standard */
transition: all 0.2s ease;
/* Hover Effekte */
transition: transform 0.2s ease, box-shadow 0.2s ease;
/* Dialog/Modal */
transition: opacity 0.3s ease, transform 0.3s ease;
Material-UI Transitions
import { Fade, Slide, Grow } from '@mui/material';
// Fade In/Out
<Fade in={open} timeout={300}>
<Box>Content</Box>
</Fade>
// Slide
<Slide direction="up" in={open}>
<Dialog>Content</Dialog>
</Slide>
// Grow
<Grow in={open}>
<Card>Content</Card>
</Grow>
Animation Best Practices
✅ DO:
- Subtile Hover-Effekte (2-4px translateY)
- Fade In/Out für Dialogs
- Smooth Transitions für Tabs
- Loading Spinners
❌ DON'T:
- Zu lange Animationen (> 500ms)
- Unnötige Animationen bei jedem Klick
- Animationen die Bedienung verlangsamen
📸 Screenshots & Wireframes
1. Login
┌─────────────────────────────────┐
│ │
│ [LOGO] │
│ │
│ Turnierverwaltung Login │
│ │
│ ┌───────────────────────────┐ │
│ │ Username 🔒 │ │
│ └───────────────────────────┘ │
│ │
│ ┌───────────────────────────┐ │
│ │ Password 🔒 │ │
│ └───────────────────────────┘ │
│ │
│ [ Anmelden ] │
│ │
└─────────────────────────────────┘
2. Dashboard
┌─────────────────────────────────────────────┐
│ 🏠 Admin - Verwaltung [+ Neue] │
├─────────────────────────────────────────────┤
│ │
│ Veranstaltungen │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │Frühjahr │ │Sommer │ │Herbst │ │
│ │Turnier │ │Cup │ │Turnier │ │
│ │ │ │ │ │ │ │
│ │[Laufend]│ │[Geplant]│ │[Geplant]│ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
└─────────────────────────────────────────────┘
3. Turnier-Ansicht (Tabs)
┌─────────────────────────────────────────────┐
│ 🏠 Admin > Frühjahrsturnier > Turnier A │
├─────────────────────────────────────────────┤
│[Stammdaten][Organisation][Bewerbe][...] │
├─────────────────────────────────────────────┤
│ │
│ Turnier-Konfiguration │
│ ┌─────────────────────────────────────┐ │
│ │ ZNS-Daten: [Import Button] │ │
│ │ ÖTO-Typ: ○ National ● International│ │
│ │ FEI-Typ: [CSI**, CDI2*, etc.] │ │
│ └─────────────────────────────────────┘ │
│ │
│ Turnier-Beschreibung │
│ ┌─────────────────────────────────────┐ │
│ │ Titel: [________________] │ │
│ │ Sub-Titel: [________________] │ │
│ └─────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────┘
🎨 Design-Tokens (CSS Variables)
/* theme.css */
:root {
/* Colors */
--color-primary: #3f51b5;
--color-primary-light: #7986cb;
--color-primary-dark: #303f9f;
--color-secondary: #ff5722;
/* Backgrounds */
--bg-default: #fafafa;
--bg-paper: #ffffff;
--bg-hover: rgba(0, 0, 0, 0.04);
/* Text */
--text-primary: #212121;
--text-secondary: #757575;
--text-disabled: #bdbdbd;
/* Borders */
--border-color: #e0e0e0;
--border-radius: 4px;
/* Shadows */
--shadow-sm: 0 1px 2px rgba(0,0,0,0.08);
--shadow-md: 0 2px 4px rgba(0,0,0,0.12);
--shadow-lg: 0 4px 8px rgba(0,0,0,0.15);
/* Spacing */
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
/* Typography */
--font-size-xs: 10px;
--font-size-sm: 11px;
--font-size-md: 13px;
--font-size-lg: 15px;
--font-size-xl: 18px;
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
/* Transitions */
--transition-fast: 0.15s ease;
--transition-base: 0.2s ease;
--transition-slow: 0.3s ease;
}
📋 Component Library Checklist
✅ Implementierte Komponenten
- Login Form
- Dashboard (Card Grid)
- Navigation (Breadcrumbs, Tabs)
- Tables (Data Tables mit Sorting)
- Forms (Text Fields, Select, Radio, Checkbox)
- Buttons (Primary, Secondary, Icon)
- Dialogs (Create, Edit, Confirm)
- Badges (Status Chips)
- Split Panels (Nennungs-Maske, Abrechnung)
⏳ Geplante Komponenten
- Notifications/Toasts
- Date/Time Pickers
- File Upload
- PDF Preview
- Print Layout
- Charts/Graphs
- Calendar View
- Drag & Drop Interface
🎯 Design-Checklist für neue Features
□ Folgt Material Design 3 Guidelines?
□ Schriftgröße 10-13px (Desktop-kompakt)?
□ Indigo (#3F51B5) als Primärfarbe verwendet?
□ Tastatur-Navigation möglich?
□ Hover/Focus States definiert?
□ Loading States vorhanden?
□ Error States behandelt?
□ Empty States designed?
□ Mobile-Ansicht berücksichtigt? (falls relevant)
□ Accessibility (A11y) beachtet?
□ Konsistent mit bestehenden Komponenten?
📚 Design-Ressourcen
Material-UI Documentation
Figma Files
- [Link zu Figma-Design-Datei]
Color Tools
- Material Color Tool: https://m2.material.io/resources/color/
- Contrast Checker: https://webaim.org/resources/contrastchecker/
Icon Resources
- Material Icons: https://fonts.google.com/icons
🔮 Design-Roadmap
Phase 1: MVP (Aktuell)
- ✅ Basic Design System
- ✅ Kompakte Desktop-Layouts
- ✅ Alle 8 Turnier-Tabs
- ✅ Nennungs-Maske
- ✅ Abrechnung
Phase 2: Verbesserungen
- Druck-Layouts (PDF-Export)
- Dark Mode
- Erweiterte Visualisierungen
- Drag & Drop für Startlisten
Phase 3: Erweiterungen
- Mobile/Tablet-Responsiveness
- Custom Themes pro Veranstalter
- Animierte Dashboards
- Real-Time Collaboration UI
Dokumentiert von: UI/UX Designer
Version: 1.0
Datum: 2026-03-24