"use client"; import useSWR from "swr"; import { fetcher } from "@/lib/fetcher"; import { Clock, CheckCircle2, AlertTriangle, Hourglass, Layers } from "lucide-react"; export default function QueueBadge() { const { data, error, isLoading } = useSWR<{ waiting: number; active: number; completed: number; failed: number; delayed: number }>( "/api/queue/status", fetcher, { refreshInterval: 8_000, dedupingInterval: 4_000, revalidateOnFocus: false }, ); if (isLoading) { return ( queue… ); } if (error || !data) return null; const total = data.waiting + data.active + data.delayed; const hasWork = total > 0 || data.failed > 0; if (!hasWork) { return ( index idle ); } return ( 0 ? "text-amber-700 dark:text-amber-400 bg-amber-500/10 border-amber-500/30" : "text-[var(--text-secondary)] bg-[var(--bg-elevated)] border-[var(--border-color)]" }`} title={`waiting:${data.waiting} active:${data.active} delayed:${data.delayed} failed:${data.failed}`} role="status" aria-live="polite" > {data.failed > 0 ? : } q:{data.waiting}w · {data.active}a {data.delayed ? ` · ${data.delayed}d` : ""} {data.failed ? ` · ${data.failed} ✕` : ""} ); } export function QueueStrip() { const { data } = useSWR<{ waiting: number; active: number; completed: number; failed: number; delayed: number }>( "/api/queue/status", fetcher, { refreshInterval: 6_000, revalidateOnFocus: false }, ); if (!data) return null; const items: { label: string; value: number; tone: string }[] = [ { label: "waiting", value: data.waiting, tone: "text-[var(--text-muted)]" }, { label: "active", value: data.active, tone: "text-sky-600 dark:text-sky-400" }, { label: "delayed", value: data.delayed, tone: "text-[var(--text-muted)]" }, { label: "failed", value: data.failed, tone: data.failed ? "text-amber-600 dark:text-amber-400" : "text-[var(--text-dim)]" }, { label: "completed", value: data.completed, tone: "text-emerald-600 dark:text-emerald-400" }, ]; return (
{items.map((it) => ( {it.label}: {it.value} ))}
); }