mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-22 23:01:48 +00:00
c0b5d941dd
When the backend or identity provider was unreachable, a returning user with a persisted session landed on the dashboard with an empty trip grid and no error. That looks identical to a logged-in user who simply has no trips, so people assumed their data had been lost. Three client-side layers were quietly swallowing the failure: the auth check only cleared state on a 401, so a 5xx or a network error left the stale session in place and kept rendering the protected route; the offline-first trip repo turned a failed fetch into the empty cache without throwing; and the dashboard had neither an error nor an empty state, so a blank grid meant both "outage" and "no trips". The auth check now tells genuine offline (keep serving the cache silently, the PWA happy path) apart from a server outage while online (keep the session but flag it). The dashboard shows a reassuring "couldn't reach the server, your trips are safe" banner with a retry, and a real zero-trip account finally gets a proper empty state so the two cases never look alike. New strings added across all locales.
168 lines
8.4 KiB
TypeScript
168 lines
8.4 KiB
TypeScript
import type { TranslationStrings } from '../types';
|
||
|
||
const dashboard: TranslationStrings = {
|
||
'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.newTripSub': 'Eine neue Reise von Grund auf planen',
|
||
'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.loadErrorBanner': 'Server nicht erreichbar. Deine Reisen sind sicher — bitte versuche es erneut.',
|
||
'dashboard.retry': 'Erneut versuchen',
|
||
'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',
|
||
'dashboard.greeting.morning': 'Guten Morgen,',
|
||
'dashboard.greeting.afternoon': 'Guten Tag,',
|
||
'dashboard.greeting.evening': 'Guten Abend,',
|
||
'dashboard.mobile.liveNow': 'Jetzt live',
|
||
'dashboard.mobile.tripProgress': 'Reisefortschritt',
|
||
'dashboard.mobile.daysLeft': '{count} Tage übrig',
|
||
'dashboard.mobile.places': 'Orte',
|
||
'dashboard.mobile.buddies': 'Freunde',
|
||
'dashboard.mobile.newTrip': 'Neuer Trip',
|
||
'dashboard.mobile.currency': 'Währung',
|
||
'dashboard.mobile.timezone': 'Zeitzone',
|
||
'dashboard.mobile.upcomingTrips': 'Anstehende Trips',
|
||
'dashboard.mobile.yourTrips': 'Deine Trips',
|
||
'dashboard.mobile.trips': 'Trips',
|
||
'dashboard.mobile.starts': 'Beginn',
|
||
'dashboard.mobile.duration': 'Dauer',
|
||
'dashboard.mobile.day': 'Tag',
|
||
'dashboard.mobile.days': 'Tage',
|
||
'dashboard.mobile.ongoing': 'Laufend',
|
||
'dashboard.mobile.startsToday': 'Beginnt heute',
|
||
'dashboard.mobile.tomorrow': 'Morgen',
|
||
'dashboard.mobile.inDays': 'In {count} Tagen',
|
||
'dashboard.mobile.inMonths': 'In {count} Monaten',
|
||
'dashboard.mobile.completed': 'Abgeschlossen',
|
||
'dashboard.mobile.currencyConverter': 'Währungsrechner',
|
||
'dashboard.filter.planned': 'Geplant',
|
||
'dashboard.hero.badgeLive': 'JETZT LIVE',
|
||
'dashboard.hero.badgeToday': 'STARTET HEUTE',
|
||
'dashboard.hero.badgeTomorrow': 'MORGEN',
|
||
'dashboard.hero.badgeNext': 'ALS NÄCHSTES',
|
||
'dashboard.hero.badgeRecent': 'KÜRZLICH',
|
||
'dashboard.hero.tripDates': 'Reisedaten',
|
||
'dashboard.hero.noDates': 'Freie Planung',
|
||
'dashboard.hero.travelerOne': '{count} Reisender',
|
||
'dashboard.hero.travelerMany': '{count} Reisende',
|
||
'dashboard.hero.destinationOne': '{count} Ziel',
|
||
'dashboard.hero.destinationMany': '{count} Ziele',
|
||
'dashboard.hero.dayUnitOne': 'Tag',
|
||
'dashboard.hero.dayUnitMany': 'Tage',
|
||
'dashboard.hero.dayLeft': 'Tag übrig',
|
||
'dashboard.hero.daysLeft': 'Tage übrig',
|
||
'dashboard.hero.lastDay': 'Letzter Tag',
|
||
'dashboard.hero.untilStart': 'Bis Start',
|
||
'dashboard.hero.startsIn': 'Reise beginnt in',
|
||
'dashboard.atlas.countriesVisited': 'Atlas · Besuchte Länder',
|
||
'dashboard.atlas.ofTotal': 'von {total}',
|
||
'dashboard.atlas.tripsTotal': 'Reisen gesamt',
|
||
'dashboard.atlas.placesMapped': '{count} Orte erfasst',
|
||
'dashboard.atlas.daysTraveled': 'Reisetage',
|
||
'dashboard.atlas.daysUnit': 'Tage',
|
||
'dashboard.atlas.acrossAllTrips': 'über alle Reisen',
|
||
'dashboard.atlas.distanceFlown': 'Geflogene Distanz',
|
||
'dashboard.atlas.kmUnit': 'km',
|
||
'dashboard.atlas.aroundEquator': '≈ {count}× um den Äquator',
|
||
'dashboard.card.idea': 'Idee',
|
||
'dashboard.card.buddyOne': 'Begleiter',
|
||
'dashboard.fx.from': 'Von',
|
||
'dashboard.fx.to': 'Nach',
|
||
'dashboard.fx.unavailable': 'Kurs nicht verfügbar',
|
||
'dashboard.tz.searchPlaceholder': 'Zeitzone suchen…',
|
||
'dashboard.tz.empty': 'Noch keine weiteren Zeitzonen — über + hinzufügen',
|
||
'dashboard.upcoming.title': 'Anstehende Reservierungen',
|
||
'dashboard.upcoming.empty': 'Noch nichts gebucht.',
|
||
'dashboard.confirm.copy.title': 'Diese Reise kopieren?',
|
||
'dashboard.confirm.copy.willCopy': 'Wird kopiert',
|
||
'dashboard.confirm.copy.will1': 'Tage, Orte & Tageszuordnungen',
|
||
'dashboard.confirm.copy.will2': 'Unterkünfte & Reservierungen',
|
||
'dashboard.confirm.copy.will3': 'Budgetposten & Kategoriereihenfolge',
|
||
'dashboard.confirm.copy.will4': 'Packlisten (nicht abgehakt)',
|
||
'dashboard.confirm.copy.will5': 'TODOs (nicht zugewiesen & nicht abgehakt)',
|
||
'dashboard.confirm.copy.will6': 'Tagesnotizen',
|
||
'dashboard.confirm.copy.wontCopy': 'Wird nicht kopiert',
|
||
'dashboard.confirm.copy.wont1': 'Mitwirkende & Mitglieder-Zuweisungen',
|
||
'dashboard.confirm.copy.wont2': 'Kollab-Notizen, Umfragen & Nachrichten',
|
||
'dashboard.confirm.copy.wont3': 'Dateien & Fotos',
|
||
'dashboard.confirm.copy.wont4': 'Freigabe-Tokens',
|
||
'dashboard.confirm.copy.confirm': 'Reise kopieren',
|
||
'dashboard.aria.toggleView': 'Ansicht wechseln',
|
||
'dashboard.aria.filter': 'Filter',
|
||
'dashboard.aria.duplicate': 'Duplizieren',
|
||
'dashboard.aria.refreshRates': 'Kurse aktualisieren',
|
||
'dashboard.aria.swapCurrencies': 'Währungen tauschen',
|
||
'dashboard.aria.addTimezone': 'Zeitzone hinzufügen',
|
||
'dashboard.aria.removeTimezone': '{city} entfernen',
|
||
'dashboard.dayCountRequired': 'Anzahl der Tage ist erforderlich',
|
||
};
|
||
export default dashboard;
|