Three distinct bugs caused infinite OIDC redirect loops:
1. After logout, navigating to /login with no signal to suppress the
auto-redirect caused the login page to immediately re-trigger the
OIDC flow. Fixed by passing `{ state: { noRedirect: true } }` via
React Router's navigation state (not URL params, which were fragile
due to async cleanup timing) from all logout call sites.
2. On the OIDC callback page (/login?oidc_code=...), App.tsx's
mount-level loadUser() fired concurrently with the LoginPage's
exchange fetch. The App-level call had no cookie yet and got a 401,
which (if it resolved after the successful exchange loadUser()) would
overwrite isAuthenticated back to false. Fixed by skipping loadUser()
in App.tsx when the initial path is /login.
3. React 18 StrictMode double-invokes useEffect. The first run called
window.history.replaceState to clean the oidc_code from the URL
before starting the async exchange, so the second run saw no
oidc_code and fell through to the getAppConfig auto-redirect, firing
window.location.href = '/api/auth/oidc/login' before the exchange
could complete. Fixed by adding a useRef guard to prevent
double-execution and moving replaceState into the fetch callbacks so
the URL is only cleaned after the exchange resolves.
Also adds login.oidcLoggedOut translation key in all 14 languages to
show "You have been logged out" instead of the generic OIDC-only
message when landing on /login after an intentional logout.
Closes #491
1699 lines
86 KiB
TypeScript
1699 lines
86 KiB
TypeScript
const de: Record<string, string | { name: string; category: string }[]> = {
|
||
// Allgemein
|
||
'common.save': 'Speichern',
|
||
'common.cancel': 'Abbrechen',
|
||
'common.delete': 'Löschen',
|
||
'common.edit': 'Bearbeiten',
|
||
'common.add': 'Hinzufügen',
|
||
'common.loading': 'Laden...',
|
||
'common.import': 'Importieren',
|
||
'common.error': 'Fehler',
|
||
'common.back': 'Zurück',
|
||
'common.all': 'Alle',
|
||
'common.close': 'Schließen',
|
||
'common.open': 'Öffnen',
|
||
'common.upload': 'Hochladen',
|
||
'common.search': 'Suchen',
|
||
'common.confirm': 'Bestätigen',
|
||
'common.ok': 'OK',
|
||
'common.yes': 'Ja',
|
||
'common.no': 'Nein',
|
||
'common.or': 'oder',
|
||
'common.none': 'Keine',
|
||
'common.date': 'Datum',
|
||
'common.rename': 'Umbenennen',
|
||
'common.name': 'Name',
|
||
'common.email': 'E-Mail',
|
||
'common.password': 'Passwort',
|
||
'common.saving': 'Speichern...',
|
||
'common.saved': 'Gespeichert',
|
||
'trips.reminder': 'Erinnerung',
|
||
'trips.reminderNone': 'Keine',
|
||
'trips.reminderDay': 'Tag',
|
||
'trips.reminderDays': 'Tage',
|
||
'trips.reminderCustom': 'Benutzerdefiniert',
|
||
'trips.reminderDaysBefore': 'Tage vor Abreise',
|
||
'trips.reminderDisabledHint': 'Reiseerinnerungen sind deaktiviert. Aktivieren Sie sie unter Admin > Einstellungen > Benachrichtigungen.',
|
||
'common.update': 'Aktualisieren',
|
||
'common.change': 'Ändern',
|
||
'common.uploading': 'Hochladen…',
|
||
'common.backToPlanning': 'Zurück zur Planung',
|
||
'common.reset': 'Zurücksetzen',
|
||
|
||
// Navbar
|
||
'nav.trip': 'Reise',
|
||
'nav.share': 'Teilen',
|
||
'nav.settings': 'Einstellungen',
|
||
'nav.admin': 'Admin',
|
||
'nav.logout': 'Abmelden',
|
||
'nav.lightMode': 'Heller Modus',
|
||
'nav.darkMode': 'Dunkler Modus',
|
||
'nav.autoMode': 'Automatischer Modus',
|
||
'nav.administrator': 'Administrator',
|
||
|
||
// Dashboard
|
||
'dashboard.title': 'Meine Reisen',
|
||
'dashboard.subtitle.loading': 'Reisen werden geladen...',
|
||
'dashboard.subtitle.trips': '{count} Reisen ({archived} archiviert)',
|
||
'dashboard.subtitle.empty': 'Starte deine erste Reise',
|
||
'dashboard.subtitle.activeOne': '{count} aktive Reise',
|
||
'dashboard.subtitle.activeMany': '{count} aktive Reisen',
|
||
'dashboard.subtitle.archivedSuffix': ' · {count} archiviert',
|
||
'dashboard.newTrip': 'Neue Reise',
|
||
'dashboard.gridView': 'Kachelansicht',
|
||
'dashboard.listView': 'Listenansicht',
|
||
'dashboard.currency': 'Währung',
|
||
'dashboard.timezone': 'Zeitzonen',
|
||
'dashboard.localTime': 'Lokal',
|
||
'dashboard.timezoneCustomTitle': 'Eigene Zeitzone',
|
||
'dashboard.timezoneCustomLabelPlaceholder': 'Bezeichnung (optional)',
|
||
'dashboard.timezoneCustomTzPlaceholder': 'z.B. America/New_York',
|
||
'dashboard.timezoneCustomAdd': 'Hinzufügen',
|
||
'dashboard.timezoneCustomErrorEmpty': 'Zeitzone eingeben',
|
||
'dashboard.timezoneCustomErrorInvalid': 'Ungültige Zeitzone. Format: Europe/Berlin',
|
||
'dashboard.timezoneCustomErrorDuplicate': 'Bereits hinzugefügt',
|
||
'dashboard.emptyTitle': 'Noch keine Reisen',
|
||
'dashboard.emptyText': 'Erstelle deine erste Reise und beginne mit der Planung von Orten, Tagesabläufen und Packlisten.',
|
||
'dashboard.emptyButton': 'Erste Reise erstellen',
|
||
'dashboard.nextTrip': 'Nächste Reise',
|
||
'dashboard.shared': 'Geteilt',
|
||
'dashboard.sharedBy': 'Geteilt von {name}',
|
||
'dashboard.days': 'Tage',
|
||
'dashboard.places': 'Orte',
|
||
'dashboard.members': 'Reise-Buddies',
|
||
'dashboard.archive': 'Archivieren',
|
||
'dashboard.copyTrip': 'Kopieren',
|
||
'dashboard.copySuffix': 'Kopie',
|
||
'dashboard.restore': 'Wiederherstellen',
|
||
'dashboard.archived': 'Archiviert',
|
||
'dashboard.status.ongoing': 'Laufend',
|
||
'dashboard.status.today': 'Heute',
|
||
'dashboard.status.tomorrow': 'Morgen',
|
||
'dashboard.status.past': 'Vergangen',
|
||
'dashboard.status.daysLeft': 'Noch {count} Tage',
|
||
'dashboard.toast.loadError': 'Fehler beim Laden der Reisen',
|
||
'dashboard.toast.created': 'Reise erfolgreich erstellt!',
|
||
'dashboard.toast.createError': 'Fehler beim Erstellen',
|
||
'dashboard.toast.updated': 'Reise aktualisiert!',
|
||
'dashboard.toast.updateError': 'Fehler beim Aktualisieren',
|
||
'dashboard.toast.deleted': 'Reise gelöscht',
|
||
'dashboard.toast.deleteError': 'Fehler beim Löschen',
|
||
'dashboard.toast.archived': 'Reise archiviert',
|
||
'dashboard.toast.archiveError': 'Fehler beim Archivieren',
|
||
'dashboard.toast.restored': 'Reise wiederhergestellt',
|
||
'dashboard.toast.restoreError': 'Fehler beim Wiederherstellen',
|
||
'dashboard.toast.copied': 'Reise kopiert!',
|
||
'dashboard.toast.copyError': 'Fehler beim Kopieren der Reise',
|
||
'dashboard.confirm.delete': 'Reise "{title}" löschen? Alle Orte und Pläne werden unwiderruflich gelöscht.',
|
||
'dashboard.editTrip': 'Reise bearbeiten',
|
||
'dashboard.createTrip': 'Neue Reise erstellen',
|
||
'dashboard.tripTitle': 'Titel',
|
||
'dashboard.tripTitlePlaceholder': 'z.B. Sommer in Japan',
|
||
'dashboard.tripDescription': 'Beschreibung',
|
||
'dashboard.tripDescriptionPlaceholder': 'Worum geht es bei dieser Reise?',
|
||
'dashboard.startDate': 'Startdatum',
|
||
'dashboard.endDate': 'Enddatum',
|
||
'dashboard.dayCount': 'Anzahl Tage',
|
||
'dashboard.dayCountHint': 'Wie viele Tage geplant werden sollen, wenn kein Reisezeitraum gesetzt ist.',
|
||
'dashboard.noDateHint': 'Kein Datum gesetzt — es werden 7 Standardtage erstellt. Du kannst das jederzeit ändern.',
|
||
'dashboard.coverImage': 'Titelbild',
|
||
'dashboard.addCoverImage': 'Titelbild hinzufügen (oder per Drag & Drop)',
|
||
'dashboard.addMembers': 'Reisebegleiter',
|
||
'dashboard.addMember': 'Mitglied hinzufügen',
|
||
'dashboard.coverSaved': 'Titelbild gespeichert',
|
||
'dashboard.coverUploadError': 'Fehler beim Hochladen',
|
||
'dashboard.coverRemoveError': 'Fehler beim Entfernen',
|
||
'dashboard.titleRequired': 'Titel ist erforderlich',
|
||
'dashboard.endDateError': 'Enddatum muss nach dem Startdatum liegen',
|
||
|
||
// Settings
|
||
'settings.title': 'Einstellungen',
|
||
'settings.subtitle': 'Konfigurieren Sie Ihre persönlichen Einstellungen',
|
||
'settings.tabs.display': 'Anzeige',
|
||
'settings.tabs.map': 'Karte',
|
||
'settings.tabs.notifications': 'Benachrichtigungen',
|
||
'settings.tabs.integrations': 'Integrationen',
|
||
'settings.tabs.account': 'Konto',
|
||
'settings.tabs.about': 'Über',
|
||
'settings.map': 'Karte',
|
||
'settings.mapTemplate': 'Karten-Vorlage',
|
||
'settings.mapTemplatePlaceholder.select': 'Vorlage auswählen...',
|
||
'settings.mapDefaultHint': 'Leer lassen für OpenStreetMap (Standard)',
|
||
'settings.mapTemplatePlaceholder': 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||
'settings.mapHint': 'URL-Template für die Kartenkacheln',
|
||
'settings.latitude': 'Breitengrad',
|
||
'settings.longitude': 'Längengrad',
|
||
'settings.saveMap': 'Karte speichern',
|
||
'settings.apiKeys': 'API-Schlüssel',
|
||
'settings.mapsKey': 'Google Maps API-Schlüssel',
|
||
'settings.mapsKeyHint': 'Für Ortsuche. Benötigt Places API (New). Erhalten unter console.cloud.google.com',
|
||
'settings.weatherKey': 'OpenWeatherMap API-Schlüssel',
|
||
'settings.weatherKeyHint': 'Für Wetterdaten. Kostenlos unter openweathermap.org/api',
|
||
'settings.keyPlaceholder': 'Schlüssel eingeben...',
|
||
'settings.configured': 'Konfiguriert',
|
||
'settings.saveKeys': 'Schlüssel speichern',
|
||
'settings.display': 'Darstellung',
|
||
'settings.colorMode': 'Farbmodus',
|
||
'settings.light': 'Hell',
|
||
'settings.dark': 'Dunkel',
|
||
'settings.auto': 'Automatisch',
|
||
'settings.language': 'Sprache',
|
||
'settings.temperature': 'Temperatureinheit',
|
||
'settings.timeFormat': 'Zeitformat',
|
||
'settings.routeCalculation': 'Routenberechnung',
|
||
'settings.blurBookingCodes': 'Buchungscodes verbergen',
|
||
'settings.notifications': 'Benachrichtigungen',
|
||
'settings.notifyTripInvite': 'Trip-Einladungen',
|
||
'settings.notifyBookingChange': 'Buchungsänderungen',
|
||
'settings.notifyTripReminder': 'Trip-Erinnerungen',
|
||
'settings.notifyVacayInvite': 'Vacay Fusion-Einladungen',
|
||
'settings.notifyPhotosShared': 'Geteilte Fotos (Immich)',
|
||
'settings.notifyCollabMessage': 'Chat-Nachrichten (Collab)',
|
||
'settings.notifyPackingTagged': 'Packliste: Zuweisungen',
|
||
'settings.notifyWebhook': 'Webhook-Benachrichtigungen',
|
||
'settings.notificationsDisabled': 'Benachrichtigungen sind nicht konfiguriert. Bitten Sie einen Administrator, E-Mail- oder Webhook-Benachrichtungen zu aktivieren.',
|
||
'settings.notificationsActive': 'Aktiver Kanal',
|
||
'settings.notificationsManagedByAdmin': 'Benachrichtigungsereignisse werden vom Administrator konfiguriert.',
|
||
'admin.notifications.title': 'Benachrichtigungen',
|
||
'admin.notifications.hint': 'Wählen Sie einen Benachrichtigungskanal. Es kann nur einer gleichzeitig aktiv sein.',
|
||
'admin.notifications.none': 'Deaktiviert',
|
||
'admin.notifications.email': 'E-Mail (SMTP)',
|
||
'admin.notifications.webhook': 'Webhook',
|
||
'admin.notifications.events': 'Benachrichtigungsereignisse',
|
||
'admin.notifications.eventsHint': 'Wähle, welche Ereignisse Benachrichtigungen für alle Benutzer auslösen.',
|
||
'admin.notifications.configureFirst': 'Konfiguriere zuerst die SMTP- oder Webhook-Einstellungen unten, dann aktiviere die Events.',
|
||
'admin.notifications.save': 'Benachrichtigungseinstellungen speichern',
|
||
'admin.notifications.saved': 'Benachrichtigungseinstellungen gespeichert',
|
||
'admin.notifications.testWebhook': 'Test-Webhook senden',
|
||
'admin.notifications.testWebhookSuccess': 'Test-Webhook erfolgreich gesendet',
|
||
'admin.notifications.testWebhookFailed': 'Test-Webhook fehlgeschlagen',
|
||
'admin.smtp.title': 'E-Mail & Benachrichtigungen',
|
||
'admin.smtp.hint': 'SMTP-Konfiguration zum Versenden von E-Mail-Benachrichtigungen.',
|
||
'admin.smtp.testButton': 'Test-E-Mail senden',
|
||
'admin.webhook.hint': 'Benachrichtigungen an einen externen Webhook senden (Discord, Slack usw.).',
|
||
'admin.smtp.testSuccess': 'Test-E-Mail erfolgreich gesendet',
|
||
'admin.smtp.testFailed': 'Test-E-Mail fehlgeschlagen',
|
||
'dayplan.icsTooltip': 'Kalender exportieren (ICS)',
|
||
'share.linkTitle': 'Öffentlicher Link',
|
||
'share.linkHint': 'Erstelle einen Link den jeder ohne Login nutzen kann, um diese Reise anzuschauen. Nur lesen — keine Bearbeitung möglich.',
|
||
'share.createLink': 'Link erstellen',
|
||
'share.deleteLink': 'Link löschen',
|
||
'share.createError': 'Link konnte nicht erstellt werden',
|
||
'common.copy': 'Kopieren',
|
||
'common.copied': 'Kopiert',
|
||
'share.permMap': 'Karte & Plan',
|
||
'share.permBookings': 'Buchungen',
|
||
'share.permPacking': 'Packliste',
|
||
'shared.expired': 'Link abgelaufen oder ungültig',
|
||
'shared.expiredHint': 'Dieser geteilte Reise-Link ist nicht mehr aktiv.',
|
||
'shared.readOnly': 'Nur-Lesen Ansicht',
|
||
'shared.tabPlan': 'Plan',
|
||
'shared.tabBookings': 'Buchungen',
|
||
'shared.tabPacking': 'Packliste',
|
||
'shared.tabBudget': 'Budget',
|
||
'shared.tabChat': 'Chat',
|
||
'shared.days': 'Tage',
|
||
'shared.places': 'Orte',
|
||
'shared.other': 'Sonstige',
|
||
'shared.totalBudget': 'Gesamtbudget',
|
||
'shared.messages': 'Nachrichten',
|
||
'shared.sharedVia': 'Geteilt über',
|
||
'shared.confirmed': 'Bestätigt',
|
||
'shared.pending': 'Ausstehend',
|
||
'share.permBudget': 'Budget',
|
||
'share.permCollab': 'Chat',
|
||
'settings.on': 'An',
|
||
'settings.off': 'Aus',
|
||
'settings.mcp.title': 'MCP-Konfiguration',
|
||
'settings.mcp.endpoint': 'MCP-Endpunkt',
|
||
'settings.mcp.clientConfig': 'Client-Konfiguration',
|
||
'settings.mcp.clientConfigHint': 'Ersetze <your_token> durch ein API-Token aus der Liste unten. Der Pfad zu npx muss ggf. für dein System angepasst werden (z. B. C:\\PROGRA~1\\nodejs\\npx.cmd unter Windows).',
|
||
'settings.mcp.copy': 'Kopieren',
|
||
'settings.mcp.copied': 'Kopiert!',
|
||
'settings.mcp.apiTokens': 'API-Tokens',
|
||
'settings.mcp.createToken': 'Neuen Token erstellen',
|
||
'settings.mcp.noTokens': 'Noch keine Tokens. Erstelle einen, um MCP-Clients zu verbinden.',
|
||
'settings.mcp.tokenCreatedAt': 'Erstellt',
|
||
'settings.mcp.tokenUsedAt': 'Verwendet',
|
||
'settings.mcp.deleteTokenTitle': 'Token löschen',
|
||
'settings.mcp.deleteTokenMessage': 'Dieser Token wird sofort ungültig. Jeder MCP-Client, der ihn verwendet, verliert den Zugang.',
|
||
'settings.mcp.modal.createTitle': 'API-Token erstellen',
|
||
'settings.mcp.modal.tokenName': 'Token-Name',
|
||
'settings.mcp.modal.tokenNamePlaceholder': 'z. B. Claude Desktop, Arbeits-Laptop',
|
||
'settings.mcp.modal.creating': 'Wird erstellt…',
|
||
'settings.mcp.modal.create': 'Token erstellen',
|
||
'settings.mcp.modal.createdTitle': 'Token erstellt',
|
||
'settings.mcp.modal.createdWarning': 'Dieser Token wird nur einmal angezeigt. Kopiere und speichere ihn jetzt — er kann nicht wiederhergestellt werden.',
|
||
'settings.mcp.modal.done': 'Fertig',
|
||
'settings.mcp.toast.created': 'Token erstellt',
|
||
'settings.mcp.toast.createError': 'Token konnte nicht erstellt werden',
|
||
'settings.mcp.toast.deleted': 'Token gelöscht',
|
||
'settings.mcp.toast.deleteError': 'Token konnte nicht gelöscht werden',
|
||
'settings.account': 'Konto',
|
||
'settings.about': 'Über',
|
||
'settings.about.reportBug': 'Bug melden',
|
||
'settings.about.reportBugHint': 'Problem gefunden? Melde es uns',
|
||
'settings.about.featureRequest': 'Feature vorschlagen',
|
||
'settings.about.featureRequestHint': 'Schlage ein neues Feature vor',
|
||
'settings.about.wikiHint': 'Dokumentation & Anleitungen',
|
||
'settings.about.description': 'TREK ist ein selbst gehosteter Reiseplaner, der dir hilft, deine Trips von der ersten Idee bis zur letzten Erinnerung zu organisieren. Tagesplanung, Budget, Packlisten, Fotos und vieles mehr — alles an einem Ort, auf deinem eigenen Server.',
|
||
'settings.about.madeWith': 'Entwickelt mit',
|
||
'settings.about.madeBy': 'von Maurice und einer wachsenden Open-Source-Community.',
|
||
'settings.username': 'Benutzername',
|
||
'settings.email': 'E-Mail',
|
||
'settings.role': 'Rolle',
|
||
'settings.roleAdmin': 'Administrator',
|
||
'settings.oidcLinked': 'Verknüpft mit',
|
||
'settings.changePassword': 'Passwort ändern',
|
||
'settings.mustChangePassword': 'Sie müssen Ihr Passwort ändern, bevor Sie fortfahren können. Bitte legen Sie unten ein neues Passwort fest.',
|
||
'settings.currentPassword': 'Aktuelles Passwort',
|
||
'settings.currentPasswordRequired': 'Aktuelles Passwort wird benötigt',
|
||
'settings.newPassword': 'Neues Passwort',
|
||
'settings.confirmPassword': 'Neues Passwort bestätigen',
|
||
'settings.updatePassword': 'Passwort aktualisieren',
|
||
'settings.passwordRequired': 'Bitte aktuelles und neues Passwort eingeben',
|
||
'settings.passwordTooShort': 'Passwort muss mindestens 8 Zeichen lang sein',
|
||
'settings.passwordMismatch': 'Passwörter stimmen nicht überein',
|
||
'settings.passwordWeak': 'Passwort muss Groß-, Kleinbuchstaben, eine Zahl und ein Sonderzeichen enthalten',
|
||
'settings.passwordChanged': 'Passwort erfolgreich geändert',
|
||
'settings.deleteAccount': 'Löschen',
|
||
'settings.deleteAccountTitle': 'Account wirklich löschen?',
|
||
'settings.deleteAccountWarning': 'Dein Account und alle deine Reisen, Orte und Dateien werden unwiderruflich gelöscht. Diese Aktion kann nicht rückgängig gemacht werden.',
|
||
'settings.deleteAccountConfirm': 'Endgültig löschen',
|
||
'settings.deleteBlockedTitle': 'Löschung nicht möglich',
|
||
'settings.deleteBlockedMessage': 'Du bist der einzige Administrator. Ernenne zuerst einen anderen Benutzer zum Admin, bevor du deinen Account löschen kannst.',
|
||
'settings.roleUser': 'Benutzer',
|
||
'settings.saveProfile': 'Speichern',
|
||
'settings.toast.mapSaved': 'Karteneinstellungen gespeichert',
|
||
'settings.toast.keysSaved': 'API-Schlüssel gespeichert',
|
||
'settings.toast.displaySaved': 'Anzeigeeinstellungen gespeichert',
|
||
'settings.toast.profileSaved': 'Profil aktualisiert',
|
||
'settings.uploadAvatar': 'Profilbild hochladen',
|
||
'settings.removeAvatar': 'Profilbild entfernen',
|
||
'settings.avatarUploaded': 'Profilbild aktualisiert',
|
||
'settings.avatarRemoved': 'Profilbild entfernt',
|
||
'settings.avatarError': 'Fehler beim Hochladen',
|
||
'settings.mfa.title': 'Zwei-Faktor-Authentifizierung (2FA)',
|
||
'settings.mfa.description': 'Zusätzlicher Schritt bei der Anmeldung mit E-Mail und Passwort. Nutze eine Authenticator-App (Google Authenticator, Authy, …).',
|
||
'settings.mfa.requiredByPolicy': 'Dein Administrator verlangt Zwei-Faktor-Authentifizierung. Richte unten eine Authenticator-App ein, bevor du fortfährst.',
|
||
'settings.mfa.backupTitle': 'Backup-Codes',
|
||
'settings.mfa.backupDescription': 'Verwende diese Einmal-Codes, wenn du keinen Zugriff mehr auf deine Authenticator-App hast.',
|
||
'settings.mfa.backupWarning': 'Jetzt speichern. Jeder Code kann nur einmal verwendet werden.',
|
||
'settings.mfa.backupCopy': 'Codes kopieren',
|
||
'settings.mfa.backupDownload': 'TXT herunterladen',
|
||
'settings.mfa.backupPrint': 'Drucken / PDF',
|
||
'settings.mfa.backupCopied': 'Backup-Codes kopiert',
|
||
'settings.mfa.enabled': '2FA ist für dein Konto aktiv.',
|
||
'settings.mfa.disabled': '2FA ist nicht aktiviert.',
|
||
'settings.mfa.setup': 'Authenticator einrichten',
|
||
'settings.mfa.scanQr': 'QR-Code mit der App scannen oder den Schlüssel manuell eingeben.',
|
||
'settings.mfa.secretLabel': 'Geheimer Schlüssel (manuell)',
|
||
'settings.mfa.codePlaceholder': '6-stelliger Code',
|
||
'settings.mfa.enable': '2FA aktivieren',
|
||
'settings.mfa.cancelSetup': 'Abbrechen',
|
||
'settings.mfa.disableTitle': '2FA deaktivieren',
|
||
'settings.mfa.disableHint': 'Passwort und einen aktuellen Code aus der Authenticator-App eingeben.',
|
||
'settings.mfa.disable': '2FA deaktivieren',
|
||
'settings.mfa.toastEnabled': 'Zwei-Faktor-Authentifizierung aktiviert',
|
||
'settings.mfa.toastDisabled': 'Zwei-Faktor-Authentifizierung deaktiviert',
|
||
'settings.mfa.demoBlocked': 'In der Demo nicht verfügbar',
|
||
|
||
// Login
|
||
'login.error': 'Anmeldung fehlgeschlagen. Bitte Zugangsdaten prüfen.',
|
||
'login.tagline': 'Deine Reisen.\nDein Plan.',
|
||
'login.description': 'Plane Reisen gemeinsam mit interaktiven Karten, Budgets und Echtzeit-Sync.',
|
||
'login.features.maps': 'Interaktive Karten',
|
||
'login.features.mapsDesc': 'Google Places, Routen & Clustering',
|
||
'login.features.realtime': 'Echtzeit-Sync',
|
||
'login.features.realtimeDesc': 'Gemeinsam planen via WebSocket',
|
||
'login.features.budget': 'Budget-Tracking',
|
||
'login.features.budgetDesc': 'Kategorien, Diagramme & Pro-Kopf',
|
||
'login.features.collab': 'Zusammenarbeit',
|
||
'login.features.collabDesc': 'Multi-User mit geteilten Reisen',
|
||
'login.features.packing': 'Packlisten',
|
||
'login.features.packingDesc': 'Kategorien & Fortschritt',
|
||
'login.features.bookings': 'Buchungen',
|
||
'login.features.bookingsDesc': 'Flüge, Hotels, Restaurants & mehr',
|
||
'login.features.files': 'Dokumente',
|
||
'login.features.filesDesc': 'Dateien hochladen & verwalten',
|
||
'login.features.routes': 'Routenoptimierung',
|
||
'login.features.routesDesc': 'Auto-Optimierung & Google Maps Export',
|
||
'login.selfHosted': 'Self-hosted \u00B7 Open Source \u00B7 Deine Daten bleiben bei dir',
|
||
'login.title': 'Anmelden',
|
||
'login.subtitle': 'Willkommen zurück',
|
||
'login.signingIn': 'Anmelden…',
|
||
'login.signIn': 'Anmelden',
|
||
'login.createAdmin': 'Admin-Konto erstellen',
|
||
'login.createAdminHint': 'Erstelle das erste Admin-Konto für TREK.',
|
||
'login.setNewPassword': 'Neues Passwort festlegen',
|
||
'login.setNewPasswordHint': 'Sie müssen Ihr Passwort ändern, bevor Sie fortfahren können.',
|
||
'login.createAccount': 'Konto erstellen',
|
||
'login.createAccountHint': 'Neues Konto registrieren.',
|
||
'login.creating': 'Erstelle…',
|
||
'login.noAccount': 'Noch kein Konto?',
|
||
'login.hasAccount': 'Bereits ein Konto?',
|
||
'login.register': 'Registrieren',
|
||
'login.emailPlaceholder': 'deine@email.de',
|
||
'login.username': 'Benutzername',
|
||
'login.oidc.registrationDisabled': 'Registrierung ist deaktiviert. Kontaktiere den Administrator.',
|
||
'login.oidc.noEmail': 'Keine E-Mail vom Provider erhalten.',
|
||
'login.oidc.tokenFailed': 'Authentifizierung fehlgeschlagen.',
|
||
'login.oidc.invalidState': 'Ungültige Sitzung. Bitte erneut versuchen.',
|
||
'login.demoFailed': 'Demo-Login fehlgeschlagen',
|
||
'login.oidcSignIn': 'Anmelden mit {name}',
|
||
'login.oidcOnly': 'Passwort-Authentifizierung ist deaktiviert. Bitte melde dich über deinen SSO-Anbieter an.',
|
||
'login.oidcLoggedOut': 'Du wurdest abgemeldet. Melde dich erneut über deinen SSO-Anbieter an.',
|
||
'login.demoHint': 'Demo ausprobieren — ohne Registrierung',
|
||
'login.mfaTitle': 'Zwei-Faktor-Authentifizierung',
|
||
'login.mfaSubtitle': 'Gib den 6-stelligen Code aus deiner Authenticator-App ein.',
|
||
'login.mfaCodeLabel': 'Bestätigungscode',
|
||
'login.mfaCodeRequired': 'Bitte den Code aus der Authenticator-App eingeben.',
|
||
'login.mfaHint': 'Google Authenticator, Authy oder eine andere TOTP-App öffnen.',
|
||
'login.mfaBack': '← Zurück zur Anmeldung',
|
||
'login.mfaVerify': 'Bestätigen',
|
||
|
||
// Register
|
||
'register.passwordMismatch': 'Passwörter stimmen nicht überein',
|
||
'register.passwordTooShort': 'Passwort muss mindestens 8 Zeichen lang sein',
|
||
'register.failed': 'Registrierung fehlgeschlagen',
|
||
'register.getStarted': 'Jetzt starten',
|
||
'register.subtitle': 'Erstellen Sie ein Konto und beginnen Sie, Ihre Traumreisen zu planen.',
|
||
'register.feature1': 'Unbegrenzte Reisepläne',
|
||
'register.feature2': 'Interaktive Kartenansicht',
|
||
'register.feature3': 'Orte und Kategorien verwalten',
|
||
'register.feature4': 'Reservierungen tracken',
|
||
'register.feature5': 'Packlisten erstellen',
|
||
'register.feature6': 'Fotos und Dateien speichern',
|
||
'register.createAccount': 'Konto erstellen',
|
||
'register.startPlanning': 'Beginnen Sie Ihre Reiseplanung',
|
||
'register.minChars': 'Mind. 6 Zeichen',
|
||
'register.confirmPassword': 'Passwort bestätigen',
|
||
'register.repeatPassword': 'Passwort wiederholen',
|
||
'register.registering': 'Registrieren...',
|
||
'register.register': 'Registrieren',
|
||
'register.hasAccount': 'Bereits ein Konto?',
|
||
'register.signIn': 'Anmelden',
|
||
|
||
// Admin
|
||
'admin.title': 'Administration',
|
||
'admin.subtitle': 'Benutzerverwaltung und Systemeinstellungen',
|
||
'admin.tabs.users': 'Benutzer',
|
||
'admin.tabs.categories': 'Kategorien',
|
||
'admin.tabs.backup': 'Backup',
|
||
'admin.tabs.audit': 'Audit',
|
||
'admin.stats.users': 'Benutzer',
|
||
'admin.stats.trips': 'Reisen',
|
||
'admin.stats.places': 'Orte',
|
||
'admin.stats.photos': 'Fotos',
|
||
'admin.stats.files': 'Dateien',
|
||
'admin.table.user': 'Benutzer',
|
||
'admin.table.email': 'E-Mail',
|
||
'admin.table.role': 'Rolle',
|
||
'admin.table.created': 'Erstellt',
|
||
'admin.table.lastLogin': 'Letzter Login',
|
||
'admin.table.actions': 'Aktionen',
|
||
'admin.you': '(Du)',
|
||
'admin.editUser': 'Benutzer bearbeiten',
|
||
'admin.newPassword': 'Neues Passwort',
|
||
'admin.newPasswordHint': 'Leer lassen, um das Passwort nicht zu ändern',
|
||
'admin.deleteUser': 'Benutzer "{name}" löschen? Alle Reisen werden unwiderruflich gelöscht.',
|
||
'admin.deleteUserTitle': 'Benutzer löschen',
|
||
'admin.newPasswordPlaceholder': 'Neues Passwort eingeben…',
|
||
'admin.toast.loadError': 'Fehler beim Laden der Admin-Daten',
|
||
'admin.toast.userUpdated': 'Benutzer aktualisiert',
|
||
'admin.toast.updateError': 'Fehler beim Aktualisieren',
|
||
'admin.toast.userDeleted': 'Benutzer gelöscht',
|
||
'admin.toast.deleteError': 'Fehler beim Löschen',
|
||
'admin.toast.cannotDeleteSelf': 'Eigenes Konto kann nicht gelöscht werden',
|
||
'admin.toast.userCreated': 'Benutzer erstellt',
|
||
'admin.toast.createError': 'Fehler beim Erstellen des Benutzers',
|
||
'admin.toast.fieldsRequired': 'Benutzername, E-Mail und Passwort sind erforderlich',
|
||
'admin.createUser': 'Benutzer anlegen',
|
||
'admin.invite.title': 'Einladungslinks',
|
||
'admin.invite.subtitle': 'Einmal-Links für die Registrierung erstellen',
|
||
'admin.invite.create': 'Link erstellen',
|
||
'admin.invite.createAndCopy': 'Erstellen & kopieren',
|
||
'admin.invite.empty': 'Noch keine Einladungslinks erstellt',
|
||
'admin.invite.maxUses': 'Max. Nutzungen',
|
||
'admin.invite.expiry': 'Gültig für',
|
||
'admin.invite.uses': 'genutzt',
|
||
'admin.invite.expiresAt': 'läuft ab am',
|
||
'admin.invite.createdBy': 'von',
|
||
'admin.invite.active': 'Aktiv',
|
||
'admin.invite.expired': 'Abgelaufen',
|
||
'admin.invite.usedUp': 'Aufgebraucht',
|
||
'admin.invite.copied': 'Einladungslink in Zwischenablage kopiert',
|
||
'admin.invite.copyLink': 'Link kopieren',
|
||
'admin.invite.deleted': 'Einladungslink gelöscht',
|
||
'admin.invite.createError': 'Fehler beim Erstellen des Einladungslinks',
|
||
'admin.invite.deleteError': 'Fehler beim Löschen des Einladungslinks',
|
||
'admin.tabs.settings': 'Einstellungen',
|
||
'admin.allowRegistration': 'Registrierung erlauben',
|
||
'admin.allowRegistrationHint': 'Neue Benutzer können sich selbst registrieren',
|
||
'admin.requireMfa': 'Zwei-Faktor-Authentifizierung (2FA) für alle verlangen',
|
||
'admin.requireMfaHint': 'Benutzer ohne 2FA müssen die Einrichtung unter Einstellungen abschließen, bevor sie die App nutzen können.',
|
||
'admin.apiKeys': 'API-Schlüssel',
|
||
'admin.apiKeysHint': 'Optional. Aktiviert erweiterte Ortsdaten wie Fotos und Wetter.',
|
||
'admin.mapsKey': 'Google Maps API Key',
|
||
'admin.mapsKeyHint': 'Für Ortsuche benötigt. Erstellen unter console.cloud.google.com',
|
||
'admin.mapsKeyHintLong': 'Ohne API Key wird OpenStreetMap für die Ortssuche genutzt. Mit Google API Key können zusätzlich Bilder, Bewertungen und Öffnungszeiten geladen werden. Erstellen unter console.cloud.google.com.',
|
||
'admin.recommended': 'Empfohlen',
|
||
'admin.weatherKey': 'OpenWeatherMap API Key',
|
||
'admin.weatherKeyHint': 'Für Wetterdaten. Kostenlos unter openweathermap.org',
|
||
'admin.validateKey': 'Test',
|
||
'admin.keyValid': 'Verbunden',
|
||
'admin.keyInvalid': 'Ungültig',
|
||
'admin.keySaved': 'API-Schlüssel gespeichert',
|
||
'admin.oidcTitle': 'Single Sign-On (OIDC)',
|
||
'admin.oidcSubtitle': 'Anmeldung über externe Anbieter wie Google, Apple, Authentik oder Keycloak.',
|
||
'admin.oidcDisplayName': 'Anzeigename',
|
||
'admin.oidcIssuer': 'Issuer URL',
|
||
'admin.oidcIssuerHint': 'Die OpenID Connect Issuer URL des Anbieters. z.B. https://accounts.google.com',
|
||
'admin.oidcSaved': 'OIDC-Konfiguration gespeichert',
|
||
'admin.oidcOnlyMode': 'Passwort-Authentifizierung deaktivieren',
|
||
'admin.oidcOnlyModeHint': 'Wenn aktiviert, ist nur SSO-Login erlaubt. Passwort-Login und Registrierung werden blockiert.',
|
||
|
||
// File Types
|
||
'admin.fileTypes': 'Erlaubte Dateitypen',
|
||
'admin.fileTypesHint': 'Konfiguriere welche Dateitypen hochgeladen werden dürfen.',
|
||
'admin.fileTypesFormat': 'Kommagetrennte Endungen (z.B. jpg,png,pdf,doc). Verwende * um alle Typen zu erlauben.',
|
||
'admin.fileTypesSaved': 'Dateityp-Einstellungen gespeichert',
|
||
|
||
// Packing Templates & Bag Tracking
|
||
'admin.bagTracking.title': 'Gepäck-Tracking',
|
||
'admin.bagTracking.subtitle': 'Gewicht und Gepäckstück-Zuordnung für Packlisteneinträge aktivieren',
|
||
'admin.tabs.config': 'Personalisierung',
|
||
'admin.tabs.templates': 'Packvorlagen',
|
||
'admin.packingTemplates.title': 'Packvorlagen',
|
||
'admin.packingTemplates.subtitle': 'Wiederverwendbare Packlisten für deine Reisen erstellen',
|
||
'admin.packingTemplates.create': 'Neue Vorlage',
|
||
'admin.packingTemplates.namePlaceholder': 'Vorlagenname (z.B. Strandurlaub)',
|
||
'admin.packingTemplates.empty': 'Noch keine Vorlagen erstellt',
|
||
'admin.packingTemplates.items': 'Einträge',
|
||
'admin.packingTemplates.categories': 'Kategorien',
|
||
'admin.packingTemplates.itemName': 'Artikelname',
|
||
'admin.packingTemplates.itemCategory': 'Kategorie',
|
||
'admin.packingTemplates.categoryName': 'Kategoriename (z.B. Kleidung)',
|
||
'admin.packingTemplates.addCategory': 'Kategorie hinzufügen',
|
||
'admin.packingTemplates.created': 'Vorlage erstellt',
|
||
'admin.packingTemplates.deleted': 'Vorlage gelöscht',
|
||
'admin.packingTemplates.loadError': 'Vorlagen konnten nicht geladen werden',
|
||
'admin.packingTemplates.createError': 'Vorlage konnte nicht erstellt werden',
|
||
'admin.packingTemplates.deleteError': 'Vorlage konnte nicht gelöscht werden',
|
||
'admin.packingTemplates.saveError': 'Fehler beim Speichern',
|
||
|
||
// Addons
|
||
'admin.tabs.addons': 'Addons',
|
||
'admin.addons.title': 'Addons',
|
||
'admin.addons.subtitle': 'Aktiviere oder deaktiviere Funktionen, um TREK nach deinen Wünschen anzupassen.',
|
||
'admin.addons.catalog.packing.name': 'Listen',
|
||
'admin.addons.catalog.packing.description': 'Packlisten und To-Do-Aufgaben für deine Reisen',
|
||
'admin.addons.catalog.budget.name': 'Budget',
|
||
'admin.addons.catalog.budget.description': 'Ausgaben verfolgen und Reisebudget planen',
|
||
'admin.addons.catalog.documents.name': 'Dokumente',
|
||
'admin.addons.catalog.documents.description': 'Reisedokumente speichern und verwalten',
|
||
'admin.addons.catalog.vacay.name': 'Vacay',
|
||
'admin.addons.catalog.vacay.description': 'Persönlicher Urlaubsplaner mit Kalenderansicht',
|
||
'admin.addons.catalog.atlas.name': 'Atlas',
|
||
'admin.addons.catalog.atlas.description': 'Weltkarte mit besuchten Ländern und Reisestatistiken',
|
||
'admin.addons.catalog.collab.name': 'Collab',
|
||
'admin.addons.catalog.collab.description': 'Echtzeit-Notizen, Umfragen und Chat für die Reiseplanung',
|
||
'admin.addons.catalog.memories.name': 'Fotos (Immich)',
|
||
'admin.addons.catalog.memories.description': 'Reisefotos über deine Immich-Instanz teilen',
|
||
'admin.addons.catalog.mcp.name': 'MCP',
|
||
'admin.addons.catalog.mcp.description': 'Model Context Protocol für die KI-Assistenten-Integration',
|
||
'admin.addons.subtitleBefore': 'Aktiviere oder deaktiviere Funktionen, um ',
|
||
'admin.addons.subtitleAfter': ' nach deinen Wünschen anzupassen.',
|
||
'admin.addons.enabled': 'Aktiviert',
|
||
'admin.addons.disabled': 'Deaktiviert',
|
||
'admin.addons.type.trip': 'Trip',
|
||
'admin.addons.type.global': 'Global',
|
||
'admin.addons.type.integration': 'Integration',
|
||
'admin.addons.tripHint': 'Verfügbar als Tab innerhalb jedes Trips',
|
||
'admin.addons.globalHint': 'Verfügbar als eigenständiger Bereich in der Navigation',
|
||
'admin.addons.integrationHint': 'Backend-Dienste und API-Integrationen ohne eigene Seite',
|
||
'admin.addons.toast.updated': 'Addon aktualisiert',
|
||
'admin.addons.toast.error': 'Addon konnte nicht aktualisiert werden',
|
||
'admin.addons.noAddons': 'Keine Addons verfügbar',
|
||
// Weather info
|
||
'admin.weather.title': 'Wetterdaten',
|
||
'admin.weather.badge': 'Seit 24. März 2026',
|
||
'admin.weather.description': 'TREK nutzt Open-Meteo als Wetterdatenquelle. Open-Meteo ist ein kostenloser, quelloffener Wetterdienst — es wird kein API-Schlüssel benötigt.',
|
||
'admin.weather.forecast': '16-Tage-Vorhersage',
|
||
'admin.weather.forecastDesc': 'Statt bisher 5 Tage (OpenWeatherMap)',
|
||
'admin.weather.climate': 'Historische Klimadaten',
|
||
'admin.weather.climateDesc': 'Durchschnittswerte der letzten 85 Jahre für Tage jenseits der 16-Tage-Vorhersage',
|
||
'admin.weather.requests': '10.000 Anfragen / Tag',
|
||
'admin.weather.requestsDesc': 'Kostenlos, kein API-Schlüssel erforderlich',
|
||
'admin.weather.locationHint': 'Das Wetter wird anhand des ersten Ortes mit Koordinaten im jeweiligen Tag berechnet. Ist kein Ort am Tag eingeplant, wird ein beliebiger Ort aus der Ortsliste als Referenz verwendet.',
|
||
|
||
// MCP Tokens
|
||
'admin.tabs.mcpTokens': 'MCP-Tokens',
|
||
'admin.mcpTokens.title': 'MCP-Tokens',
|
||
'admin.mcpTokens.subtitle': 'API-Tokens aller Benutzer verwalten',
|
||
'admin.mcpTokens.owner': 'Besitzer',
|
||
'admin.mcpTokens.tokenName': 'Token-Name',
|
||
'admin.mcpTokens.created': 'Erstellt',
|
||
'admin.mcpTokens.lastUsed': 'Zuletzt verwendet',
|
||
'admin.mcpTokens.never': 'Nie',
|
||
'admin.mcpTokens.empty': 'Es wurden noch keine MCP-Tokens erstellt',
|
||
'admin.mcpTokens.deleteTitle': 'Token löschen',
|
||
'admin.mcpTokens.deleteMessage': 'Dieser Token wird sofort widerrufen. Der Benutzer verliert den MCP-Zugang über diesen Token.',
|
||
'admin.mcpTokens.deleteSuccess': 'Token gelöscht',
|
||
'admin.mcpTokens.deleteError': 'Token konnte nicht gelöscht werden',
|
||
'admin.mcpTokens.loadError': 'Tokens konnten nicht geladen werden',
|
||
|
||
// GitHub
|
||
'admin.tabs.github': 'GitHub',
|
||
|
||
'admin.audit.subtitle': 'Sicherheitsrelevante und administrative Ereignisse (Backups, Benutzer, MFA, Einstellungen).',
|
||
'admin.audit.empty': 'Noch keine Audit-Einträge.',
|
||
'admin.audit.refresh': 'Aktualisieren',
|
||
'admin.audit.loadMore': 'Mehr laden',
|
||
'admin.audit.showing': '{count} geladen · {total} gesamt',
|
||
'admin.audit.col.time': 'Zeit',
|
||
'admin.audit.col.user': 'Benutzer',
|
||
'admin.audit.col.action': 'Aktion',
|
||
'admin.audit.col.resource': 'Ressource',
|
||
'admin.audit.col.ip': 'IP',
|
||
'admin.audit.col.details': 'Details',
|
||
|
||
'admin.github.title': 'Update-Verlauf',
|
||
'admin.github.subtitle': 'Neueste Updates von {repo}',
|
||
'admin.github.latest': 'Aktuell',
|
||
'admin.github.prerelease': 'Vorabversion',
|
||
'admin.github.showDetails': 'Details anzeigen',
|
||
'admin.github.hideDetails': 'Details ausblenden',
|
||
'admin.github.loadMore': 'Mehr laden',
|
||
'admin.github.loading': 'Wird geladen...',
|
||
'admin.github.error': 'Releases konnten nicht geladen werden',
|
||
'admin.github.by': 'von',
|
||
'admin.github.support': 'Hilft mir, TREK weiterzuentwickeln',
|
||
|
||
'admin.update.available': 'Update verfügbar',
|
||
'admin.update.text': 'TREK {version} ist verfügbar. Du verwendest {current}.',
|
||
'admin.update.button': 'Auf GitHub ansehen',
|
||
'admin.update.install': 'Update installieren',
|
||
'admin.update.confirmTitle': 'Update installieren?',
|
||
'admin.update.confirmText': 'TREK wird von {current} auf {version} aktualisiert. Der Server startet danach automatisch neu.',
|
||
'admin.update.dataInfo': 'Alle Daten (Reisen, Benutzer, API-Schlüssel, Uploads, Vacay, Atlas, Budgets) bleiben erhalten.',
|
||
'admin.update.warning': 'Die App ist während des Neustarts kurz nicht erreichbar.',
|
||
'admin.update.confirm': 'Jetzt aktualisieren',
|
||
'admin.update.installing': 'Wird aktualisiert…',
|
||
'admin.update.success': 'Update installiert! Server startet neu…',
|
||
'admin.update.failed': 'Update fehlgeschlagen',
|
||
'admin.update.backupHint': 'Wir empfehlen, vor dem Update ein Backup zu erstellen und herunterzuladen.',
|
||
'admin.update.backupLink': 'Zum Backup',
|
||
'admin.update.howTo': 'Update-Anleitung',
|
||
'admin.update.dockerText': 'Deine TREK-Instanz läuft in Docker. Um auf {version} zu aktualisieren, führe folgende Befehle auf deinem Server aus:',
|
||
'admin.update.reloadHint': 'Bitte lade die Seite in wenigen Sekunden neu.',
|
||
|
||
// Vacay addon
|
||
'vacay.subtitle': 'Urlaubstage planen und verwalten',
|
||
'vacay.settings': 'Einstellungen',
|
||
'vacay.year': 'Jahr',
|
||
'vacay.addYear': 'Nächstes Jahr hinzufügen',
|
||
'vacay.addPrevYear': 'Vorheriges Jahr hinzufügen',
|
||
'vacay.removeYear': 'Jahr entfernen',
|
||
'vacay.removeYearConfirm': '{year} entfernen?',
|
||
'vacay.removeYearHint': 'Alle Urlaubseinträge und Betriebsferien für dieses Jahr werden unwiderruflich gelöscht.',
|
||
'vacay.remove': 'Entfernen',
|
||
'vacay.persons': 'Personen',
|
||
'vacay.noPersons': 'Keine Personen angelegt',
|
||
'vacay.addPerson': 'Person hinzufügen',
|
||
'vacay.editPerson': 'Person bearbeiten',
|
||
'vacay.removePerson': 'Person entfernen',
|
||
'vacay.removePersonConfirm': '{name} wirklich entfernen?',
|
||
'vacay.removePersonHint': 'Alle Urlaubseinträge dieser Person werden unwiderruflich gelöscht.',
|
||
'vacay.personName': 'Name',
|
||
'vacay.personNamePlaceholder': 'Name eingeben',
|
||
'vacay.color': 'Farbe',
|
||
'vacay.add': 'Hinzufügen',
|
||
'vacay.legend': 'Legende',
|
||
'vacay.publicHoliday': 'Feiertag',
|
||
'vacay.companyHoliday': 'Betriebsferien',
|
||
'vacay.weekend': 'Wochenende',
|
||
'vacay.modeVacation': 'Urlaub',
|
||
'vacay.modeCompany': 'Betriebsferien',
|
||
'vacay.entitlement': 'Urlaubsanspruch',
|
||
'vacay.entitlementDays': 'Tage',
|
||
'vacay.used': 'Weg',
|
||
'vacay.remaining': 'Rest',
|
||
'vacay.carriedOver': 'aus {year}',
|
||
'vacay.blockWeekends': 'Wochenenden sperren',
|
||
'vacay.blockWeekendsHint': 'Verhindert Urlaubseinträge an Wochenendtagen',
|
||
'vacay.weekendDays': 'Wochenendtage',
|
||
'vacay.mon': 'Mo',
|
||
'vacay.tue': 'Di',
|
||
'vacay.wed': 'Mi',
|
||
'vacay.thu': 'Do',
|
||
'vacay.fri': 'Fr',
|
||
'vacay.sat': 'Sa',
|
||
'vacay.sun': 'So',
|
||
'vacay.publicHolidays': 'Feiertage',
|
||
'vacay.publicHolidaysHint': 'Feiertage im Kalender markieren',
|
||
'vacay.selectCountry': 'Land wählen',
|
||
'vacay.selectRegion': 'Region wählen (optional)',
|
||
'vacay.addCalendar': 'Kalender hinzufügen',
|
||
'vacay.calendarLabel': 'Bezeichnung (optional)',
|
||
'vacay.calendarColor': 'Farbe',
|
||
'vacay.noCalendars': 'Noch keine Feiertagskalender angelegt',
|
||
'vacay.companyHolidays': 'Betriebsferien',
|
||
'vacay.companyHolidaysHint': 'Erlaubt das Markieren von unternehmensweiten Feiertagen',
|
||
'vacay.companyHolidaysNoDeduct': 'Betriebsferien werden nicht vom Urlaubskontingent abgezogen.',
|
||
'vacay.carryOver': 'Urlaubsmitnahme',
|
||
'vacay.carryOverHint': 'Resturlaub automatisch ins Folgejahr übertragen',
|
||
'vacay.sharing': 'Teilen',
|
||
'vacay.sharingHint': 'Teile deinen Urlaubsplan mit anderen TREK-Benutzern',
|
||
'vacay.owner': 'Besitzer',
|
||
'vacay.shareEmailPlaceholder': 'E-Mail des TREK-Benutzers',
|
||
'vacay.shareSuccess': 'Plan erfolgreich geteilt',
|
||
'vacay.shareError': 'Plan konnte nicht geteilt werden',
|
||
'vacay.dissolve': 'Fusion auflösen',
|
||
'vacay.dissolveHint': 'Kalender wieder trennen. Deine Einträge bleiben erhalten.',
|
||
'vacay.dissolveAction': 'Auflösen',
|
||
'vacay.dissolved': 'Kalender getrennt',
|
||
'vacay.fusedWith': 'Fusioniert mit',
|
||
'vacay.you': 'du',
|
||
'vacay.noData': 'Keine Daten',
|
||
'vacay.changeColor': 'Farbe ändern',
|
||
'vacay.inviteUser': 'Benutzer einladen',
|
||
'vacay.inviteHint': 'Lade einen anderen TREK-Benutzer ein, um einen gemeinsamen Urlaubskalender zu teilen.',
|
||
'vacay.selectUser': 'Benutzer wählen',
|
||
'vacay.sendInvite': 'Einladung senden',
|
||
'vacay.inviteSent': 'Einladung gesendet',
|
||
'vacay.inviteError': 'Einladung konnte nicht gesendet werden',
|
||
'vacay.pending': 'ausstehend',
|
||
'vacay.noUsersAvailable': 'Keine Benutzer verfügbar',
|
||
'vacay.accept': 'Annehmen',
|
||
'vacay.decline': 'Ablehnen',
|
||
'vacay.acceptFusion': 'Annehmen & Fusionieren',
|
||
'vacay.inviteTitle': 'Fusionsanfrage',
|
||
'vacay.inviteWantsToFuse': 'möchte einen Urlaubskalender mit dir teilen.',
|
||
'vacay.fuseInfo1': 'Beide sehen alle Urlaubseinträge in einem gemeinsamen Kalender.',
|
||
'vacay.fuseInfo2': 'Beide können Einträge für den jeweils anderen erstellen und bearbeiten.',
|
||
'vacay.fuseInfo3': 'Beide können Einträge löschen und den Urlaubsanspruch ändern.',
|
||
'vacay.fuseInfo4': 'Einstellungen wie Feiertage und Betriebsferien werden geteilt.',
|
||
'vacay.fuseInfo5': 'Die Fusion kann jederzeit von beiden Seiten aufgelöst werden. Einträge bleiben erhalten.',
|
||
'nav.myTrips': 'Meine Trips',
|
||
|
||
// Atlas addon
|
||
'atlas.subtitle': 'Dein Reise-Fußabdruck auf der Welt',
|
||
'atlas.countries': 'Länder',
|
||
'atlas.trips': 'Reisen',
|
||
'atlas.places': 'Orte',
|
||
'atlas.unmark': 'Entfernen',
|
||
'atlas.confirmMark': 'Dieses Land als besucht markieren?',
|
||
'atlas.confirmUnmark': 'Dieses Land von der Liste entfernen?',
|
||
'atlas.confirmUnmarkRegion': 'Diese Region von der Liste entfernen?',
|
||
'atlas.markVisited': 'Als besucht markieren',
|
||
'atlas.markVisitedHint': 'Dieses Land zur besuchten Liste hinzufügen',
|
||
'atlas.markRegionVisitedHint': 'Diese Region zur besuchten Liste hinzufügen',
|
||
'atlas.addToBucket': 'Zur Bucket List',
|
||
'atlas.addPoi': 'Ort hinzufügen',
|
||
'atlas.searchCountry': 'Land suchen...',
|
||
'atlas.bucketNamePlaceholder': 'Name (Land, Stadt, Ort...)',
|
||
'atlas.month': 'Monat',
|
||
'atlas.year': 'Jahr',
|
||
'atlas.addToBucketHint': 'Als Wunschziel speichern',
|
||
'atlas.bucketWhen': 'Wann möchtest du dorthin reisen?',
|
||
'atlas.statsTab': 'Statistik',
|
||
'atlas.bucketTab': 'Bucket List',
|
||
'atlas.addBucket': 'Zur Bucket List hinzufügen',
|
||
'atlas.bucketNotesPlaceholder': 'Notizen (optional)',
|
||
'atlas.bucketEmpty': 'Deine Bucket List ist leer',
|
||
'atlas.bucketEmptyHint': 'Füge Orte hinzu, die du besuchen möchtest',
|
||
'atlas.days': 'Tage',
|
||
'atlas.visitedCountries': 'Besuchte Länder',
|
||
'atlas.cities': 'Städte',
|
||
'atlas.noData': 'Noch keine Reisedaten',
|
||
'atlas.noDataHint': 'Erstelle einen Trip und füge Orte hinzu',
|
||
'atlas.lastTrip': 'Letzter Trip',
|
||
'atlas.nextTrip': 'Nächster Trip',
|
||
'atlas.daysLeft': 'Tage',
|
||
'atlas.streak': 'Streak',
|
||
'atlas.years': 'Jahre',
|
||
'atlas.yearInRow': 'Jahr in Folge',
|
||
'atlas.yearsInRow': 'Jahre in Folge',
|
||
'atlas.tripIn': 'Reise in',
|
||
'atlas.tripsIn': 'Reisen in',
|
||
'atlas.since': 'seit',
|
||
'atlas.europe': 'Europa',
|
||
'atlas.asia': 'Asien',
|
||
'atlas.northAmerica': 'N-Amerika',
|
||
'atlas.southAmerica': 'S-Amerika',
|
||
'atlas.africa': 'Afrika',
|
||
'atlas.oceania': 'Ozeanien',
|
||
'atlas.other': 'Andere',
|
||
'atlas.firstVisit': 'Erste Reise',
|
||
'atlas.lastVisitLabel': 'Letzte Reise',
|
||
'atlas.tripSingular': 'Reise',
|
||
'atlas.tripPlural': 'Reisen',
|
||
'atlas.placeVisited': 'Ort besucht',
|
||
'atlas.placesVisited': 'Orte besucht',
|
||
|
||
// Trip Planner
|
||
'trip.tabs.plan': 'Karte',
|
||
'trip.tabs.reservations': 'Buchungen',
|
||
'trip.tabs.reservationsShort': 'Buchung',
|
||
'trip.tabs.packing': 'Liste',
|
||
'trip.tabs.packingShort': 'Liste',
|
||
'trip.tabs.lists': 'Listen',
|
||
'trip.tabs.listsShort': 'Listen',
|
||
'trip.tabs.budget': 'Budget',
|
||
'trip.tabs.files': 'Dateien',
|
||
'trip.loading': 'Reise wird geladen...',
|
||
'trip.loadingPhotos': 'Fotos der Orte werden geladen...',
|
||
'trip.mobilePlan': 'Planung',
|
||
'trip.mobilePlaces': 'Orte',
|
||
'trip.toast.placeUpdated': 'Ort aktualisiert',
|
||
'trip.toast.placeAdded': 'Ort hinzugefügt',
|
||
'trip.toast.placeDeleted': 'Ort gelöscht',
|
||
'trip.toast.selectDay': 'Bitte wähle zuerst einen Tag aus',
|
||
'trip.toast.assignedToDay': 'Ort wurde dem Tag zugewiesen',
|
||
'trip.toast.reorderError': 'Fehler beim Sortieren',
|
||
'trip.toast.reservationUpdated': 'Reservierung aktualisiert',
|
||
'trip.toast.reservationAdded': 'Reservierung hinzugefügt',
|
||
'trip.toast.deleted': 'Gelöscht',
|
||
'trip.confirm.deletePlace': 'Möchtest du diesen Ort wirklich löschen?',
|
||
|
||
// Day Plan Sidebar
|
||
'dayplan.emptyDay': 'Keine Orte für diesen Tag geplant',
|
||
'dayplan.cannotReorderTransport': 'Buchungen mit fester Uhrzeit können nicht verschoben werden',
|
||
'dayplan.confirmRemoveTimeTitle': 'Uhrzeit entfernen?',
|
||
'dayplan.confirmRemoveTimeBody': 'Dieser Ort hat eine feste Uhrzeit ({time}). Durch das Verschieben wird die Uhrzeit entfernt und der Ort kann frei sortiert werden.',
|
||
'dayplan.confirmRemoveTimeAction': 'Uhrzeit entfernen & verschieben',
|
||
'dayplan.cannotDropOnTimed': 'Orte können nicht zwischen zeitgebundene Einträge geschoben werden',
|
||
'dayplan.cannotBreakChronology': 'Die zeitliche Reihenfolge von Uhrzeiten und Buchungen darf nicht verletzt werden',
|
||
'dayplan.addNote': 'Notiz hinzufügen',
|
||
'dayplan.editNote': 'Notiz bearbeiten',
|
||
'dayplan.noteAdd': 'Notiz hinzufügen',
|
||
'dayplan.noteEdit': 'Notiz bearbeiten',
|
||
'dayplan.noteTitle': 'Notiz',
|
||
'dayplan.noteSubtitle': 'Tagesnotiz',
|
||
'dayplan.totalCost': 'Gesamtkosten',
|
||
'dayplan.days': 'Tage',
|
||
'dayplan.dayN': 'Tag {n}',
|
||
'dayplan.calculating': 'Berechne...',
|
||
'dayplan.route': 'Route',
|
||
'dayplan.optimize': 'Optimieren',
|
||
'dayplan.optimized': 'Route optimiert',
|
||
'dayplan.routeError': 'Fehler bei der Routenberechnung',
|
||
'dayplan.toast.needTwoPlaces': 'Mindestens zwei Orte für Routenoptimierung nötig',
|
||
'dayplan.toast.routeOptimized': 'Route optimiert',
|
||
'dayplan.toast.noGeoPlaces': 'Keine Orte mit Koordinaten für Routenberechnung gefunden',
|
||
'dayplan.confirmed': 'Bestätigt',
|
||
'dayplan.pendingRes': 'Ausstehend',
|
||
'dayplan.pdf': 'PDF',
|
||
'dayplan.pdfTooltip': 'Tagesplan als PDF exportieren',
|
||
'dayplan.pdfError': 'Fehler beim PDF-Export',
|
||
|
||
// Places Sidebar
|
||
'places.addPlace': 'Ort/Aktivität hinzufügen',
|
||
'places.importGpx': 'GPX',
|
||
'places.gpxImported': '{count} Orte aus GPX importiert',
|
||
'places.urlResolved': 'Ort aus URL importiert',
|
||
'places.gpxError': 'GPX-Import fehlgeschlagen',
|
||
'places.importGoogleList': 'Google Liste',
|
||
'places.googleListHint': 'Geteilten Google Maps Listen-Link einfügen, um alle Orte zu importieren.',
|
||
'places.googleListImported': '{count} Orte aus "{list}" importiert',
|
||
'places.googleListError': 'Google Maps Liste konnte nicht importiert werden',
|
||
'places.viewDetails': 'Details anzeigen',
|
||
'places.assignToDay': 'Zu welchem Tag hinzufügen?',
|
||
'places.all': 'Alle',
|
||
'places.unplanned': 'Ungeplant',
|
||
'places.search': 'Orte suchen...',
|
||
'places.allCategories': 'Alle Kategorien',
|
||
'places.categoriesSelected': 'Kategorien',
|
||
'places.clearFilter': 'Filter zurücksetzen',
|
||
'places.count': '{count} Orte',
|
||
'places.countSingular': '1 Ort',
|
||
'places.allPlanned': 'Alle Orte sind eingeplant',
|
||
'places.noneFound': 'Keine Orte gefunden',
|
||
'places.editPlace': 'Ort bearbeiten',
|
||
'places.formName': 'Name',
|
||
'places.formNamePlaceholder': 'z.B. Eiffelturm',
|
||
'places.formDescription': 'Beschreibung',
|
||
'places.formDescriptionPlaceholder': 'Kurze Beschreibung...',
|
||
'places.formAddress': 'Adresse',
|
||
'places.formAddressPlaceholder': 'Straße, Stadt, Land',
|
||
'places.formLat': 'Breitengrad (z.B. 48.8566)',
|
||
'places.formLng': 'Längengrad (z.B. 2.3522)',
|
||
'places.formCategory': 'Kategorie',
|
||
'places.noCategory': 'Keine Kategorie',
|
||
'places.categoryNamePlaceholder': 'Kategoriename',
|
||
'places.formTime': 'Uhrzeit',
|
||
'places.startTime': 'Start',
|
||
'places.endTime': 'Ende',
|
||
'places.endTimeBeforeStart': 'Endzeit liegt vor der Startzeit',
|
||
'places.timeCollision': 'Zeitliche Überschneidung mit:',
|
||
'places.formWebsite': 'Website',
|
||
'places.formNotesPlaceholder': 'Persönliche Notizen...',
|
||
'places.formReservation': 'Reservierung',
|
||
'places.reservationNotesPlaceholder': 'Reservierungsnotizen, Bestätigungsnummer...',
|
||
'places.mapsSearchPlaceholder': 'Ortssuche...',
|
||
'places.mapsSearchError': 'Ortssuche fehlgeschlagen.',
|
||
'places.osmHint': 'OpenStreetMap-Suche aktiv (ohne Bilder, Öffnungszeiten, Bewertungen). Für erweiterte Daten Google API Key in den Einstellungen hinterlegen.',
|
||
'places.osmActive': 'Suche via OpenStreetMap (ohne Bilder, Bewertungen & Öffnungszeiten). Google API Key in den Einstellungen hinterlegen für erweiterte Daten.',
|
||
'places.categoryCreateError': 'Fehler beim Erstellen der Kategorie',
|
||
'places.nameRequired': 'Bitte einen Namen eingeben',
|
||
'places.saveError': 'Fehler beim Speichern',
|
||
// Place Inspector
|
||
'inspector.opened': 'Geöffnet',
|
||
'inspector.closed': 'Geschlossen',
|
||
'inspector.openingHours': 'Öffnungszeiten',
|
||
'inspector.showHours': 'Öffnungszeiten anzeigen',
|
||
'inspector.files': 'Dateien',
|
||
'inspector.filesCount': '{count} Dateien',
|
||
'inspector.removeFromDay': 'Vom Tag entfernen',
|
||
'inspector.addToDay': 'Zum Tag hinzufügen',
|
||
'inspector.confirmedRes': 'Bestätigte Reservierung',
|
||
'inspector.pendingRes': 'Ausstehende Reservierung',
|
||
'inspector.google': 'In Google Maps öffnen',
|
||
'inspector.website': 'Webseite öffnen',
|
||
'inspector.addRes': 'Reservierung',
|
||
'inspector.editRes': 'Reservierung bearbeiten',
|
||
'inspector.participants': 'Teilnehmer',
|
||
'inspector.trackStats': 'Streckendaten',
|
||
|
||
// Reservations
|
||
'reservations.title': 'Buchungen',
|
||
'reservations.empty': 'Keine Reservierungen vorhanden',
|
||
'reservations.emptyHint': 'Füge Reservierungen für Flüge, Hotels und mehr hinzu',
|
||
'reservations.add': 'Reservierung hinzufügen',
|
||
'reservations.addManual': 'Manuelle Buchung',
|
||
'reservations.placeHint': 'Tipp: Buchungen werden am besten direkt über einen angelegten Ort erstellt, um sie mit dem Tagesplan zu verknüpfen.',
|
||
'reservations.confirmed': 'Bestätigt',
|
||
'reservations.pending': 'Ausstehend',
|
||
'reservations.summary': '{confirmed} bestätigt, {pending} ausstehend',
|
||
'reservations.fromPlan': 'Aus Planung',
|
||
'reservations.showFiles': 'Dateien anzeigen',
|
||
'reservations.editTitle': 'Reservierung bearbeiten',
|
||
'reservations.status': 'Status',
|
||
'reservations.datetime': 'Datum & Uhrzeit',
|
||
'reservations.startTime': 'Startzeit',
|
||
'reservations.endTime': 'Endzeit',
|
||
'reservations.date': 'Datum',
|
||
'reservations.time': 'Uhrzeit',
|
||
'reservations.timeAlt': 'Uhrzeit (alternativ, z.B. 19:30)',
|
||
'reservations.notes': 'Notizen',
|
||
'reservations.notesPlaceholder': 'Zusätzliche Notizen...',
|
||
'reservations.meta.airline': 'Airline',
|
||
'reservations.meta.flightNumber': 'Flugnr.',
|
||
'reservations.meta.from': 'Von',
|
||
'reservations.meta.to': 'Nach',
|
||
'reservations.meta.trainNumber': 'Zugnr.',
|
||
'reservations.meta.platform': 'Gleis',
|
||
'reservations.meta.seat': 'Sitzplatz',
|
||
'reservations.meta.checkIn': 'Check-in',
|
||
'reservations.meta.checkOut': 'Check-out',
|
||
'reservations.meta.linkAccommodation': 'Unterkunft',
|
||
'reservations.meta.pickAccommodation': 'Mit Unterkunft verknüpfen',
|
||
'reservations.meta.noAccommodation': 'Keine',
|
||
'reservations.meta.hotelPlace': 'Unterkunft',
|
||
'reservations.meta.pickHotel': 'Unterkunft auswählen',
|
||
'reservations.meta.fromDay': 'Von',
|
||
'reservations.meta.toDay': 'Bis',
|
||
'reservations.meta.selectDay': 'Tag wählen',
|
||
'reservations.type.flight': 'Flug',
|
||
'reservations.type.hotel': 'Unterkunft',
|
||
'reservations.type.restaurant': 'Restaurant',
|
||
'reservations.type.train': 'Zug',
|
||
'reservations.type.car': 'Mietwagen',
|
||
'reservations.type.cruise': 'Kreuzfahrt',
|
||
'reservations.type.event': 'Veranstaltung',
|
||
'reservations.type.tour': 'Tour',
|
||
'reservations.type.other': 'Sonstiges',
|
||
'reservations.confirm.delete': 'Möchtest du die Reservierung "{name}" wirklich löschen?',
|
||
'reservations.confirm.deleteTitle': 'Buchung löschen?',
|
||
'reservations.confirm.deleteBody': '"{name}" wird unwiderruflich gelöscht.',
|
||
'reservations.toast.updated': 'Reservierung aktualisiert',
|
||
'reservations.toast.removed': 'Reservierung gelöscht',
|
||
'reservations.toast.saveError': 'Fehler beim Speichern',
|
||
'reservations.toast.updateError': 'Fehler beim Aktualisieren',
|
||
'reservations.toast.deleteError': 'Fehler beim Löschen',
|
||
'reservations.confirm.remove': 'Reservierung für "{name}" entfernen?',
|
||
'reservations.toast.fileUploaded': 'Datei hochgeladen',
|
||
'reservations.toast.uploadError': 'Fehler beim Hochladen',
|
||
'reservations.newTitle': 'Neue Buchung',
|
||
'reservations.bookingType': 'Art der Buchung',
|
||
'reservations.titleLabel': 'Titel',
|
||
'reservations.titlePlaceholder': 'z.B. Lufthansa LH123, Hotel Adlon, ...',
|
||
'reservations.locationAddress': 'Ort / Adresse',
|
||
'reservations.locationPlaceholder': 'Adresse, Flughafen, Hotel...',
|
||
'reservations.confirmationCode': 'Buchungscode',
|
||
'reservations.confirmationPlaceholder': 'z.B. ABC12345',
|
||
'reservations.day': 'Tag',
|
||
'reservations.noDay': 'Kein Tag',
|
||
'reservations.place': 'Ort',
|
||
'reservations.noPlace': 'Kein Ort',
|
||
'reservations.pendingSave': 'wird gespeichert…',
|
||
'reservations.uploading': 'Wird hochgeladen...',
|
||
'reservations.attachFile': 'Datei anhängen',
|
||
'reservations.linkExisting': 'Vorhandene verknüpfen',
|
||
'reservations.linkAssignment': 'Mit Tagesplanung verknüpfen',
|
||
'reservations.pickAssignment': 'Zuordnung aus dem Plan wählen...',
|
||
'reservations.noAssignment': 'Keine Verknüpfung',
|
||
'reservations.price': 'Preis',
|
||
'reservations.budgetCategory': 'Budgetkategorie',
|
||
'reservations.budgetCategoryPlaceholder': 'z.B. Transport, Unterkunft',
|
||
'reservations.budgetCategoryAuto': 'Auto (aus Buchungstyp)',
|
||
'reservations.budgetHint': 'Beim Speichern wird automatisch ein Budgeteintrag erstellt.',
|
||
'reservations.departureDate': 'Abflug',
|
||
'reservations.arrivalDate': 'Ankunft',
|
||
'reservations.departureTime': 'Abflugzeit',
|
||
'reservations.arrivalTime': 'Ankunftszeit',
|
||
'reservations.pickupDate': 'Abholung',
|
||
'reservations.returnDate': 'Rückgabe',
|
||
'reservations.pickupTime': 'Abholzeit',
|
||
'reservations.returnTime': 'Rückgabezeit',
|
||
'reservations.endDate': 'Enddatum',
|
||
'reservations.meta.departureTimezone': 'Abfl. TZ',
|
||
'reservations.meta.arrivalTimezone': 'Ank. TZ',
|
||
'reservations.span.departure': 'Abflug',
|
||
'reservations.span.arrival': 'Ankunft',
|
||
'reservations.span.inTransit': 'Unterwegs',
|
||
'reservations.span.pickup': 'Abholung',
|
||
'reservations.span.return': 'Rückgabe',
|
||
'reservations.span.active': 'Aktiv',
|
||
'reservations.span.start': 'Start',
|
||
'reservations.span.end': 'Ende',
|
||
'reservations.span.ongoing': 'Laufend',
|
||
'reservations.validation.endBeforeStart': 'Enddatum/-zeit muss nach dem Startdatum/-zeit liegen',
|
||
|
||
// Budget
|
||
'budget.title': 'Budget',
|
||
'budget.exportCsv': 'CSV exportieren',
|
||
'budget.emptyTitle': 'Noch kein Budget erstellt',
|
||
'budget.emptyText': 'Erstelle Kategorien und Einträge, um dein Reisebudget zu planen',
|
||
'budget.emptyPlaceholder': 'Kategoriename eingeben...',
|
||
'budget.createCategory': 'Kategorie erstellen',
|
||
'budget.category': 'Kategorie',
|
||
'budget.categoryName': 'Kategoriename',
|
||
'budget.table.name': 'Name',
|
||
'budget.table.total': 'Gesamt',
|
||
'budget.table.persons': 'Personen',
|
||
'budget.table.days': 'Tage',
|
||
'budget.table.perPerson': 'Pro Person',
|
||
'budget.table.perDay': 'Pro Tag',
|
||
'budget.table.perPersonDay': 'P. p / Tag',
|
||
'budget.table.note': 'Notiz',
|
||
'budget.table.date': 'Datum',
|
||
'budget.newEntry': 'Neuer Eintrag',
|
||
'budget.defaultEntry': 'Neuer Eintrag',
|
||
'budget.defaultCategory': 'Neue Kategorie',
|
||
'budget.total': 'Gesamt',
|
||
'budget.totalBudget': 'Gesamtbudget',
|
||
'budget.byCategory': 'Nach Kategorie',
|
||
'budget.editTooltip': 'Klicken zum Bearbeiten',
|
||
'budget.linkedToReservation': 'Verknüpft mit einer Buchung — Name dort bearbeiten',
|
||
'budget.confirm.deleteCategory': 'Möchtest du die Kategorie "{name}" mit {count} Einträgen wirklich löschen?',
|
||
'budget.deleteCategory': 'Kategorie löschen',
|
||
'budget.perPerson': 'Pro Person',
|
||
'budget.paid': 'Bezahlt',
|
||
'budget.open': 'Offen',
|
||
'budget.noMembers': 'Keine Teilnehmer zugewiesen',
|
||
'budget.settlement': 'Ausgleich',
|
||
'budget.settlementInfo': 'Klicke auf ein Mitglied-Bild bei einem Eintrag, um es grün zu markieren — das bedeutet, diese Person hat bezahlt. Der Ausgleich zeigt dann, wer wem wie viel schuldet.',
|
||
'budget.netBalances': 'Netto-Salden',
|
||
|
||
// Files
|
||
'files.title': 'Dateien',
|
||
'files.count': '{count} Dateien',
|
||
'files.countSingular': '1 Datei',
|
||
'files.uploaded': '{count} hochgeladen',
|
||
'files.uploadError': 'Fehler beim Hochladen',
|
||
'files.dropzone': 'Dateien hier ablegen',
|
||
'files.dropzoneHint': 'oder klicken zum Auswählen',
|
||
'files.allowedTypes': 'Bilder, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Max 50 MB',
|
||
'files.uploading': 'Wird hochgeladen...',
|
||
'files.filterAll': 'Alle',
|
||
'files.filterPdf': 'PDFs',
|
||
'files.filterImages': 'Bilder',
|
||
'files.filterDocs': 'Dokumente',
|
||
'files.filterCollab': 'Collab Notizen',
|
||
'files.sourceCollab': 'Aus Collab Notizen',
|
||
'files.empty': 'Keine Dateien vorhanden',
|
||
'files.emptyHint': 'Lade Dateien hoch, um sie mit deiner Reise zu verknüpfen',
|
||
'files.openTab': 'In neuem Tab öffnen',
|
||
'files.confirm.delete': 'Möchtest du diese Datei wirklich löschen?',
|
||
'files.toast.deleted': 'Datei gelöscht',
|
||
'files.toast.deleteError': 'Fehler beim Löschen der Datei',
|
||
'files.sourcePlan': 'Tagesplan',
|
||
'files.sourceBooking': 'Buchung',
|
||
'files.attach': 'Anhängen',
|
||
'files.pasteHint': 'Du kannst auch Bilder aus der Zwischenablage einfügen (Strg+V)',
|
||
'files.trash': 'Papierkorb',
|
||
'files.trashEmpty': 'Papierkorb ist leer',
|
||
'files.emptyTrash': 'Papierkorb leeren',
|
||
'files.restore': 'Wiederherstellen',
|
||
'files.star': 'Markieren',
|
||
'files.unstar': 'Markierung entfernen',
|
||
'files.assign': 'Zuweisen',
|
||
'files.assignTitle': 'Datei zuweisen',
|
||
'files.assignPlace': 'Ort',
|
||
'files.assignBooking': 'Buchung',
|
||
'files.unassigned': 'Nicht zugewiesen',
|
||
'files.unlink': 'Verknüpfung entfernen',
|
||
'files.toast.trashed': 'In den Papierkorb verschoben',
|
||
'files.toast.restored': 'Datei wiederhergestellt',
|
||
'files.toast.trashEmptied': 'Papierkorb geleert',
|
||
'files.toast.assigned': 'Datei zugewiesen',
|
||
'files.toast.assignError': 'Zuweisung fehlgeschlagen',
|
||
'files.toast.restoreError': 'Wiederherstellung fehlgeschlagen',
|
||
'files.confirm.permanentDelete': 'Diese Datei endgültig löschen? Das kann nicht rückgängig gemacht werden.',
|
||
'files.confirm.emptyTrash': 'Alle Dateien im Papierkorb endgültig löschen? Das kann nicht rückgängig gemacht werden.',
|
||
'files.noteLabel': 'Notiz',
|
||
'files.notePlaceholder': 'Notiz hinzufügen...',
|
||
|
||
// Packing
|
||
'packing.title': 'Packliste',
|
||
'packing.empty': 'Packliste ist leer',
|
||
'packing.import': 'Importieren',
|
||
'packing.importTitle': 'Packliste importieren',
|
||
'packing.importHint': 'Ein Eintrag pro Zeile. Format: Kategorie, Name, Gewicht in g (optional), Tasche (optional), checked/unchecked (optional)',
|
||
'packing.importPlaceholder': 'Hygiene, Zahnbürste\nKleidung, T-Shirts, 200\nDokumente, Reisepass, , Handgepäck\nElektronik, Ladekabel, 50, Koffer, checked',
|
||
'packing.importCsv': 'CSV/TXT laden',
|
||
'packing.importAction': '{count} importieren',
|
||
'packing.importSuccess': '{count} Einträge importiert',
|
||
'packing.importError': 'Import fehlgeschlagen',
|
||
'packing.importEmpty': 'Keine Einträge zum Importieren',
|
||
'packing.progress': '{packed} von {total} gepackt ({percent}%)',
|
||
'packing.clearChecked': '{count} abgehakte entfernen',
|
||
'packing.clearCheckedShort': '{count} entfernen',
|
||
'packing.suggestions': 'Vorschläge',
|
||
'packing.suggestionsTitle': 'Vorschläge hinzufügen',
|
||
'packing.allSuggested': 'Alle Vorschläge hinzugefügt',
|
||
'packing.allPacked': 'Alles gepackt!',
|
||
'packing.addPlaceholder': 'Neuen Gegenstand hinzufügen...',
|
||
'packing.categoryPlaceholder': 'Kategorie...',
|
||
'packing.filterAll': 'Alle',
|
||
'packing.filterOpen': 'Offen',
|
||
'packing.filterDone': 'Erledigt',
|
||
'packing.emptyTitle': 'Packliste ist leer',
|
||
'packing.emptyHint': 'Füge Gegenstände hinzu oder nutze die Vorschläge',
|
||
'packing.emptyFiltered': 'Keine Gegenstände in diesem Filter',
|
||
'packing.menuRename': 'Umbenennen',
|
||
'packing.menuCheckAll': 'Alle abhaken',
|
||
'packing.menuUncheckAll': 'Alle Haken entfernen',
|
||
'packing.menuDeleteCat': 'Kategorie löschen',
|
||
'packing.assignUser': 'Benutzer zuweisen',
|
||
'packing.noMembers': 'Keine Mitglieder',
|
||
'packing.addItem': 'Eintrag hinzufügen',
|
||
'packing.addItemPlaceholder': 'Artikelname...',
|
||
'packing.addCategory': 'Kategorie hinzufügen',
|
||
'packing.newCategoryPlaceholder': 'Kategoriename (z.B. Kleidung)',
|
||
'packing.applyTemplate': 'Vorlage anwenden',
|
||
'packing.template': 'Vorlage',
|
||
'packing.templateApplied': '{count} Einträge aus Vorlage hinzugefügt',
|
||
'packing.templateError': 'Vorlage konnte nicht angewendet werden',
|
||
'packing.saveAsTemplate': 'Als Vorlage speichern',
|
||
'packing.templateName': 'Vorlagenname',
|
||
'packing.templateSaved': 'Packliste als Vorlage gespeichert',
|
||
'packing.assignUser': 'Person zuweisen',
|
||
'packing.bags': 'Gepäck',
|
||
'packing.noBag': 'Nicht zugeordnet',
|
||
'packing.totalWeight': 'Gesamtgewicht',
|
||
'packing.bagName': 'Name...',
|
||
'packing.addBag': 'Gepäck hinzufügen',
|
||
'packing.changeCategory': 'Kategorie ändern',
|
||
'packing.confirm.clearChecked': 'Möchtest du {count} abgehakte Gegenstände wirklich entfernen?',
|
||
'packing.confirm.deleteCat': 'Möchtest du die Kategorie "{name}" mit {count} Gegenständen wirklich löschen?',
|
||
'packing.defaultCategory': 'Sonstiges',
|
||
'packing.toast.saveError': 'Fehler beim Speichern',
|
||
'packing.toast.deleteError': 'Fehler beim Löschen',
|
||
'packing.toast.renameError': 'Fehler beim Umbenennen',
|
||
'packing.toast.addError': 'Fehler beim Hinzufügen',
|
||
|
||
// Packing suggestions
|
||
'packing.suggestions.items': [
|
||
{ name: 'Reisepass', category: 'Dokumente' },
|
||
{ name: 'Personalausweis', category: 'Dokumente' },
|
||
{ name: 'Reiseversicherung', category: 'Dokumente' },
|
||
{ name: 'Flugtickets', category: 'Dokumente' },
|
||
{ name: 'Kreditkarte', category: 'Finanzen' },
|
||
{ name: 'Bargeld', category: 'Finanzen' },
|
||
{ name: 'Visum', category: 'Dokumente' },
|
||
{ name: 'T-Shirts', category: 'Kleidung' },
|
||
{ name: 'Hosen', category: 'Kleidung' },
|
||
{ name: 'Unterwäsche', category: 'Kleidung' },
|
||
{ name: 'Socken', category: 'Kleidung' },
|
||
{ name: 'Jacke', category: 'Kleidung' },
|
||
{ name: 'Schlafkleidung', category: 'Kleidung' },
|
||
{ name: 'Badekleidung', category: 'Kleidung' },
|
||
{ name: 'Regenjacke', category: 'Kleidung' },
|
||
{ name: 'Bequeme Schuhe', category: 'Kleidung' },
|
||
{ name: 'Zahnbürste', category: 'Hygiene' },
|
||
{ name: 'Zahnpasta', category: 'Hygiene' },
|
||
{ name: 'Shampoo', category: 'Hygiene' },
|
||
{ name: 'Deo', category: 'Hygiene' },
|
||
{ name: 'Sonnencreme', category: 'Hygiene' },
|
||
{ name: 'Rasierer', category: 'Hygiene' },
|
||
{ name: 'Ladegerät', category: 'Elektronik' },
|
||
{ name: 'Powerbank', category: 'Elektronik' },
|
||
{ name: 'Kopfhörer', category: 'Elektronik' },
|
||
{ name: 'Reiseadapter', category: 'Elektronik' },
|
||
{ name: 'Kamera', category: 'Elektronik' },
|
||
{ name: 'Schmerzmittel', category: 'Gesundheit' },
|
||
{ name: 'Pflaster', category: 'Gesundheit' },
|
||
{ name: 'Desinfektionsmittel', category: 'Gesundheit' },
|
||
],
|
||
|
||
// Members / Sharing
|
||
'members.shareTrip': 'Reise teilen',
|
||
'members.inviteUser': 'Benutzer einladen',
|
||
'members.selectUser': 'Benutzer auswählen…',
|
||
'members.invite': 'Einladen',
|
||
'members.allHaveAccess': 'Alle Benutzer haben bereits Zugriff.',
|
||
'members.access': 'Zugriff',
|
||
'members.person': 'Person',
|
||
'members.persons': 'Personen',
|
||
'members.you': 'du',
|
||
'members.owner': 'Eigentümer',
|
||
'members.leaveTrip': 'Reise verlassen',
|
||
'members.removeAccess': 'Zugriff entfernen',
|
||
'members.confirmLeave': 'Reise verlassen? Du verlierst den Zugriff.',
|
||
'members.confirmRemove': 'Zugriff für diesen Benutzer entfernen?',
|
||
'members.loadError': 'Fehler beim Laden der Mitglieder',
|
||
'members.added': 'hinzugefügt',
|
||
'members.addError': 'Fehler beim Hinzufügen',
|
||
'members.removed': 'Mitglied entfernt',
|
||
'members.removeError': 'Fehler beim Entfernen',
|
||
|
||
// Categories (Admin)
|
||
'categories.title': 'Kategorien',
|
||
'categories.subtitle': 'Kategorien für Orte verwalten',
|
||
'categories.new': 'Neue Kategorie',
|
||
'categories.empty': 'Keine Kategorien vorhanden',
|
||
'categories.namePlaceholder': 'Kategoriename',
|
||
'categories.icon': 'Symbol',
|
||
'categories.color': 'Farbe',
|
||
'categories.customColor': 'Eigene Farbe wählen',
|
||
'categories.preview': 'Vorschau',
|
||
'categories.defaultName': 'Kategorie',
|
||
'categories.update': 'Aktualisieren',
|
||
'categories.create': 'Erstellen',
|
||
'categories.confirm.delete': 'Kategorie löschen? Orte dieser Kategorie werden nicht gelöscht.',
|
||
'categories.toast.loadError': 'Fehler beim Laden der Kategorien',
|
||
'categories.toast.nameRequired': 'Bitte einen Namen eingeben',
|
||
'categories.toast.updated': 'Kategorie aktualisiert',
|
||
'categories.toast.created': 'Kategorie erstellt',
|
||
'categories.toast.saveError': 'Fehler beim Speichern',
|
||
'categories.toast.deleted': 'Kategorie gelöscht',
|
||
'categories.toast.deleteError': 'Fehler beim Löschen',
|
||
|
||
// Backup (Admin)
|
||
'backup.title': 'Datensicherung',
|
||
'backup.subtitle': 'Datenbank und alle hochgeladenen Dateien',
|
||
'backup.refresh': 'Aktualisieren',
|
||
'backup.upload': 'Backup hochladen',
|
||
'backup.uploading': 'Wird hochgeladen…',
|
||
'backup.create': 'Backup erstellen',
|
||
'backup.creating': 'Erstelle…',
|
||
'backup.empty': 'Noch keine Backups vorhanden',
|
||
'backup.createFirst': 'Erstes Backup erstellen',
|
||
'backup.download': 'Herunterladen',
|
||
'backup.restore': 'Wiederherstellen',
|
||
'backup.confirm.restore': 'Backup "{name}" wiederherstellen?\n\nAlle aktuellen Daten werden durch den Backup-Stand ersetzt.',
|
||
'backup.confirm.uploadRestore': 'Backup-Datei "{name}" hochladen und wiederherstellen?\n\nAlle aktuellen Daten werden überschrieben.',
|
||
'backup.confirm.delete': 'Backup "{name}" löschen?',
|
||
'backup.toast.loadError': 'Fehler beim Laden der Backups',
|
||
'backup.toast.created': 'Backup erfolgreich erstellt',
|
||
'backup.toast.createError': 'Fehler beim Erstellen des Backups',
|
||
'backup.toast.restored': 'Backup wiederhergestellt. Seite wird neu geladen…',
|
||
'backup.toast.restoreError': 'Fehler beim Wiederherstellen',
|
||
'backup.toast.uploadError': 'Fehler beim Hochladen',
|
||
'backup.toast.deleted': 'Backup gelöscht',
|
||
'backup.toast.deleteError': 'Fehler beim Löschen',
|
||
'backup.toast.downloadError': 'Download fehlgeschlagen',
|
||
'backup.toast.settingsSaved': 'Auto-Backup Einstellungen gespeichert',
|
||
'backup.toast.settingsError': 'Fehler beim Speichern der Einstellungen',
|
||
'backup.auto.title': 'Auto-Backup',
|
||
'backup.auto.subtitle': 'Automatische Sicherung nach Zeitplan',
|
||
'backup.auto.enable': 'Auto-Backup aktivieren',
|
||
'backup.auto.enableHint': 'Backups werden automatisch nach dem gewählten Zeitplan erstellt',
|
||
'backup.auto.interval': 'Intervall',
|
||
'backup.auto.hour': 'Ausführung um',
|
||
'backup.auto.hourHint': 'Lokale Serverzeit ({format}-Format)',
|
||
'backup.auto.dayOfWeek': 'Wochentag',
|
||
'backup.auto.dayOfMonth': 'Tag des Monats',
|
||
'backup.auto.dayOfMonthHint': 'Auf 1–28 beschränkt, um mit allen Monaten kompatibel zu sein',
|
||
'backup.auto.scheduleSummary': 'Zeitplan',
|
||
'backup.auto.summaryDaily': 'Täglich um {hour}:00',
|
||
'backup.auto.summaryWeekly': 'Jeden {day} um {hour}:00',
|
||
'backup.auto.summaryMonthly': 'Am {day}. jedes Monats um {hour}:00',
|
||
'backup.auto.envLocked': 'Docker',
|
||
'backup.auto.envLockedHint': 'Auto-Backup wird über Docker-Umgebungsvariablen konfiguriert. Ändern Sie Ihre docker-compose.yml und starten Sie den Container neu.',
|
||
'backup.auto.copyEnv': 'Docker-Umgebungsvariablen kopieren',
|
||
'backup.auto.envCopied': 'Docker-Umgebungsvariablen in die Zwischenablage kopiert',
|
||
'backup.auto.keepLabel': 'Alte Backups löschen nach',
|
||
'backup.dow.sunday': 'So',
|
||
'backup.dow.monday': 'Mo',
|
||
'backup.dow.tuesday': 'Di',
|
||
'backup.dow.wednesday': 'Mi',
|
||
'backup.dow.thursday': 'Do',
|
||
'backup.dow.friday': 'Fr',
|
||
'backup.dow.saturday': 'Sa',
|
||
'backup.interval.hourly': 'Stündlich',
|
||
'backup.interval.daily': 'Täglich',
|
||
'backup.interval.weekly': 'Wöchentlich',
|
||
'backup.interval.monthly': 'Monatlich',
|
||
'backup.keep.1day': '1 Tag',
|
||
'backup.keep.3days': '3 Tage',
|
||
'backup.keep.7days': '7 Tage',
|
||
'backup.keep.14days': '14 Tage',
|
||
'backup.keep.30days': '30 Tage',
|
||
'backup.keep.forever': 'Immer behalten',
|
||
|
||
// Photos
|
||
'photos.allDays': 'Alle Tage',
|
||
'photos.noPhotos': 'Noch keine Fotos',
|
||
'photos.uploadHint': 'Lade deine Reisefotos hoch',
|
||
'photos.clickToSelect': 'oder klicken zum Auswählen',
|
||
'photos.linkPlace': 'Ort verknüpfen',
|
||
'photos.noPlace': 'Kein Ort',
|
||
'photos.uploadN': '{n} Foto(s) hochladen',
|
||
|
||
// Backup restore modal
|
||
'backup.restoreConfirmTitle': 'Backup wiederherstellen?',
|
||
'backup.restoreWarning': 'Alle aktuellen Daten (Reisen, Orte, Benutzer, Uploads) werden unwiderruflich durch das Backup ersetzt. Dieser Vorgang kann nicht rückgängig gemacht werden.',
|
||
'backup.restoreTip': 'Tipp: Erstelle zuerst ein Backup des aktuellen Stands, bevor du wiederherstellst.',
|
||
'backup.restoreConfirm': 'Ja, wiederherstellen',
|
||
|
||
// PDF
|
||
'pdf.travelPlan': 'Reiseplan',
|
||
'pdf.planned': 'Eingeplant',
|
||
'pdf.costLabel': 'Kosten EUR',
|
||
'pdf.preview': 'PDF Vorschau',
|
||
'pdf.saveAsPdf': 'Als PDF speichern',
|
||
|
||
// Planner
|
||
'planner.places': 'Orte',
|
||
'planner.bookings': 'Buchungen',
|
||
'planner.packingList': 'Packliste',
|
||
'planner.documents': 'Dokumente',
|
||
'planner.dayPlan': 'Tagesplan',
|
||
'planner.reservations': 'Reservierungen',
|
||
'planner.minTwoPlaces': 'Mindestens 2 Orte mit Koordinaten benötigt',
|
||
'planner.noGeoPlaces': 'Keine Orte mit Koordinaten vorhanden',
|
||
'planner.routeCalculated': 'Route berechnet',
|
||
'planner.routeCalcFailed': 'Route konnte nicht berechnet werden',
|
||
'planner.routeError': 'Fehler bei der Routenberechnung',
|
||
'planner.routeOptimized': 'Route optimiert',
|
||
'planner.reservationUpdated': 'Reservierung aktualisiert',
|
||
'planner.reservationAdded': 'Reservierung hinzugefügt',
|
||
'planner.confirmDeleteReservation': 'Reservierung löschen?',
|
||
'planner.reservationDeleted': 'Reservierung gelöscht',
|
||
'planner.days': 'Tage',
|
||
'planner.allPlaces': 'Alle Orte',
|
||
'planner.totalPlaces': '{n} Orte gesamt',
|
||
'planner.noDaysPlanned': 'Noch keine Tage geplant',
|
||
'planner.editTrip': 'Reise bearbeiten \u2192',
|
||
'planner.placeOne': '1 Ort',
|
||
'planner.placeN': '{n} Orte',
|
||
'planner.addNote': 'Notiz hinzufügen',
|
||
'planner.noEntries': 'Keine Einträge für diesen Tag',
|
||
'planner.addPlace': 'Ort/Aktivität hinzufügen',
|
||
'planner.addPlaceShort': '+ Ort/Aktivität hinzufügen',
|
||
'planner.resPending': 'Reservierung ausstehend · ',
|
||
'planner.resConfirmed': 'Reservierung bestätigt · ',
|
||
'planner.notePlaceholder': 'Notiz\u2026',
|
||
'planner.noteTimePlaceholder': 'Zeit (optional)',
|
||
'planner.noteExamplePlaceholder': 'z.B. S3 um 14:30 ab Hauptbahnhof, Fähre ab Pier 7, Mittagspause\u2026',
|
||
'planner.totalCost': 'Gesamtkosten',
|
||
'planner.searchPlaces': 'Orte suchen\u2026',
|
||
'planner.allCategories': 'Alle Kategorien',
|
||
'planner.noPlacesFound': 'Keine Orte gefunden',
|
||
'planner.addFirstPlace': 'Ersten Ort hinzufügen',
|
||
'planner.noReservations': 'Keine Reservierungen',
|
||
'planner.addFirstReservation': 'Erste Reservierung hinzufügen',
|
||
'planner.new': 'Neu',
|
||
'planner.addToDay': '+ Tag',
|
||
'planner.calculating': 'Berechne\u2026',
|
||
'planner.route': 'Route',
|
||
'planner.optimize': 'Optimieren',
|
||
'planner.openGoogleMaps': 'In Google Maps öffnen',
|
||
'planner.selectDayHint': 'Wähle einen Tag aus der linken Liste um den Tagesplan zu sehen',
|
||
'planner.noPlacesForDay': 'Noch keine Orte für diesen Tag',
|
||
'planner.addPlacesLink': 'Orte hinzufügen \u2192',
|
||
'planner.minTotal': 'Min. gesamt',
|
||
'planner.noReservation': 'Keine Reservierung',
|
||
'planner.removeFromDay': 'Aus Tag entfernen',
|
||
'planner.addToThisDay': 'Zum Tag hinzufügen',
|
||
'planner.overview': 'Gesamtübersicht',
|
||
'planner.noDays': 'Noch keine Tage',
|
||
'planner.editTripToAddDays': 'Reise bearbeiten um Tage hinzuzufügen',
|
||
'planner.dayCount': '{n} Tage',
|
||
'planner.clickToUnlock': 'Klicken zum Entsperren',
|
||
'planner.keepPosition': 'Position bei Routenoptimierung beibehalten',
|
||
'planner.dayDetails': 'Tagesdetails',
|
||
'planner.dayN': 'Tag {n}',
|
||
|
||
// Dashboard Stats
|
||
'stats.countries': 'Länder',
|
||
'stats.cities': 'Städte',
|
||
'stats.trips': 'Reisen',
|
||
'stats.places': 'Orte',
|
||
'stats.worldProgress': 'Weltfortschritt',
|
||
'stats.visited': 'besucht',
|
||
'stats.remaining': 'verbleibend',
|
||
'stats.visitedCountries': 'Besuchte Länder',
|
||
|
||
// Day Detail Panel
|
||
'day.precipProb': 'Regenwahrscheinlichkeit',
|
||
'day.precipitation': 'Niederschlag',
|
||
'day.wind': 'Wind',
|
||
'day.sunrise': 'Sonnenaufgang',
|
||
'day.sunset': 'Sonnenuntergang',
|
||
'day.hourlyForecast': 'Stündliche Vorhersage',
|
||
'day.climateHint': 'Historische Durchschnittswerte — echte Vorhersage verfügbar innerhalb von 16 Tagen vor diesem Datum.',
|
||
'day.noWeather': 'Keine Wetterdaten verfügbar. Füge einen Ort mit Koordinaten hinzu.',
|
||
'day.overview': 'Tagesübersicht',
|
||
'day.accommodation': 'Unterkunft',
|
||
'day.addAccommodation': 'Unterkunft hinzufügen',
|
||
'day.hotelDayRange': 'Auf Tage anwenden',
|
||
'day.noPlacesForHotel': 'Füge zuerst Orte zu deiner Reise hinzu',
|
||
'day.allDays': 'Alle',
|
||
'day.checkIn': 'Check-in',
|
||
'day.checkOut': 'Check-out',
|
||
'day.confirmation': 'Bestätigung',
|
||
'day.editAccommodation': 'Unterkunft bearbeiten',
|
||
'day.reservations': 'Reservierungen',
|
||
|
||
// Photos / Immich
|
||
'memories.title': 'Fotos',
|
||
'memories.notConnected': 'Immich nicht verbunden',
|
||
'memories.notConnectedHint': 'Verbinde deine Immich-Instanz in den Einstellungen, um deine Reisefotos hier zu sehen.',
|
||
'memories.noDates': 'Füge Daten zu deiner Reise hinzu, um Fotos zu laden.',
|
||
'memories.noPhotos': 'Keine Fotos gefunden',
|
||
'memories.noPhotosHint': 'Keine Fotos in Immich für den Zeitraum dieser Reise gefunden.',
|
||
'memories.photosFound': 'Fotos',
|
||
'memories.fromOthers': 'von anderen',
|
||
'memories.sharePhotos': 'Fotos teilen',
|
||
'memories.sharing': 'Wird geteilt',
|
||
'memories.reviewTitle': 'Deine Fotos prüfen',
|
||
'memories.reviewHint': 'Klicke auf Fotos, um sie vom Teilen auszuschließen.',
|
||
'memories.shareCount': '{count} Fotos teilen',
|
||
'memories.immichUrl': 'Immich Server URL',
|
||
'memories.immichApiKey': 'API-Schlüssel',
|
||
'memories.testConnection': 'Verbindung testen',
|
||
'memories.testFirst': 'Verbindung zuerst testen',
|
||
'memories.connected': 'Verbunden',
|
||
'memories.disconnected': 'Nicht verbunden',
|
||
'memories.connectionSuccess': 'Verbindung zu Immich hergestellt',
|
||
'memories.connectionError': 'Verbindung zu Immich fehlgeschlagen',
|
||
'memories.saved': 'Immich-Einstellungen gespeichert',
|
||
'memories.addPhotos': 'Fotos hinzufügen',
|
||
'memories.linkAlbum': 'Album verknüpfen',
|
||
'memories.selectAlbum': 'Immich-Album auswählen',
|
||
'memories.noAlbums': 'Keine Alben gefunden',
|
||
'memories.syncAlbum': 'Album synchronisieren',
|
||
'memories.unlinkAlbum': 'Album trennen',
|
||
'memories.photos': 'Fotos',
|
||
'memories.selectPhotos': 'Fotos aus Immich auswählen',
|
||
'memories.selectHint': 'Tippe auf Fotos um sie auszuwählen.',
|
||
'memories.selected': 'ausgewählt',
|
||
'memories.addSelected': '{count} Fotos hinzufügen',
|
||
'memories.alreadyAdded': 'Hinzugefügt',
|
||
'memories.private': 'Privat',
|
||
'memories.stopSharing': 'Nicht mehr teilen',
|
||
'memories.oldest': 'Älteste zuerst',
|
||
'memories.newest': 'Neueste zuerst',
|
||
'memories.allLocations': 'Alle Orte',
|
||
'memories.tripDates': 'Trip-Zeitraum',
|
||
'memories.allPhotos': 'Alle Fotos',
|
||
'memories.confirmShareTitle': 'Mit Reisebegleitern teilen?',
|
||
'memories.confirmShareHint': '{count} Fotos werden für alle Mitglieder dieses Trips sichtbar. Du kannst einzelne Fotos nachträglich auf privat setzen.',
|
||
'memories.confirmShareButton': 'Fotos teilen',
|
||
|
||
// Collab Addon
|
||
'collab.tabs.chat': 'Chat',
|
||
'collab.tabs.notes': 'Notizen',
|
||
'collab.tabs.polls': 'Umfragen',
|
||
'collab.whatsNext.title': 'Nächste',
|
||
'collab.whatsNext.today': 'Heute',
|
||
'collab.whatsNext.tomorrow': 'Morgen',
|
||
'collab.whatsNext.empty': 'Keine anstehenden Aktivitäten',
|
||
'collab.whatsNext.until': 'bis',
|
||
'collab.whatsNext.emptyHint': 'Aktivitäten mit Uhrzeit erscheinen hier',
|
||
'collab.chat.send': 'Senden',
|
||
'collab.chat.placeholder': 'Nachricht eingeben...',
|
||
'collab.chat.empty': 'Starte die Unterhaltung',
|
||
'collab.chat.emptyHint': 'Nachrichten werden mit allen Reiseteilnehmern geteilt',
|
||
'collab.chat.emptyDesc': 'Teile Ideen, Pläne und Updates mit deiner Reisegruppe',
|
||
'collab.chat.today': 'Heute',
|
||
'collab.chat.yesterday': 'Gestern',
|
||
'collab.chat.deletedMessage': 'hat eine Nachricht gelöscht',
|
||
'collab.chat.reply': 'Antworten',
|
||
'collab.chat.loadMore': 'Ältere Nachrichten laden',
|
||
'collab.chat.justNow': 'gerade eben',
|
||
'collab.chat.minutesAgo': 'vor {n} Min.',
|
||
'collab.chat.hoursAgo': 'vor {n} Std.',
|
||
'collab.notes.title': 'Notizen',
|
||
'collab.notes.new': 'Neue Notiz',
|
||
'collab.notes.empty': 'Noch keine Notizen',
|
||
'collab.notes.emptyHint': 'Halte Ideen und Pläne fest',
|
||
'collab.notes.all': 'Alle',
|
||
'collab.notes.titlePlaceholder': 'Notiztitel',
|
||
'collab.notes.contentPlaceholder': 'Schreibe etwas...',
|
||
'collab.notes.categoryPlaceholder': 'Kategorie',
|
||
'collab.notes.newCategory': 'Neue Kategorie...',
|
||
'collab.notes.category': 'Kategorie',
|
||
'collab.notes.noCategory': 'Keine Kategorie',
|
||
'collab.notes.color': 'Farbe',
|
||
'collab.notes.save': 'Speichern',
|
||
'collab.notes.cancel': 'Abbrechen',
|
||
'collab.notes.edit': 'Bearbeiten',
|
||
'collab.notes.delete': 'Löschen',
|
||
'collab.notes.pin': 'Anheften',
|
||
'collab.notes.unpin': 'Loslösen',
|
||
'collab.notes.daysAgo': 'vor {n} T.',
|
||
'collab.notes.categorySettings': 'Kategorien verwalten',
|
||
'collab.notes.create': 'Erstellen',
|
||
'collab.notes.website': 'Website',
|
||
'collab.notes.websitePlaceholder': 'https://...',
|
||
'collab.notes.attachFiles': 'Dateien anhängen',
|
||
'collab.notes.noCategoriesYet': 'Noch keine Kategorien',
|
||
'collab.notes.emptyDesc': 'Erstelle eine Notiz um loszulegen',
|
||
'collab.polls.title': 'Umfragen',
|
||
'collab.polls.new': 'Neue Umfrage',
|
||
'collab.polls.empty': 'Noch keine Umfragen',
|
||
'collab.polls.emptyHint': 'Frage die Gruppe und stimmt gemeinsam ab',
|
||
'collab.polls.question': 'Frage',
|
||
'collab.polls.questionPlaceholder': 'Was sollen wir machen?',
|
||
'collab.polls.addOption': '+ Option hinzufügen',
|
||
'collab.polls.optionPlaceholder': 'Option {n}',
|
||
'collab.polls.create': 'Umfrage erstellen',
|
||
'collab.polls.close': 'Schließen',
|
||
'collab.polls.closed': 'Geschlossen',
|
||
'collab.polls.votes': '{n} Stimmen',
|
||
'collab.polls.vote': '{n} Stimme',
|
||
'collab.polls.multipleChoice': 'Mehrfachauswahl',
|
||
'collab.polls.multiChoice': 'Mehrfachauswahl',
|
||
'collab.polls.deadline': 'Frist',
|
||
'collab.polls.option': 'Option',
|
||
'collab.polls.options': 'Optionen',
|
||
'collab.polls.delete': 'Löschen',
|
||
'collab.polls.closedSection': 'Geschlossen',
|
||
|
||
// Permissions
|
||
'admin.tabs.permissions': 'Berechtigungen',
|
||
'perm.title': 'Berechtigungseinstellungen',
|
||
'perm.subtitle': 'Steuern Sie, wer Aktionen in der Anwendung ausführen kann',
|
||
'perm.saved': 'Berechtigungseinstellungen gespeichert',
|
||
'perm.resetDefaults': 'Auf Standard zurücksetzen',
|
||
'perm.customized': 'angepasst',
|
||
'perm.level.admin': 'Nur Administrator',
|
||
'perm.level.tripOwner': 'Reise-Eigentümer',
|
||
'perm.level.tripMember': 'Reise-Mitglieder',
|
||
'perm.level.everybody': 'Alle',
|
||
'perm.cat.trip': 'Reiseverwaltung',
|
||
'perm.cat.members': 'Mitgliederverwaltung',
|
||
'perm.cat.files': 'Dateien',
|
||
'perm.cat.content': 'Inhalte & Zeitplan',
|
||
'perm.cat.extras': 'Budget, Packlisten & Zusammenarbeit',
|
||
'perm.action.trip_create': 'Reisen erstellen',
|
||
'perm.action.trip_edit': 'Reisedetails bearbeiten',
|
||
'perm.action.trip_delete': 'Reisen löschen',
|
||
'perm.action.trip_archive': 'Reisen archivieren / dearchivieren',
|
||
'perm.action.trip_cover_upload': 'Titelbild hochladen',
|
||
'perm.action.member_manage': 'Mitglieder hinzufügen / entfernen',
|
||
'perm.action.file_upload': 'Dateien hochladen',
|
||
'perm.action.file_edit': 'Datei-Metadaten bearbeiten',
|
||
'perm.action.file_delete': 'Dateien löschen',
|
||
'perm.action.place_edit': 'Orte hinzufügen / bearbeiten / löschen',
|
||
'perm.action.day_edit': 'Tage, Notizen & Zuweisungen bearbeiten',
|
||
'perm.action.reservation_edit': 'Reservierungen verwalten',
|
||
'perm.action.budget_edit': 'Budget verwalten',
|
||
'perm.action.packing_edit': 'Packlisten verwalten',
|
||
'perm.action.collab_edit': 'Zusammenarbeit (Notizen, Umfragen, Chat)',
|
||
'perm.action.share_manage': 'Freigabelinks verwalten',
|
||
'perm.actionHint.trip_create': 'Wer kann neue Reisen erstellen',
|
||
'perm.actionHint.trip_edit': 'Wer kann Reisename, Daten, Beschreibung und Währung ändern',
|
||
'perm.actionHint.trip_delete': 'Wer kann eine Reise dauerhaft löschen',
|
||
'perm.actionHint.trip_archive': 'Wer kann eine Reise archivieren oder dearchivieren',
|
||
'perm.actionHint.trip_cover_upload': 'Wer kann das Titelbild hochladen oder ändern',
|
||
'perm.actionHint.member_manage': 'Wer kann Reise-Mitglieder einladen oder entfernen',
|
||
'perm.actionHint.file_upload': 'Wer kann Dateien zu einer Reise hochladen',
|
||
'perm.actionHint.file_edit': 'Wer kann Dateibeschreibungen und Links bearbeiten',
|
||
'perm.actionHint.file_delete': 'Wer kann Dateien in den Papierkorb verschieben oder dauerhaft löschen',
|
||
'perm.actionHint.place_edit': 'Wer kann Orte hinzufügen, bearbeiten oder löschen',
|
||
'perm.actionHint.day_edit': 'Wer kann Tage, Tagesnotizen und Ort-Zuweisungen bearbeiten',
|
||
'perm.actionHint.reservation_edit': 'Wer kann Reservierungen erstellen, bearbeiten oder löschen',
|
||
'perm.actionHint.budget_edit': 'Wer kann Budgetposten erstellen, bearbeiten oder löschen',
|
||
'perm.actionHint.packing_edit': 'Wer kann Packstücke und Taschen verwalten',
|
||
'perm.actionHint.collab_edit': 'Wer kann Notizen, Umfragen erstellen und Nachrichten senden',
|
||
'perm.actionHint.share_manage': 'Wer kann öffentliche Freigabelinks erstellen oder löschen',
|
||
// Undo
|
||
'undo.button': 'Rückgängig',
|
||
'undo.tooltip': 'Rückgängig: {action}',
|
||
'undo.assignPlace': 'Ort einem Tag zugewiesen',
|
||
'undo.removeAssignment': 'Ort von Tag entfernt',
|
||
'undo.reorder': 'Orte neu sortiert',
|
||
'undo.optimize': 'Route optimiert',
|
||
'undo.deletePlace': 'Ort gelöscht',
|
||
'undo.moveDay': 'Ort zu anderem Tag verschoben',
|
||
'undo.lock': 'Ortssperre umgeschaltet',
|
||
'undo.importGpx': 'GPX-Import',
|
||
'undo.importGoogleList': 'Google Maps-Import',
|
||
|
||
// Notifications
|
||
'notifications.title': 'Benachrichtigungen',
|
||
'notifications.markAllRead': 'Alle als gelesen markieren',
|
||
'notifications.deleteAll': 'Alle löschen',
|
||
'notifications.showAll': 'Alle Benachrichtigungen anzeigen',
|
||
'notifications.empty': 'Keine Benachrichtigungen',
|
||
'notifications.emptyDescription': 'Sie sind auf dem neuesten Stand!',
|
||
'notifications.all': 'Alle',
|
||
'notifications.unreadOnly': 'Ungelesen',
|
||
'notifications.markRead': 'Als gelesen markieren',
|
||
'notifications.markUnread': 'Als ungelesen markieren',
|
||
'notifications.delete': 'Löschen',
|
||
'notifications.system': 'System',
|
||
'memories.error.loadAlbums': 'Alben konnten nicht geladen werden',
|
||
'memories.error.linkAlbum': 'Album konnte nicht verknüpft werden',
|
||
'memories.error.unlinkAlbum': 'Album konnte nicht getrennt werden',
|
||
'memories.error.syncAlbum': 'Album konnte nicht synchronisiert werden',
|
||
'memories.error.loadPhotos': 'Fotos konnten nicht geladen werden',
|
||
'memories.error.addPhotos': 'Fotos konnten nicht hinzugefügt werden',
|
||
'memories.error.removePhoto': 'Foto konnte nicht entfernt werden',
|
||
'memories.error.toggleSharing': 'Freigabe konnte nicht aktualisiert werden',
|
||
'undo.addPlace': 'Ort hinzugefügt',
|
||
'undo.done': 'Rückgängig gemacht: {action}',
|
||
'notifications.test.title': 'Testbenachrichtigung von {actor}',
|
||
'notifications.test.text': 'Dies ist eine einfache Testbenachrichtigung.',
|
||
'notifications.test.booleanTitle': '{actor} bittet um Ihre Zustimmung',
|
||
'notifications.test.booleanText': 'Dies ist eine boolesche Testbenachrichtigung.',
|
||
'notifications.test.accept': 'Genehmigen',
|
||
'notifications.test.decline': 'Ablehnen',
|
||
'notifications.test.navigateTitle': 'Etwas ansehen',
|
||
'notifications.test.navigateText': 'Dies ist eine Navigations-Testbenachrichtigung.',
|
||
'notifications.test.goThere': 'Dorthin',
|
||
'notifications.test.adminTitle': 'Admin-Broadcast',
|
||
'notifications.test.adminText': '{actor} hat eine Testbenachrichtigung an alle Admins gesendet.',
|
||
'notifications.test.tripTitle': '{actor} hat in Ihrer Reise gepostet',
|
||
'notifications.test.tripText': 'Testbenachrichtigung für Reise "{trip}".',
|
||
|
||
// Todo
|
||
'todo.subtab.packing': 'Packliste',
|
||
'todo.subtab.todo': 'To-Do',
|
||
'todo.completed': 'erledigt',
|
||
'todo.filter.all': 'Alle',
|
||
'todo.filter.open': 'Offen',
|
||
'todo.filter.done': 'Erledigt',
|
||
'todo.uncategorized': 'Ohne Kategorie',
|
||
'todo.namePlaceholder': 'Aufgabenname',
|
||
'todo.descriptionPlaceholder': 'Beschreibung (optional)',
|
||
'todo.unassigned': 'Nicht zugewiesen',
|
||
'todo.noCategory': 'Keine Kategorie',
|
||
'todo.hasDescription': 'Hat Beschreibung',
|
||
'todo.addItem': 'Neue Aufgabe hinzufügen...',
|
||
'todo.newCategory': 'Kategoriename',
|
||
'todo.addCategory': 'Kategorie hinzufügen',
|
||
'todo.newItem': 'Neue Aufgabe',
|
||
'todo.empty': 'Noch keine Aufgaben. Erstelle eine Aufgabe um loszulegen!',
|
||
'todo.filter.my': 'Meine Aufgaben',
|
||
'todo.filter.overdue': 'Überfällig',
|
||
'todo.sidebar.tasks': 'Aufgaben',
|
||
'todo.sidebar.categories': 'Kategorien',
|
||
'todo.detail.title': 'Aufgabe',
|
||
'todo.detail.description': 'Beschreibung',
|
||
'todo.detail.category': 'Kategorie',
|
||
'todo.detail.dueDate': 'Fällig am',
|
||
'todo.detail.assignedTo': 'Zuständig',
|
||
'todo.detail.delete': 'Löschen',
|
||
'todo.detail.save': 'Speichern',
|
||
'todo.sortByPrio': 'Priorität',
|
||
'todo.detail.priority': 'Priorität',
|
||
'todo.detail.noPriority': 'Keine',
|
||
'todo.detail.create': 'Aufgabe erstellen',
|
||
|
||
// Notification system (added from feat/notification-system)
|
||
'settings.notifyVersionAvailable': 'Neue Version verfügbar',
|
||
'settings.notificationPreferences.noChannels': 'Keine Benachrichtigungskanäle konfiguriert. Bitte einen Administrator, E-Mail- oder Webhook-Benachrichtigungen einzurichten.',
|
||
'settings.webhookUrl.label': 'Webhook URL',
|
||
'settings.webhookUrl.placeholder': 'https://discord.com/api/webhooks/...',
|
||
'settings.webhookUrl.hint': 'Gib deine Discord-, Slack- oder benutzerdefinierte Webhook-URL ein, um Benachrichtigungen zu erhalten.',
|
||
'settings.webhookUrl.save': 'Speichern',
|
||
'settings.webhookUrl.saved': 'Webhook-URL gespeichert',
|
||
'settings.webhookUrl.test': 'Testen',
|
||
'settings.webhookUrl.testSuccess': 'Test-Webhook erfolgreich gesendet',
|
||
'settings.webhookUrl.testFailed': 'Test-Webhook fehlgeschlagen',
|
||
'settings.notificationPreferences.inapp': 'In-App',
|
||
'settings.notificationPreferences.webhook': 'Webhook',
|
||
'settings.notificationPreferences.email': 'Email',
|
||
'admin.notifications.emailPanel.title': 'Email (SMTP)',
|
||
'admin.notifications.webhookPanel.title': 'Webhook',
|
||
'admin.notifications.inappPanel.title': 'In-App',
|
||
'admin.notifications.inappPanel.hint': 'In-App-Benachrichtigungen sind immer aktiv und können nicht global deaktiviert werden.',
|
||
'admin.notifications.adminWebhookPanel.title': 'Admin-Webhook',
|
||
'admin.notifications.adminWebhookPanel.hint': 'Dieser Webhook wird ausschließlich für Admin-Benachrichtigungen verwendet (z. B. Versions-Updates). Er ist unabhängig von den Benutzer-Webhooks und sendet automatisch, wenn eine URL konfiguriert ist.',
|
||
'admin.notifications.adminWebhookPanel.saved': 'Admin-Webhook-URL gespeichert',
|
||
'admin.notifications.adminWebhookPanel.testSuccess': 'Test-Webhook erfolgreich gesendet',
|
||
'admin.notifications.adminWebhookPanel.testFailed': 'Test-Webhook fehlgeschlagen',
|
||
'admin.notifications.adminWebhookPanel.alwaysOnHint': 'Admin-Webhook sendet automatisch, wenn eine URL konfiguriert ist',
|
||
'admin.notifications.adminNotificationsHint': 'Konfiguriere, welche Kanäle Admin-Benachrichtigungen liefern (z. B. Versions-Updates). Der Webhook sendet automatisch, wenn eine Admin-Webhook-URL gesetzt ist.',
|
||
'admin.tabs.notifications': 'Benachrichtigungen',
|
||
'notifications.versionAvailable.title': 'Update verfügbar',
|
||
'notifications.versionAvailable.text': 'TREK {version} ist jetzt verfügbar.',
|
||
'notifications.versionAvailable.button': 'Details anzeigen',
|
||
'notif.test.title': '[Test] Benachrichtigung',
|
||
'notif.test.simple.text': 'Dies ist eine einfache Testbenachrichtigung.',
|
||
'notif.test.boolean.text': 'Akzeptierst du diese Testbenachrichtigung?',
|
||
'notif.test.navigate.text': 'Klicke unten, um zum Dashboard zu navigieren.',
|
||
|
||
// Notifications
|
||
'notif.trip_invite.title': 'Reiseeinladung',
|
||
'notif.trip_invite.text': '{actor} hat dich zu {trip} eingeladen',
|
||
'notif.booking_change.title': 'Buchung aktualisiert',
|
||
'notif.booking_change.text': '{actor} hat eine Buchung in {trip} aktualisiert',
|
||
'notif.trip_reminder.title': 'Reiseerinnerung',
|
||
'notif.trip_reminder.text': 'Deine Reise {trip} steht bald an!',
|
||
'notif.vacay_invite.title': 'Vacay Fusion-Einladung',
|
||
'notif.vacay_invite.text': '{actor} hat dich zum Fusionieren von Urlaubsplänen eingeladen',
|
||
'notif.photos_shared.title': 'Fotos geteilt',
|
||
'notif.photos_shared.text': '{actor} hat {count} Foto(s) in {trip} geteilt',
|
||
'notif.collab_message.title': 'Neue Nachricht',
|
||
'notif.collab_message.text': '{actor} hat eine Nachricht in {trip} gesendet',
|
||
'notif.packing_tagged.title': 'Packlistenzuweisung',
|
||
'notif.packing_tagged.text': '{actor} hat dich zu {category} in {trip} zugewiesen',
|
||
'notif.version_available.title': 'Neue Version verfügbar',
|
||
'notif.version_available.text': 'TREK {version} ist jetzt verfügbar',
|
||
'notif.action.view_trip': 'Reise ansehen',
|
||
'notif.action.view_collab': 'Nachrichten ansehen',
|
||
'notif.action.view_packing': 'Packliste ansehen',
|
||
'notif.action.view_photos': 'Fotos ansehen',
|
||
'notif.action.view_vacay': 'Vacay ansehen',
|
||
'notif.action.view_admin': 'Zum Admin',
|
||
'notif.action.view': 'Ansehen',
|
||
'notif.action.accept': 'Annehmen',
|
||
'notif.action.decline': 'Ablehnen',
|
||
'notif.generic.title': 'Benachrichtigung',
|
||
'notif.generic.text': 'Du hast eine neue Benachrichtigung',
|
||
'notif.dev.unknown_event.title': '[DEV] Unbekanntes Ereignis',
|
||
'notif.dev.unknown_event.text': 'Ereignistyp "{event}" ist nicht in EVENT_NOTIFICATION_CONFIG registriert',
|
||
}
|
||
|
||
export default de
|
||
|