import { useEffect, useState } from "react"; import type { GenerationJob, GenerationState } from "@editor/state"; export function currentGenerationJob(generation: GenerationState): GenerationJob | undefined { return generation.jobs.find((job) => job.status === "running") ?? generation.jobs[0]; } export function GenerationJobStatus({ generation, compact = false }: { generation: GenerationState; compact?: boolean }) { const job = currentGenerationJob(generation); const [, setTick] = useState(0); useEffect(() => { if (job?.status !== "running") return; const interval = window.setInterval(() => setTick((tick) => tick + 1), 1000); return () => window.clearInterval(interval); }, [job?.id, job?.status]); if (!job) return null; const elapsed = Math.max(0, Math.floor(((job.finishedAt ?? Date.now()) - job.startedAt) / 1000)); const label = job.status === "running" ? `${job.detail ?? job.label}${job.progress !== undefined ? ` ยท ${Math.round(job.progress * 100)}%` : ""} ${formatElapsed(elapsed)}` : job.status === "failed" ? job.error ?? `${job.label} failed` : job.status === "cancelled" ? `${job.label} cancelled` : `${job.label} complete`; const tone = job.status === "failed" ? "bg-red-500/15 text-red-100" : job.status === "running" ? "bg-white/10 text-white/70" : job.status === "cancelled" ? "bg-amber-500/15 text-amber-100" : "bg-emerald-500/15 text-emerald-100"; return {label}; } function formatElapsed(seconds: number) { const minutes = Math.floor(seconds / 60); return `${minutes}:${(seconds % 60).toString().padStart(2, "0")}`; }