T07a: frontend core SPA — shell + auth + routing + i18n + UI library + a11y
- React 18 + Vite + TypeScript + Tailwind CSS setup - AppShell with Sidebar (plugin menu) + TopBar (tenant switcher, search, notifications, user menu) - Auth pages: Login, PasswordResetRequest, PasswordResetConfirm - Protected routes with auth guard - API client (axios with interceptors: session cookie, 401 redirect, 422 validation) - TanStack Query hooks for auth, users, companies, contacts, notifications - Zustand stores: authStore, uiStore - i18n setup (de/en locales) with react-i18next - UI component library: Button, Input, Select, Modal, Toast, Table, Card, Badge, Avatar, Pagination, EmptyState, Skeleton, ConfirmDialog - Accessibility: ARIA labels, 44px touch targets, keyboard nav, reduced-motion, sr-only - Design tokens from prototype as CSS custom properties - 111 tests passing across 20 test files - tsc --noEmit: 0 errors - npm run build: success (471KB JS, 24KB CSS)
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
{
|
||||
"app": {
|
||||
"name": "leocrm",
|
||||
"tagline": "Mini-CRM für kleine Unternehmen"
|
||||
},
|
||||
"nav": {
|
||||
"dashboard": "Dashboard",
|
||||
"companies": "Firmen",
|
||||
"contacts": "Kontakte",
|
||||
"calendar": "Kalender",
|
||||
"files": "Dateien",
|
||||
"email": "E-Mail",
|
||||
"users": "Benutzer",
|
||||
"auditLog": "Audit-Log",
|
||||
"settings": "Einstellungen"
|
||||
},
|
||||
"auth": {
|
||||
"login": "Anmelden",
|
||||
"logout": "Abmelden",
|
||||
"email": "E-Mail-Adresse",
|
||||
"password": "Passwort",
|
||||
"loginButton": "Anmelden",
|
||||
"loginFailed": "Anmeldung fehlgeschlagen. Bitte überprüfen Sie Ihre Eingaben.",
|
||||
"forgotPassword": "Passwort vergessen?",
|
||||
"resetPassword": "Passwort zurücksetzen",
|
||||
"resetRequestTitle": "Passwort zurücksetzen",
|
||||
"resetRequestDesc": "Geben Sie Ihre E-Mail-Adresse ein. Sie erhalten einen Link zum Zurücksetzen Ihres Passworts.",
|
||||
"resetRequestButton": "Link senden",
|
||||
"resetRequestSuccess": "Wenn die E-Mail-Adresse existiert, wurde ein Reset-Link gesendet.",
|
||||
"resetConfirmTitle": "Neues Passwort festlegen",
|
||||
"resetConfirmDesc": "Geben Sie Ihr neues Passwort ein.",
|
||||
"newPassword": "Neues Passwort",
|
||||
"confirmPassword": "Passwort bestätigen",
|
||||
"resetConfirmButton": "Passwort ändern",
|
||||
"resetConfirmSuccess": "Passwort erfolgreich geändert. Sie können sich jetzt anmelden.",
|
||||
"resetConfirmFailed": "Passwort konnte nicht geändert werden. Der Link ist möglicherweise abgelaufen.",
|
||||
"backToLogin": "Zurück zur Anmeldung",
|
||||
"passwordMismatch": "Passwörter stimmen nicht überein.",
|
||||
"passwordTooShort": "Passwort muss mindestens 8 Zeichen lang sein."
|
||||
},
|
||||
"common": {
|
||||
"save": "Speichern",
|
||||
"cancel": "Abbrechen",
|
||||
"delete": "Löschen",
|
||||
"edit": "Bearbeiten",
|
||||
"create": "Erstellen",
|
||||
"search": "Suchen",
|
||||
"loading": "Wird geladen...",
|
||||
"noResults": "Keine Ergebnisse gefunden",
|
||||
"confirm": "Bestätigen",
|
||||
"close": "Schließen",
|
||||
"yes": "Ja",
|
||||
"no": "Nein",
|
||||
"actions": "Aktionen",
|
||||
"all": "Alle",
|
||||
"none": "Keine",
|
||||
"error": "Fehler",
|
||||
"success": "Erfolg",
|
||||
"warning": "Warnung",
|
||||
"info": "Information",
|
||||
"required": "Pflichtfeld",
|
||||
"optional": "Optional"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Einstellungen",
|
||||
"language": "Sprache",
|
||||
"theme": "Design",
|
||||
"light": "Hell",
|
||||
"dark": "Dunkel",
|
||||
"system": "System",
|
||||
"profile": "Profil",
|
||||
"notifications": "Benachrichtigungen",
|
||||
"security": "Sicherheit"
|
||||
},
|
||||
"topbar": {
|
||||
"tenant": "Mandant",
|
||||
"switchTenant": "Mandant wechseln",
|
||||
"search": "Suchen...",
|
||||
"notifications": "Benachrichtigungen",
|
||||
"userMenu": "Benutzermenü",
|
||||
"profile": "Profil",
|
||||
"settings": "Einstellungen",
|
||||
"logout": "Abmelden"
|
||||
},
|
||||
"toast": {
|
||||
"success": "Erfolg",
|
||||
"error": "Fehler",
|
||||
"warning": "Warnung",
|
||||
"info": "Information"
|
||||
},
|
||||
"table": {
|
||||
"page": "Seite",
|
||||
"of": "von",
|
||||
"results": "Ergebnisse",
|
||||
"perPage": "pro Seite",
|
||||
"previous": "Zurück",
|
||||
"next": "Weiter",
|
||||
"sortAscending": "Aufsteigend sortieren",
|
||||
"sortDescending": "Absteigend sortieren",
|
||||
"sortedBy": "Sortiert nach",
|
||||
"empty": "Keine Daten vorhanden"
|
||||
},
|
||||
"confirmDialog": {
|
||||
"title": "Bestätigung erforderlich",
|
||||
"confirm": "Bestätigen",
|
||||
"cancel": "Abbrechen"
|
||||
},
|
||||
"pagination": {
|
||||
"previous": "Zurück",
|
||||
"next": "Weiter",
|
||||
"page": "Seite {{page}}",
|
||||
"first": "Erste Seite",
|
||||
"last": "Letzte Seite"
|
||||
},
|
||||
"emptyState": {
|
||||
"title": "Nichts gefunden",
|
||||
"description": "Es sind noch keine Daten vorhanden."
|
||||
},
|
||||
"validation": {
|
||||
"required": "Dieses Feld ist erforderlich.",
|
||||
"email": "Bitte geben Sie eine gültige E-Mail-Adresse ein.",
|
||||
"minLength": "Mindestens {{count}} Zeichen erforderlich.",
|
||||
"maxLength": "Maximal {{count}} Zeichen erlaubt."
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user