"use client"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter, } from "@/components/ui/card"; import { toast } from "sonner"; import { Skeleton } from "@/components/ui/skeleton"; import { getAnalysis } from "@/app/actions/analyze"; import { Loader2Icon, TerminalIcon } from "lucide-react"; import { useCallback, useEffect, useState } from "react"; import { ChartDataPoint, CodeAnalysisRadarChart, } from "@/features/problems/analysis/components/radar-chart"; import type { AnalysisStatus, CodeAnalysis } from "@/generated/client"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { useTranslations } from "next-intl"; interface AnalysisCardProps { submissionId: string; } const ACTIVE_STATUSES: AnalysisStatus[] = ["PENDING", "QUEUED", "PROCESSING"]; const FINAL_STATUSES: AnalysisStatus[] = ["COMPLETED", "FAILED"]; export const AnalysisCard = ({ submissionId }: AnalysisCardProps) => { const t = useTranslations("AnalysisCard"); const [analysis, setAnalysis] = useState(null); const fetchAnalysis = useCallback(() => { getAnalysis(submissionId) .then((analysis) => { setAnalysis(analysis); }) .catch((error) => { toast.error(t("UpdateFailed"), { description: error.message || t("UpdateFailedDescription"), }); }); }, [submissionId, t]); useEffect(() => { if (!analysis) { fetchAnalysis(); } const interval = setInterval(() => { if (!analysis || ACTIVE_STATUSES.includes(analysis.status)) { fetchAnalysis(); } else if (FINAL_STATUSES.includes(analysis.status)) { clearInterval(interval); } }, 5000); return () => clearInterval(interval); }, [analysis, fetchAnalysis]); if (!analysis) { return (

{t("Analyzing")}

); } if (analysis.status === "FAILED") { return ( {t("Title")} {t("FailedTitle")} {t("FailedDescription")} ); } if (analysis.status !== "COMPLETED") { return ( {t("Title")} {t("PreparingDescription")}

{t("Processing")}

{t("ProcessingHint")}

); } // Transform the data into a format suitable for the RadarChart const chartData: ChartDataPoint[] = [ { kind: t("Kinds.Overall"), score: analysis.overallScore ?? 0, fullMark: 100, }, { kind: t("Kinds.Style"), score: analysis.styleScore ?? 0, fullMark: 100, }, { kind: t("Kinds.Readability"), score: analysis.readabilityScore ?? 0, fullMark: 100, }, { kind: t("Kinds.Efficiency"), score: analysis.efficiencyScore ?? 0, fullMark: 100, }, { kind: t("Kinds.Correctness"), score: analysis.correctnessScore ?? 0, fullMark: 100, }, ]; return ( {t("Title")} {t("CompletedDescription")}
{t("OverallScore")} {analysis.overallScore ?? t("NotAvailable")} /100

{t("Feedback")}

{analysis.feedback}

); };