feat: add skeleton loading to Journeys page

Use JourneysSkeleton with useMinimumLoading hook, matching the
loading pattern used on Dashboard, Funnels, Uptime, and Settings.
This commit is contained in:
Usman Baig
2026-03-13 11:58:35 +01:00
parent 57e43b1b4f
commit b6a7c642f2
2 changed files with 15 additions and 13 deletions

View File

@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
## [Unreleased]
### Improved
- **Smoother loading on the Journeys page.** The Journeys tab now shows a polished skeleton placeholder while data loads, matching the loading experience on Dashboard, Funnels, Uptime, and Settings.
### Fixed
- **No more random errors when switching tabs.** Navigating between Dashboard, Funnels, Uptime, and Settings no longer shows "Invalid credentials", "Something went wrong", or "Site not found" errors. This was caused by a timing issue when your login session refreshed in the background while multiple pages were loading at the same time — all those requests now wait for the refresh to finish and retry cleanly.

View File

@@ -6,7 +6,7 @@ import { getDateRange, formatDate } from '@ciphera-net/ui'
import { Select, DatePicker } from '@ciphera-net/ui'
import SankeyDiagram from '@/components/journeys/SankeyDiagram'
import TopPathsTable from '@/components/journeys/TopPathsTable'
import { SkeletonCard } from '@/components/skeletons'
import { JourneysSkeleton, useMinimumLoading } from '@/components/skeletons'
import {
useDashboard,
useJourneyTransitions,
@@ -52,6 +52,8 @@ export default function JourneysPage() {
document.title = domain ? `Journeys \u00b7 ${domain} | Pulse` : 'Journeys | Pulse'
}, [dashboard?.site?.domain])
const showSkeleton = useMinimumLoading(transitionsLoading && !transitionsData)
const entryPointOptions = [
{ value: '', label: 'All entry points' },
...(entryPoints ?? []).map((ep) => ({
@@ -60,6 +62,8 @@ export default function JourneysPage() {
})),
]
if (showSkeleton) return <JourneysSkeleton />
return (
<div className="w-full max-w-6xl mx-auto px-4 sm:px-6 pb-8">
{/* Header */}
@@ -146,18 +150,12 @@ export default function JourneysPage() {
{/* Sankey Diagram */}
<div className="bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-2xl p-6 mb-6">
{transitionsLoading ? (
<div className="h-[400px] flex items-center justify-center">
<SkeletonCard className="w-full h-full" />
</div>
) : (
<SankeyDiagram
transitions={transitionsData?.transitions ?? []}
totalSessions={transitionsData?.total_sessions ?? 0}
depth={depth}
onNodeClick={(path) => setEntryPath(path)}
/>
)}
<SankeyDiagram
transitions={transitionsData?.transitions ?? []}
totalSessions={transitionsData?.total_sessions ?? 0}
depth={depth}
onNodeClick={(path) => setEntryPath(path)}
/>
</div>
{/* Top Paths */}