BunnyCDN, Search tab, journeys redesign, and dashboard polish #52
@@ -237,7 +237,7 @@ export default function SiteDashboardPage() {
|
|||||||
// Single dashboard request replaces focused hooks (overview, pages, locations,
|
// Single dashboard request replaces focused hooks (overview, pages, locations,
|
||||||
// devices, referrers, goals). The backend runs all queries in parallel
|
// devices, referrers, goals). The backend runs all queries in parallel
|
||||||
// and caches the result in Redis for efficient data loading.
|
// and caches the result in Redis for efficient data loading.
|
||||||
const { data: dashboard, isLoading: dashboardLoading, error: dashboardError } = useDashboard(siteId, dateRange.start, dateRange.end, interval, filtersParam || undefined)
|
const { data: dashboard, isLoading: dashboardLoading, isValidating: dashboardValidating, error: dashboardError } = useDashboard(siteId, dateRange.start, dateRange.end, interval, filtersParam || undefined)
|
||||||
const { data: realtimeData } = useRealtime(siteId)
|
const { data: realtimeData } = useRealtime(siteId)
|
||||||
const { data: prevStats } = useStats(siteId, prevRange.start, prevRange.end)
|
const { data: prevStats } = useStats(siteId, prevRange.start, prevRange.end)
|
||||||
const { data: prevDailyStats } = useDailyStats(siteId, prevRange.start, prevRange.end, interval)
|
const { data: prevDailyStats } = useDailyStats(siteId, prevRange.start, prevRange.end, interval)
|
||||||
@@ -531,6 +531,13 @@ export default function SiteDashboardPage() {
|
|||||||
<FilterBar filters={filters} onRemove={handleRemoveFilter} onClear={handleClearFilters} />
|
<FilterBar filters={filters} onRemove={handleRemoveFilter} onClear={handleClearFilters} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Refetch indicator — visible when SWR is revalidating with stale data on screen */}
|
||||||
|
{dashboardValidating && !dashboardLoading && (
|
||||||
|
<div className="h-0.5 w-full rounded-full bg-neutral-100 dark:bg-neutral-800 overflow-hidden mb-2">
|
||||||
|
<div className="h-full w-1/3 rounded-full bg-brand-orange animate-[shimmer_1.2s_ease-in-out_infinite]" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Advanced Chart with Integrated Stats */}
|
{/* Advanced Chart with Integrated Stats */}
|
||||||
<div className="mb-8">
|
<div className="mb-8">
|
||||||
<Chart
|
<Chart
|
||||||
|
|||||||
@@ -27,11 +27,16 @@ const config: Config = {
|
|||||||
'0%': { opacity: '0' },
|
'0%': { opacity: '0' },
|
||||||
'100%': { opacity: '1' },
|
'100%': { opacity: '1' },
|
||||||
},
|
},
|
||||||
|
shimmer: {
|
||||||
|
'0%': { transform: 'translateX(-100%)' },
|
||||||
|
'100%': { transform: 'translateX(400%)' },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
animation: {
|
animation: {
|
||||||
'cell-highlight': 'cell-highlight 0.5s ease forwards',
|
'cell-highlight': 'cell-highlight 0.5s ease forwards',
|
||||||
'cell-flash': 'cell-flash 0.6s ease forwards',
|
'cell-flash': 'cell-flash 0.6s ease forwards',
|
||||||
'fade-in': 'fade-in 150ms ease-out',
|
'fade-in': 'fade-in 150ms ease-out',
|
||||||
|
shimmer: 'shimmer 1.2s ease-in-out infinite',
|
||||||
},
|
},
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
sans: ['var(--font-plus-jakarta-sans)', 'system-ui', 'sans-serif'],
|
sans: ['var(--font-plus-jakarta-sans)', 'system-ui', 'sans-serif'],
|
||||||
|
|||||||
Reference in New Issue
Block a user