"use client"; import { useEffect, useState } from "react"; import Link from "next/link"; import type { GenerationStatus } from "@codeboard/shared"; import { Loader2, CheckCircle2, Circle, AlertCircle, FileText, RefreshCw, } from "lucide-react"; interface ProgressData { status: GenerationStatus; progress: number; message: string; } interface ProgressTrackerProps { generationId: string; repoUrl: string; } const STEPS: { status: GenerationStatus; label: string }[] = [ { status: "QUEUED", label: "Queued" }, { status: "CLONING", label: "Cloning Repository" }, { status: "PARSING", label: "Analyzing Code" }, { status: "GENERATING", label: "Generating Docs" }, { status: "RENDERING", label: "Finalizing" }, ]; export function ProgressTracker({ generationId, repoUrl, }: ProgressTrackerProps) { const [data, setData] = useState({ status: "QUEUED", progress: 0, message: "Waiting in queue...", }); const [error, setError] = useState(null); useEffect(() => { const eventSource = new EventSource(`/api/status/${generationId}`); eventSource.addEventListener("progress", (event) => { try { const parsed = JSON.parse(event.data); setData(parsed); if (parsed.status === "COMPLETED" || parsed.status === "FAILED") { eventSource.close(); } } catch { setError("Failed to parse progress data"); } }); eventSource.addEventListener("timeout", () => { setError("Connection timed out. Please refresh the page."); eventSource.close(); }); eventSource.onerror = () => { setError("Connection error. Please refresh the page."); eventSource.close(); }; return () => { eventSource.close(); }; }, [generationId]); const getStepIndex = (status: GenerationStatus) => { if (status === "COMPLETED") return STEPS.length; if (status === "FAILED") return -1; return STEPS.findIndex((s) => s.status === status); }; const currentStepIndex = getStepIndex(data.status); const isCompleted = data.status === "COMPLETED"; const isFailed = data.status === "FAILED"; return (
{data.message} {data.progress}%
{STEPS.map((step, index) => { const isActive = index === currentStepIndex; const isDone = index < currentStepIndex || isCompleted; return (
{isActive ? ( ) : isDone ? ( ) : ( )}
{step.label}
{isActive && (
)}
))}
{isFailed && (

Generation Failed

Something went wrong. Please try again.

)} {isCompleted && (

Documentation Ready!

Your interactive documentation has been generated successfully.

View Documentation
)} {error && !isFailed && (

Connection Error

{error}

)}
); }