import { auth } from "@/auth" import { redirect } from "next/navigation" import { Activity, Link2, Radar, Shuffle } from "lucide-react" type AdminEventType = "CONNECTION" | "PRODUCT_SYNC" | "SYNC_HEALTH" interface AdminEvent { id: string type: AdminEventType status: string timestamp: string storeName: string | null supplierName: string | null metadata?: Record } async function getEvents(type?: AdminEventType): Promise { const searchParams = new URLSearchParams() searchParams.set("limit", "50") if (type) { searchParams.set("type", type) } const res = await fetch( `${process.env.NEXTAUTH_URL}/api/admin/events?${searchParams.toString()}`, { cache: "no-store", }, ) if (!res.ok) { return [] } const data = (await res.json()) as { events: AdminEvent[] } return data.events } function typeBadge(eventType: AdminEventType) { switch (eventType) { case "CONNECTION": return ( Connection ) case "PRODUCT_SYNC": return ( Product Sync ) case "SYNC_HEALTH": return ( Sync Health ) default: return null } } function statusBadge(status: string) { const normalized = status.toUpperCase() let colorClasses = "bg-slate-800/60 text-slate-200 border-slate-500/40" if (normalized === "CONNECTED" || normalized === "ACCEPTED" || normalized === "SUCCESS") { colorClasses = "bg-emerald-500/15 text-emerald-200 border-emerald-500/40" } else if (normalized === "PENDING" || normalized === "IN_PROGRESS") { colorClasses = "bg-amber-500/15 text-amber-200 border-amber-500/40" } else if (normalized === "REJECTED" || normalized === "FAILED") { colorClasses = "bg-rose-500/15 text-rose-200 border-rose-500/40" } return ( {normalized} ) } export default async function AdminEventsPage({ searchParams, }: { searchParams: Promise<{ type?: string }> }) { const session = await auth() if (!session || session.user.role !== "ADMIN") { redirect("/login") } const { type } = await searchParams const filterType = type && ["CONNECTION", "PRODUCT_SYNC", "SYNC_HEALTH"].includes(type) ? (type as AdminEventType) : undefined const events = await getEvents(filterType) return (

Event Timeline

Chronological, read-only view of platform activity across connections, product syncs, and sync health events.

Filter by type:
{events.length === 0 ? (

No events found for the current filter.

) : (
{events.map((event) => (
{typeBadge(event.type)} {statusBadge(event.status)}
{new Date( event.timestamp, ).toLocaleString("en-US", { dateStyle: "short", timeStyle: "short", })}
{event.storeName && ( {event.storeName} )} {event.storeName && event.supplierName && ( ↔ )} {event.supplierName && ( {event.supplierName} )} {!event.storeName && !event.supplierName && ( Platform-level event )}
{event.metadata && event.type === "PRODUCT_SYNC" && (

{(event.metadata.productTitle as string) || "Product sync"}

)} {event.metadata && event.type === "SYNC_HEALTH" && (

{String( (event.metadata.resourceType || "unknown") as string, ).toUpperCase()}{" "} · Records:{" "} {String( (event.metadata.recordCount || 0) as number, )}

)}
))}
)}
) } function FilterChip({ label, href, active, }: { label: string href: string active: boolean }) { return ( {label} ) }