mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-23 15:21:46 +00:00
fix(dashboard): show an error instead of a blank trip list when the server is unreachable (#1283)
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.
This commit is contained in:
@@ -42,6 +42,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'منتهية',
|
||||
'dashboard.status.daysLeft': 'متبقي {count} يوم',
|
||||
'dashboard.toast.loadError': 'فشل تحميل الرحلات',
|
||||
'dashboard.loadErrorBanner': 'تعذّر الوصول إلى الخادم. رحلاتك في أمان — يرجى المحاولة مرة أخرى.',
|
||||
'dashboard.retry': 'إعادة المحاولة',
|
||||
'dashboard.toast.created': 'تم إنشاء الرحلة بنجاح',
|
||||
'dashboard.toast.createError': 'فشل إنشاء الرحلة',
|
||||
'dashboard.toast.updated': 'تم تحديث الرحلة',
|
||||
|
||||
@@ -42,6 +42,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'Passada',
|
||||
'dashboard.status.daysLeft': 'Faltam {count} dias',
|
||||
'dashboard.toast.loadError': 'Não foi possível carregar as viagens',
|
||||
'dashboard.loadErrorBanner': 'Não foi possível conectar ao servidor. Suas viagens estão seguras — tente novamente.',
|
||||
'dashboard.retry': 'Tentar novamente',
|
||||
'dashboard.toast.created': 'Viagem criada com sucesso!',
|
||||
'dashboard.toast.createError': 'Não foi possível criar a viagem',
|
||||
'dashboard.toast.updated': 'Viagem atualizada!',
|
||||
|
||||
@@ -42,6 +42,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'Proběhlé',
|
||||
'dashboard.status.daysLeft': 'zbývá {count} dní',
|
||||
'dashboard.toast.loadError': 'Nepodařilo se načíst cesty',
|
||||
'dashboard.loadErrorBanner': 'Server nebyl dostupný. Vaše cesty jsou v bezpečí — zkuste to prosím znovu.',
|
||||
'dashboard.retry': 'Zkusit znovu',
|
||||
'dashboard.toast.created': 'Cesta byla úspěšně vytvořena!',
|
||||
'dashboard.toast.createError': 'Nepodařilo se vytvořit cestu',
|
||||
'dashboard.toast.updated': 'Cesta byla aktualizována!',
|
||||
|
||||
@@ -43,6 +43,8 @@ const dashboard: TranslationStrings = {
|
||||
'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!',
|
||||
|
||||
@@ -42,6 +42,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'Past',
|
||||
'dashboard.status.daysLeft': '{count} days left',
|
||||
'dashboard.toast.loadError': 'Failed to load trips',
|
||||
'dashboard.loadErrorBanner': "Couldn't reach the server. Your trips are safe — please try again.",
|
||||
'dashboard.retry': 'Retry',
|
||||
'dashboard.toast.created': 'Trip created successfully!',
|
||||
'dashboard.toast.createError': 'Failed to create trip',
|
||||
'dashboard.toast.updated': 'Trip updated!',
|
||||
|
||||
@@ -42,6 +42,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'Pasado',
|
||||
'dashboard.status.daysLeft': 'Quedan {count} días',
|
||||
'dashboard.toast.loadError': 'No se pudieron cargar los viajes',
|
||||
'dashboard.loadErrorBanner': 'No se pudo conectar con el servidor. Tus viajes están a salvo: inténtalo de nuevo.',
|
||||
'dashboard.retry': 'Reintentar',
|
||||
'dashboard.toast.created': '¡Viaje creado correctamente!',
|
||||
'dashboard.toast.createError': 'No se pudo crear el viaje',
|
||||
'dashboard.toast.updated': '¡Viaje actualizado!',
|
||||
|
||||
@@ -42,6 +42,9 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'Passé',
|
||||
'dashboard.status.daysLeft': '{count} jours restants',
|
||||
'dashboard.toast.loadError': 'Impossible de charger les voyages',
|
||||
'dashboard.loadErrorBanner':
|
||||
"Impossible de joindre le serveur. Vos voyages sont en sécurité — veuillez réessayer.",
|
||||
'dashboard.retry': 'Réessayer',
|
||||
'dashboard.toast.created': 'Voyage créé avec succès !',
|
||||
'dashboard.toast.createError': 'Impossible de créer le voyage',
|
||||
'dashboard.toast.updated': 'Voyage mis à jour !',
|
||||
|
||||
@@ -41,6 +41,9 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'Παρελθόν',
|
||||
'dashboard.status.daysLeft': '{count} μέρες έμειναν',
|
||||
'dashboard.toast.loadError': 'Αποτυχία φόρτωσης ταξιδιών',
|
||||
'dashboard.loadErrorBanner':
|
||||
'Δεν ήταν δυνατή η σύνδεση με τον διακομιστή. Τα ταξίδια σας είναι ασφαλή — δοκιμάστε ξανά.',
|
||||
'dashboard.retry': 'Δοκιμάστε ξανά',
|
||||
'dashboard.toast.created': 'Ταξίδι δημιουργήθηκε επιτυχώς!',
|
||||
'dashboard.toast.createError': 'Αποτυχία δημιουργίας ταξιδιού',
|
||||
'dashboard.toast.updated': 'Ταξίδι ενημερώθηκε!',
|
||||
|
||||
@@ -43,6 +43,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'Múlt',
|
||||
'dashboard.status.daysLeft': 'Még {count} nap',
|
||||
'dashboard.toast.loadError': 'Nem sikerült betölteni az utazásokat',
|
||||
'dashboard.loadErrorBanner': 'Nem sikerült elérni a kiszolgálót. Az utazásaid biztonságban vannak — kérlek, próbáld újra.',
|
||||
'dashboard.retry': 'Újra',
|
||||
'dashboard.toast.created': 'Utazás sikeresen létrehozva!',
|
||||
'dashboard.toast.createError': 'Nem sikerült létrehozni',
|
||||
'dashboard.toast.updated': 'Utazás frissítve!',
|
||||
|
||||
@@ -42,6 +42,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'Sudah lewat',
|
||||
'dashboard.status.daysLeft': '{count} hari lagi',
|
||||
'dashboard.toast.loadError': 'Gagal memuat perjalanan',
|
||||
'dashboard.loadErrorBanner': 'Tidak dapat terhubung ke server. Perjalananmu aman — silakan coba lagi.',
|
||||
'dashboard.retry': 'Coba lagi',
|
||||
'dashboard.toast.created': 'Perjalanan berhasil dibuat!',
|
||||
'dashboard.toast.createError': 'Gagal membuat perjalanan',
|
||||
'dashboard.toast.updated': 'Perjalanan diperbarui!',
|
||||
|
||||
@@ -42,6 +42,9 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'Passato',
|
||||
'dashboard.status.daysLeft': '-{count} giorni',
|
||||
'dashboard.toast.loadError': 'Impossibile caricare i viaggi',
|
||||
'dashboard.loadErrorBanner':
|
||||
"Impossibile raggiungere il server. I tuoi viaggi sono al sicuro — riprova.",
|
||||
'dashboard.retry': 'Riprova',
|
||||
'dashboard.toast.created': 'Viaggio creato con successo!',
|
||||
'dashboard.toast.createError': 'Impossibile creare il viaggio',
|
||||
'dashboard.toast.updated': 'Viaggio aggiornato!',
|
||||
|
||||
@@ -42,6 +42,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': '過去',
|
||||
'dashboard.status.daysLeft': '残り{count}日',
|
||||
'dashboard.toast.loadError': '旅行の読み込みに失敗しました',
|
||||
'dashboard.loadErrorBanner': 'サーバーに接続できませんでした。旅行のデータは安全に保存されています — もう一度お試しください。',
|
||||
'dashboard.retry': '再試行',
|
||||
'dashboard.toast.created': '旅行を作成しました!',
|
||||
'dashboard.toast.createError': '旅行の作成に失敗しました',
|
||||
'dashboard.toast.updated': '旅行を更新しました!',
|
||||
|
||||
@@ -42,6 +42,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': '지난 여행',
|
||||
'dashboard.status.daysLeft': '{count}일 남음',
|
||||
'dashboard.toast.loadError': '여행 불러오기 실패',
|
||||
'dashboard.loadErrorBanner': '서버에 연결할 수 없습니다. 여행 정보는 안전하게 보관되어 있으니 잠시 후 다시 시도해 주세요.',
|
||||
'dashboard.retry': '다시 시도',
|
||||
'dashboard.toast.created': '여행이 생성되었습니다!',
|
||||
'dashboard.toast.createError': '여행 생성 실패',
|
||||
'dashboard.toast.updated': '여행이 업데이트되었습니다!',
|
||||
|
||||
@@ -42,6 +42,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'Afgelopen',
|
||||
'dashboard.status.daysLeft': 'nog {count} dagen',
|
||||
'dashboard.toast.loadError': 'Reizen laden mislukt',
|
||||
'dashboard.loadErrorBanner': 'De server is niet bereikbaar. Je reizen zijn veilig — probeer het opnieuw.',
|
||||
'dashboard.retry': 'Opnieuw proberen',
|
||||
'dashboard.toast.created': 'Reis aangemaakt!',
|
||||
'dashboard.toast.createError': 'Reis aanmaken mislukt',
|
||||
'dashboard.toast.updated': 'Reis bijgewerkt!',
|
||||
|
||||
@@ -39,6 +39,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'Zakończona',
|
||||
'dashboard.status.daysLeft': '{count} dni do końca',
|
||||
'dashboard.toast.loadError': 'Nie udało się załadować podróży',
|
||||
'dashboard.loadErrorBanner': 'Nie udało się połączyć z serwerem. Twoje podróże są bezpieczne — spróbuj ponownie.',
|
||||
'dashboard.retry': 'Spróbuj ponownie',
|
||||
'dashboard.toast.created': 'Podróż została utworzona pomyślnie!',
|
||||
'dashboard.toast.createError': 'Nie udało się utworzyć podróży',
|
||||
'dashboard.toast.updated': 'Podróż została zaktualizowana!',
|
||||
|
||||
@@ -42,6 +42,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'Прошло',
|
||||
'dashboard.status.daysLeft': 'осталось {count} дн.',
|
||||
'dashboard.toast.loadError': 'Не удалось загрузить поездки',
|
||||
'dashboard.loadErrorBanner': 'Не удалось подключиться к серверу. Ваши поездки в безопасности — попробуйте снова.',
|
||||
'dashboard.retry': 'Повторить',
|
||||
'dashboard.toast.created': 'Поездка создана!',
|
||||
'dashboard.toast.createError': 'Не удалось создать поездку',
|
||||
'dashboard.toast.updated': 'Поездка обновлена!',
|
||||
|
||||
@@ -42,6 +42,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'Geçmiş',
|
||||
'dashboard.status.daysLeft': '{count} gün kaldı',
|
||||
'dashboard.toast.loadError': 'Seyahatler yüklenemedi',
|
||||
'dashboard.loadErrorBanner': 'Sunucuya ulaşılamadı. Seyahatleriniz güvende — lütfen tekrar deneyin.',
|
||||
'dashboard.retry': 'Tekrar dene',
|
||||
'dashboard.toast.created': 'Seyahat oluşturuldu!',
|
||||
'dashboard.toast.createError': 'Seyahat oluşturulamadı',
|
||||
'dashboard.toast.updated': 'Seyahat güncellendi!',
|
||||
|
||||
@@ -42,6 +42,9 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': 'Минуло',
|
||||
'dashboard.status.daysLeft': 'залишилось {count} дн.',
|
||||
'dashboard.toast.loadError': 'Не вдалося завантажити поїздки',
|
||||
'dashboard.loadErrorBanner':
|
||||
"Не вдалося з'єднатися із сервером. Ваші поїздки в безпеці — будь ласка, спробуйте ще раз.",
|
||||
'dashboard.retry': 'Спробувати ще раз',
|
||||
'dashboard.toast.created': 'Поїздка створена!',
|
||||
'dashboard.toast.createError': 'Не вдалося створити поїздку',
|
||||
'dashboard.toast.updated': 'Поїздка оновлена!',
|
||||
|
||||
@@ -42,6 +42,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': '已結束',
|
||||
'dashboard.status.daysLeft': '還剩 {count} 天',
|
||||
'dashboard.toast.loadError': '載入旅行失敗',
|
||||
'dashboard.loadErrorBanner': '無法連線到伺服器。你的旅行資料安全無虞——請稍後再試。',
|
||||
'dashboard.retry': '重試',
|
||||
'dashboard.toast.created': '旅行建立成功!',
|
||||
'dashboard.toast.createError': '建立旅行失敗',
|
||||
'dashboard.toast.updated': '旅行已更新!',
|
||||
|
||||
@@ -42,6 +42,8 @@ const dashboard: TranslationStrings = {
|
||||
'dashboard.status.past': '已结束',
|
||||
'dashboard.status.daysLeft': '还剩 {count} 天',
|
||||
'dashboard.toast.loadError': '加载旅行失败',
|
||||
'dashboard.loadErrorBanner': '无法连接到服务器。你的旅行数据安然无恙——请稍后重试。',
|
||||
'dashboard.retry': '重试',
|
||||
'dashboard.toast.created': '旅行创建成功!',
|
||||
'dashboard.toast.createError': '创建旅行失败',
|
||||
'dashboard.toast.updated': '旅行已更新!',
|
||||
|
||||
Reference in New Issue
Block a user