diff --git a/frontend/src/components/repeater/repeaterPaneShared.tsx b/frontend/src/components/repeater/repeaterPaneShared.tsx index 3fad438..4dc182d 100644 --- a/frontend/src/components/repeater/repeaterPaneShared.tsx +++ b/frontend/src/components/repeater/repeaterPaneShared.tsx @@ -80,6 +80,28 @@ export function formatAdvertInterval(val: string | null): string { return `${trimmed}h`; } +function formatFetchedRelative(fetchedAt: number): string { + const elapsedSeconds = Math.max(0, Math.floor((Date.now() - fetchedAt) / 1000)); + + if (elapsedSeconds < 60) return 'Just now'; + + const elapsedMinutes = Math.floor(elapsedSeconds / 60); + if (elapsedMinutes < 60) { + return `${elapsedMinutes} minute${elapsedMinutes === 1 ? '' : 's'} ago`; + } + + const elapsedHours = Math.floor(elapsedMinutes / 60); + return `${elapsedHours} hour${elapsedHours === 1 ? '' : 's'} ago`; +} + +function formatFetchedTime(fetchedAt: number): string { + return new Date(fetchedAt).toLocaleTimeString([], { + hour: 'numeric', + minute: '2-digit', + second: '2-digit', + }); +} + // --- Generic Pane Wrapper --- export function RepeaterPane({ @@ -99,10 +121,22 @@ export function RepeaterPane({ className?: string; contentClassName?: string; }) { + const fetchedAt = state.fetched_at ?? null; + return (
-

{title}

+
+

{title}

+ {fetchedAt && ( +

+ Fetched {formatFetchedTime(fetchedAt)} ({formatFetchedRelative(fetchedAt)}) +

+ )} +
{onRefresh && (