11 KiB
11 KiB
HMS Licht & Ton – Component Inventory
Overview
All components are built as Vue 3 single-file components (template + setup). In production (Nuxt 3), these map to .vue files in components/ and pages/ directories.
Shared Components
HmsLogo
- Purpose: SVG logo with white HMS text + orange (#EC6925) rectangular border
- Props:
size(Number, default: 40) - States: Default only (static SVG)
- Accessibility:
aria-label,role="img"
SpeakerIcon
- Purpose: SVG loudspeaker/light icon for equipment grid
- Props:
type(String: linearray, subwoofer, monitor, pointsource, column, movinghead) - States: Default (gray), Hover (orange via parent CSS)
- Accessibility:
aria-hidden="true"
AppHeader
- Purpose: Sticky navigation header with logo, desktop nav, mobile hamburger menu
- States: Default, Active nav item (
aria-current="page"), Mobile menu open/closed - Accessibility:
role="banner",aria-label,aria-expanded,aria-controls
AppFooter
- Purpose: 4-column footer with company info, navigation, contact, legal links
- States: Default only
- Accessibility:
role="contentinfo"
ServiceCard
- Purpose: Service offering card with icon, title, description
- Props:
icon,title,description - States: Default, Hover (border highlight)
EquipmentCard
- Purpose: Equipment listing card with image, badge, name, description, add-to-cart button
- Props:
item(Object: id, code, name, category, description, brand, image) - Emits:
click,add-to-cart - States: Default, Hover (border + shadow + lift), Focus (keyboard), No image (placeholder)
- Accessibility:
role="article",tabindex="0",aria-labelon add button
LoadingSkeleton
- Purpose: Shimmer animation skeleton cards for loading states
- Props:
count(Number, default: 6) - States: Shimmer animation (infinite)
- Accessibility:
aria-live="polite",aria-busy="true"
EmptyState
- Purpose: Empty state with icon, title, message, optional CTA button
- Props:
icon,title,message,actionLabel - Emits:
action - States: Default
- Accessibility:
role="status"
ErrorState
- Purpose: Error state with alert icon, title, message, retry button
- Props:
title,message - Emits:
retry - States: Default
- Accessibility:
role="alert"
LegalContentPage
- Purpose: Reusable layout for static legal content pages (Impressum, Datenschutz, AGB)
- Props:
title(String),content(String/HTML) - States: loading (skeleton), content (rendered)
- Accessibility:
role="article", semantic heading structure h1 > h2 > h3
Page Components
HomePage (#/)
- Sections: Hero (bg image + overlay), Speaker Grid (6 types), Über uns (stats + image), 8 Service Cards, Mietkatalog CTA
- States: Default (all content static)
ReferenzenPage (#/referenzen)
- States: Loading (skeleton), Loaded (gallery grid), Error (retry), Empty (no category results)
- Features: Category filter chips (Alle, Open-Air, Indoor, Rigging, Event), 9 real HMS photos
KontaktPage (#/kontakt)
- Sections: Büro/Lager/Öffnungszeiten cards, 2 Ansprechpartner cards, Contact form
- Form States: Default, Validation errors (inline), Submitting (spinner), Submitted (success message)
- Validation: Name*, Email* (regex), Message*, Privacy checkbox*
MietkatalogPage (#/mietkatalog)
- States: Loading (skeleton), Loaded (equipment grid), Error (retry), Empty (no search results)
- Features: Search input, Category filter chips (7 categories), Sort dropdown (name/brand/code), Result count
EquipmentDetailPage (#/mietkatalog/:id)
- States: Loading (skeleton), Loaded (detail view), Error (not found)
- Sections: Image/placeholder, Specs table, Rental form (date range + quantity), Related items grid
- Form: Mietbeginn, Mietende, Anzahl (stepper), Add to cart button
WarenkorbPage (#/warenkorb)
- States: Empty (no items), Cart with items
- Features: Item list with quantity steppers, remove buttons, rental dates display, CTA button → /mietanfrage
- Note: Warenkorb verwaltet nur Items (anzeigen, Mengen steuern, entfernen). Kein Formular für Kontaktdaten hier.
- Accessibility: Cart summary with live-updating totals,
aria-live="polite"
MietanfragePage (#/mietanfrage)
- Purpose: Mietanfrage-Formular mit Veranstaltungsdaten + Kontaktdaten + Nachricht. Submit sendet an Rentman via POST /projectrequests + POST /projectrequests/{id}/projectrequestequipment.
- Sections:
- Warenkorb-Übersicht: Zeigt ausgewählte Artikel mit Mengen (read-only), Link zurück zum Warenkorb
- Veranstaltungsdaten: Name*, Datum von*, Datum bis*, Ort*, Anzahl Personen
- Kontaktdaten: Name*, Firma, E-Mail*, Telefon, Adresse (Straße, PLZ, Ort)
- Nachricht: Freitext-Nachrichtfeld
- Submit: "Mietanfrage absenden" Button
- States:
form– Default, Formular leer oder mit Validierungs-Hinweisenvalidation-error– Inline-Validierungsfehler (Pflichtfelder markiert, Fehlermeldungen unter den Feldern)submitting– Spinner im Submit-Button, Felder disabledsuccess– Erfolgsmeldung mit Referenz-Nummer, Weiter-Button ("Zurück zur Startseite")error– Fehlermeldung mit Retry-Button ("Erneut versuchen")
- Empty Cart Handling: Wenn Warenkorb leer → Hinweis "Keine Artikel ausgewählt" + Link zum Mietkatalog
- Validation:
- Veranstaltungsname: Pflicht, min 3 Zeichen
- Datum von/bis: Pflicht, von ≤ bis
- Ort: Pflicht
- Name: Pflicht, min 2 Zeichen
- E-Mail: Pflicht, Regex-Validierung
- Telefon: Optional, Format-Validierung
- Adresse: Optional (aber wenn PLZ angegeben, auch Ort erforderlich)
- Accessibility:
role="form",aria-invalidon error fields,aria-describedbyfor error messages, fieldset/legend for grouped sections
AdminPage (#/admin)
- Purpose: Admin-Login und post-login Dashboard mit Equipment-Sync-Trigger
- States:
login– Login-Form (Username + Password), Fehler bei falschen Datenidle– Post-Login Dashboard, Sync-Status sichtbar, Sync-Button bereitsyncing– Sync läuft, Progress-Indicator, Sync-Log live aktualisiertsync-complete– Sync abgeschlossen, Status aktualisiert (last sync date, article count), Erfolgsmeldungsync-error– Sync fehlgeschlagen, Fehlermeldung + Retry-Button, Sync-Log zeigt Fehlerdetails
- Elements:
- Sync-Trigger Button: "Equipment-Sync starten" (Primary, disabled während syncing)
- Sync-Status: Last sync date, article count, Sync-Status-Badge (idle/syncing/complete/error)
- Sync-Log Viewer: Scrollbarer Log-Bereich mit Zeitstempeln, kollabierbar
- Login-Form States: Default, Validation error (invalid credentials), Loading (spinner)
- Accessibility:
role="main",aria-live="polite"für Sync-Status,aria-busywährend syncing
ImpressumPage (#/impressum)
- Purpose: Statische Impressum-Seite mit rechtlichen Angaben gemäß §5 TMG
- Route:
/impressum - Content: Firmenname, Vertretungsberechtigte, Anschrift, Kontakt, USt-IdNr., Verantwortlich für Inhalte
- States: loading (skeleton), content (rendered)
- Component: Verwendet
LegalContentPageLayout - Accessibility: Semantic heading structure h1 > h2
DatenschutzPage (#/datenschutz)
- Purpose: Statische Datenschutz-Seite mit DSGVO-konformer Datenschutzerklärung
- Route:
/datenschutz - Content: Server-Logfiles, Cookies, Kontaktformular-Datenverarbeitung, Rentman-Datenverarbeitung, Nutzerrechte
- States: loading (skeleton), content (rendered)
- Component: Verwendet
LegalContentPageLayout - Accessibility: Semantic heading structure h1 > h2 > h3
AGBVermietungPage (#/agb-vermietung)
- Purpose: Statische AGB-Seite für Vermietung
- Route:
/agb-vermietung - Content: Allgemeine Geschäftsbedingungen für Vermietung (vom User bereitgestellter Text)
- States: loading (skeleton), content (rendered)
- Component: Verwendet
LegalContentPageLayout - Accessibility: Semantic heading structure h1 > h2
NotFoundPage (#/404)
- States: Default (404 message + home link)
UX State Coverage Summary
| Page | Loading | Empty | Error | Partial | Success | Additional States |
|---|---|---|---|---|---|---|
| Home | – | – | – | – | – | – |
| Referenzen | Skeleton | No category | Retry | Filtered | – | – |
| Kontakt | – | – | – | – | Form sent | validation-error |
| Mietkatalog | Skeleton | No results | Retry | Filtered | – | – |
| Detail | Skeleton | – | Not found | – | – | – |
| Warenkorb | – | Empty cart | – | – | – | – |
| Mietanfrage | – | Empty cart | Retry | – | Request sent | form, submitting, validation-error |
| Admin | Spinner | – | Login error | – | Logged in | idle, syncing, sync-complete, sync-error |
| Impressum | Skeleton | – | – | – | – | content |
| Datenschutz | Skeleton | – | – | – | – | content |
| AGB Vermietung | Skeleton | – | – | – | – | content |
| 404 | – | – | – | – | – | – |
Component States Documentation
Button States
- Default:
background: var(--color-accent); color: white - Hover:
background: var(--color-accent-hover) - Active:
transform: translateY(0) - Disabled:
background: var(--secondary); cursor: not-allowed - Focus-visible:
outline: 2px solid var(--color-accent); outline-offset: 2px
Input States
- Default:
border: 1px solid var(--border-strong); background: var(--surface) - Focus:
border-color: var(--color-accent); box-shadow: 0 0 0 2px rgba(236,105,37,0.1) - Error:
border-color: var(--color-error) - Disabled:
background: var(--row); color: var(--secondary); cursor: not-allowed
Card States
- Default:
border: 1px solid var(--border); box-shadow: var(--shadow-sm) - Hover:
border-color: var(--secondary); box-shadow: var(--shadow-lg)
Chip States
- Default:
border: 1px solid var(--border-strong); background: var(--surface) - Hover:
border-color: var(--secondary) - Active:
background: var(--color-accent); color: white; border-color: var(--color-accent)
Sync-Status Badge States (AdminPage)
- Idle:
background: var(--surface); color: var(--text-muted) - Syncing:
background: rgba(96, 165, 250, 0.08); color: var(--color-info); animation: pulse - Complete:
background: var(--color-success-bg); color: var(--color-success) - Error:
background: var(--color-error-bg); color: var(--color-error)