1.1 KB32 lines
Blame
1"use client";
2
3import { useState, useEffect } from "react";
4
5function computeTimeAgo(dateStr: string): string {
6 // SQLite datetime('now') returns UTC without Z suffix — append Z if missing
7 const normalized = dateStr.endsWith("Z") || dateStr.includes("+") || dateStr.includes("T")
8 ? dateStr
9 : dateStr + "Z";
10 const seconds = Math.floor((Date.now() - new Date(normalized).getTime()) / 1000);
11 if (seconds < 60) return "just now";
12 if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;
13 if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;
14 if (seconds < 2592000) return `${Math.floor(seconds / 86400)}d ago`;
15 return new Date(normalized).toLocaleDateString();
16}
17
18export function TimeAgo({ date }: { date: string }) {
19 const [text, setText] = useState(() => computeTimeAgo(date));
20
21 useEffect(() => {
22 // Re-compute immediately on mount (fixes SSR mismatch)
23 setText(computeTimeAgo(date));
24 const interval = setInterval(() => {
25 setText(computeTimeAgo(date));
26 }, 10_000);
27 return () => clearInterval(interval);
28 }, [date]);
29
30 return <span suppressHydrationWarning>{text}</span>;
31}
32