"use client"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faSpinner } from "@fortawesome/free-solid-svg-icons"; import type { AnalysisProgress } from "../types/analysis"; import type { AnalysisStatus } from "../hooks/useAnalysis"; type ProgressIndicatorProps = { status: AnalysisStatus; progress: AnalysisProgress | null; timeoutSeconds: number; incompleteTests?: string[]; }; type ProgressVariant = "normal" | "warning" | "timeout"; const formatSeconds = (seconds: number): string => `${seconds}s`; const getVariant = ( status: AnalysisStatus, remainingSeconds: number, timeoutSeconds: number, ): ProgressVariant => { if (status === "timeout") { return "timeout"; } if (status !== "analysing") { return "normal"; } const warningThreshold = Math.max(5, Math.round(timeoutSeconds * 0.15)); return remainingSeconds <= warningThreshold ? "warning" : "normal"; }; const variantStyles: Record = { normal: { bar: "bg-clean", badge: "text-clean border-clean/40", track: "bg-clean/10", }, warning: { bar: "bg-suspicious", badge: "text-suspicious border-suspicious/40", track: "bg-suspicious/10", }, timeout: { bar: "bg-spam", badge: "text-spam border-spam/40", track: "bg-spam/10", }, }; export default function ProgressIndicator({ status, progress, timeoutSeconds, incompleteTests = [], }: ProgressIndicatorProps) { const elapsedSeconds = progress ? Math.floor(progress.elapsedMs / 1000) : 0; const remainingSeconds = Math.max(0, timeoutSeconds - elapsedSeconds); const percentage = progress ? Math.round(progress.percentage) : 0; const variant = getVariant(status, remainingSeconds, timeoutSeconds); const styles = variantStyles[variant]; return (
{status === "analysing" ? "Analysing" : status} {status === "analysing" ? ( ) : null}
{formatSeconds(elapsedSeconds)} / {formatSeconds(remainingSeconds)}
{progress?.currentTest ?? "Preparing analysis"} {percentage}%
{status === "timeout" ? (

Timeout reached at {timeoutSeconds} seconds.

Incomplete tests:

{incompleteTests.length > 0 ? incompleteTests.join(", ") : "None"}

) : null}
); }