From 9b95ead6bad26cb7bf6f5679409d54f139fa559d Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Thu, 12 Feb 2026 08:24:55 +0100 Subject: [PATCH] feat: implement last updated timestamp display in dashboard components for improved data freshness indication --- app/share/[id]/page.tsx | 27 +++++++++---------------- app/sites/[id]/page.tsx | 37 ++++++++++++++-------------------- components/dashboard/Chart.tsx | 16 +++++++++++++-- 3 files changed, 39 insertions(+), 41 deletions(-) diff --git a/app/share/[id]/page.tsx b/app/share/[id]/page.tsx index 087f558..dae6587 100644 --- a/app/share/[id]/page.tsx +++ b/app/share/[id]/page.tsx @@ -3,7 +3,6 @@ import { useEffect, useState } from 'react' import { useParams, useSearchParams, useRouter } from 'next/navigation' import { getPublicDashboard, getPublicStats, getPublicDailyStats, getPublicRealtime, getPublicPerformanceByPage, type DashboardData, type Stats, type DailyStat, type PerformanceByPageStat } from '@/lib/api/stats' -import { formatUpdatedAgo } from '@/lib/utils/format' import { toast } from '@ciphera-net/ui' import { getAuthErrorMessage } from '@/lib/utils/authErrors' import { LoadingOverlay, Button } from '@ciphera-net/ui' @@ -293,22 +292,15 @@ export default function PublicDashboardPage() { - {/* Realtime Indicator & Polling - Desktop */} -
-
- - - - - - {realtime_visitors} current visitors - -
- {lastUpdatedAt !== null && ( - - Updated {formatUpdatedAgo(lastUpdatedAt)} - - )} + {/* Realtime Indicator - Desktop */} +
+ + + + + + {realtime_visitors} current visitors +
@@ -388,6 +380,7 @@ export default function PublicDashboardPage() { setTodayInterval={setTodayInterval} multiDayInterval={multiDayInterval} setMultiDayInterval={setMultiDayInterval} + lastUpdatedAt={lastUpdatedAt} /> diff --git a/app/sites/[id]/page.tsx b/app/sites/[id]/page.tsx index 676f9d4..ac9bd4c 100644 --- a/app/sites/[id]/page.tsx +++ b/app/sites/[id]/page.tsx @@ -6,7 +6,7 @@ import { useParams, useRouter } from 'next/navigation' import { motion } from 'framer-motion' import { getSite, type Site } from '@/lib/api/sites' import { getStats, getRealtime, getDailyStats, getTopPages, getTopReferrers, getCountries, getCities, getRegions, getBrowsers, getOS, getDevices, getScreenResolutions, getEntryPages, getExitPages, getDashboard, getCampaigns, getPerformanceByPage, type Stats, type DailyStat, type PerformanceByPageStat } from '@/lib/api/stats' -import { formatNumber, formatDuration, formatUpdatedAgo, getDateRange } from '@/lib/utils/format' +import { formatNumber, formatDuration, getDateRange } from '@/lib/utils/format' import { toast } from '@ciphera-net/ui' import { getAuthErrorMessage } from '@/lib/utils/authErrors' import { LoadingOverlay, Button } from '@ciphera-net/ui' @@ -259,27 +259,19 @@ export default function SiteDashboardPage() {

-
- {/* Realtime Indicator */} - - {/* Polling indicator */} - {lastUpdatedAt !== null && ( - - Updated {formatUpdatedAgo(lastUpdatedAt)} - - )} -
+ {/* Realtime Indicator */} +
@@ -379,6 +371,7 @@ export default function SiteDashboardPage() { setTodayInterval={setTodayInterval} multiDayInterval={multiDayInterval} setMultiDayInterval={setMultiDayInterval} + lastUpdatedAt={lastUpdatedAt} />
diff --git a/components/dashboard/Chart.tsx b/components/dashboard/Chart.tsx index b0c74ff..b94e468 100644 --- a/components/dashboard/Chart.tsx +++ b/components/dashboard/Chart.tsx @@ -13,7 +13,7 @@ import { ReferenceLine, } from 'recharts' import type { TooltipProps } from 'recharts' -import { formatNumber, formatDuration } from '@/lib/utils/format' +import { formatNumber, formatDuration, formatUpdatedAgo } from '@/lib/utils/format' import { ArrowUpRightIcon, ArrowDownRightIcon, BarChartIcon, Select, Button, DownloadIcon } from '@ciphera-net/ui' import { Checkbox } from '@ciphera-net/ui' @@ -69,6 +69,8 @@ interface ChartProps { setMultiDayInterval: (interval: 'hour' | 'day') => void /** Optional: callback when user requests chart export (parent can open ExportModal or handle export) */ onExportChart?: () => void + /** Optional: timestamp of last data fetch for "Live · Xs ago" indicator */ + lastUpdatedAt?: number | null } type MetricType = 'pageviews' | 'visitors' | 'bounce_rate' | 'avg_duration' @@ -263,6 +265,7 @@ export default function Chart({ multiDayInterval, setMultiDayInterval, onExportChart, + lastUpdatedAt, }: ChartProps) { const [metric, setMetric] = useState('visitors') const [showComparison, setShowComparison] = useState(false) @@ -406,10 +409,19 @@ export default function Chart({ return (
+ {/* * Subtle live/updated indicator in bottom-right corner */} + {lastUpdatedAt != null && ( +
+ Live · {formatUpdatedAgo(lastUpdatedAt)} +
+ )} {/* Stats Header (Interactive Tabs) */}
{metrics.map((item) => (