"use client"; import { useEffect, useState } from "react"; import { useParams } from "next/navigation"; import Link from "next/link"; interface ActivityItem { id: string; projectId: string; projectName: string; action: string; type: "atlas" | "build" | "deploy" | "user"; createdAt: string; } function timeAgo(dateStr: string): string { const date = new Date(dateStr); if (isNaN(date.getTime())) return "—"; const diff = (Date.now() - date.getTime()) / 1000; if (diff < 60) return "just now"; if (diff < 3600) return `${Math.floor(diff / 60)}m ago`; if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`; const days = Math.floor(diff / 86400); if (days === 1) return "Yesterday"; if (days < 7) return `${days}d ago`; return date.toLocaleDateString("en-US", { month: "short", day: "numeric" }); } function typeColor(t: string) { return t === "atlas" ? "#1a1a1a" : t === "build" ? "#3d5afe" : t === "deploy" ? "#2e7d32" : "#8a8478"; } const FILTERS = [ { id: "all", label: "All" }, { id: "atlas", label: "Atlas" }, { id: "build", label: "Builds" }, { id: "deploy", label: "Deploys" }, { id: "user", label: "You" }, ]; export default function ActivityPage() { const params = useParams(); const workspace = params.workspace as string; const [filter, setFilter] = useState("all"); const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { fetch("/api/activity") .then((r) => r.json()) .then((d) => setItems(d.items ?? [])) .catch(() => {}) .finally(() => setLoading(false)); }, []); const filtered = filter === "all" ? items : items.filter((a) => a.type === filter); return (

Activity

Everything happening across your projects

{/* Filter pills */}
{FILTERS.map((f) => ( ))}
{loading && (

Loading…

)} {/* Timeline */} {!loading && filtered.length === 0 && (

No activity yet.

)} {!loading && filtered.length > 0 && (
{/* Vertical line */}
{filtered.map((item, i) => (
(e.currentTarget.style.background = "#fff")} onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")} > {/* Timeline dot */}
(e.currentTarget.style.textDecoration = "underline")} onMouseLeave={(e) => (e.currentTarget.style.textDecoration = "none")} > {item.projectName} · {timeAgo(item.createdAt)}
{item.action}
))}
)}
); }