mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-30 10:41:49 +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:
@@ -25,6 +25,11 @@ interface AuthState {
|
||||
user: User | null
|
||||
isAuthenticated: boolean
|
||||
isLoading: boolean
|
||||
/** The auth check (loadUser) failed for a non-401 reason while we were online —
|
||||
* the server was unreachable or erroring. Surfaced by the UI so a backend/IdP
|
||||
* outage doesn't render as a blank, error-free page that looks like lost data.
|
||||
* Transient, never persisted. #1283 */
|
||||
authCheckFailed: boolean
|
||||
error: string | null
|
||||
demoMode: boolean
|
||||
devMode: boolean
|
||||
@@ -86,6 +91,7 @@ export const useAuthStore = create<AuthState>()(
|
||||
user: null,
|
||||
isAuthenticated: false,
|
||||
isLoading: true,
|
||||
authCheckFailed: false,
|
||||
error: null,
|
||||
demoMode: localStorage.getItem('demo_mode') === 'true',
|
||||
devMode: false,
|
||||
@@ -200,6 +206,7 @@ export const useAuthStore = create<AuthState>()(
|
||||
set({
|
||||
user: null,
|
||||
isAuthenticated: false,
|
||||
authCheckFailed: false,
|
||||
error: null,
|
||||
})
|
||||
},
|
||||
@@ -215,22 +222,33 @@ export const useAuthStore = create<AuthState>()(
|
||||
user: data.user,
|
||||
isAuthenticated: true,
|
||||
isLoading: false,
|
||||
authCheckFailed: false,
|
||||
})
|
||||
await onAuthSuccess(data.user.id)
|
||||
connect()
|
||||
} catch (err: unknown) {
|
||||
if (seq !== authSequence) return // stale response — ignore
|
||||
// Only clear auth state on 401 (invalid/expired token), not on network errors
|
||||
const isAuthError = err && typeof err === 'object' && 'response' in err &&
|
||||
(err as { response?: { status?: number } }).response?.status === 401
|
||||
if (isAuthError) {
|
||||
const status = err && typeof err === 'object' && 'response' in err
|
||||
? (err as { response?: { status?: number } }).response?.status
|
||||
: undefined
|
||||
if (status === 401) {
|
||||
// Invalid/expired token — clear auth so the guard redirects to login.
|
||||
set({
|
||||
user: null,
|
||||
isAuthenticated: false,
|
||||
isLoading: false,
|
||||
authCheckFailed: false,
|
||||
})
|
||||
} else {
|
||||
} else if (status === undefined && typeof navigator !== 'undefined' && !navigator.onLine) {
|
||||
// Genuinely offline — keep the persisted session so the PWA serves cached
|
||||
// data without a scary error. This is the offline-first happy path.
|
||||
set({ isLoading: false })
|
||||
} else {
|
||||
// Server erroring (5xx) or unreachable while we're online: keep the session
|
||||
// (don't eject the user over a transient outage), but flag it so the UI can
|
||||
// say "couldn't reach the server" instead of showing a blank, error-free
|
||||
// page that looks like the user's trips were lost. #1283
|
||||
set({ isLoading: false, authCheckFailed: true })
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user