@@ -4,3 +4,40 @@ import { twMerge } from "tailwind-merge"
44export function cn ( ...inputs : ClassValue [ ] ) {
55 return twMerge ( clsx ( inputs ) )
66}
7+
8+ /**
9+ * Format an ISO timestamp string to a readable local date/time.
10+ * e.g. "2026-06-12T12:46:20.671Z" → "12 Jun 2026, 12:46 pm"
11+ */
12+ export function formatTimestamp ( dateString ?: string | null ) : string {
13+ if ( ! dateString ) return "—" ;
14+ const date = new Date ( dateString ) ;
15+ if ( isNaN ( date . getTime ( ) ) ) return dateString ;
16+ return date . toLocaleString ( undefined , {
17+ day : "2-digit" ,
18+ month : "short" ,
19+ year : "numeric" ,
20+ hour : "2-digit" ,
21+ minute : "2-digit" ,
22+ hour12 : true ,
23+ } ) ;
24+ }
25+
26+ /**
27+ * Show relative time for recent events, fall back to formatTimestamp for older ones.
28+ * e.g. "5m ago", "2h ago", "3d ago", or "12 Jun 2026, 12:46 pm"
29+ */
30+ export function formatRelativeTime ( dateString ?: string | null ) : string {
31+ if ( ! dateString ) return "Never" ;
32+ const date = new Date ( dateString ) ;
33+ if ( isNaN ( date . getTime ( ) ) ) return dateString ;
34+ const diffMs = Date . now ( ) - date . getTime ( ) ;
35+ const diffMins = Math . floor ( diffMs / 60000 ) ;
36+ const diffHours = Math . floor ( diffMs / 3600000 ) ;
37+ const diffDays = Math . floor ( diffMs / 86400000 ) ;
38+ if ( diffMins < 1 ) return "Just now" ;
39+ if ( diffMins < 60 ) return `${ diffMins } m ago` ;
40+ if ( diffHours < 24 ) return `${ diffHours } h ago` ;
41+ if ( diffDays < 7 ) return `${ diffDays } d ago` ;
42+ return formatTimestamp ( dateString ) ;
43+ }
0 commit comments