import { useEffect, useState } from "react"; import { FileText, Loader2, Maximize2, Minimize2, PanelRightClose } from "lucide-react"; import { AgenticApiError, generateReport, getReportVersion, listReportVersions, type ReportDetail, type ReportSummary, } from "@/services/agenticApi"; import type { Analysis } from "@/services/orchestrationApi"; import { MarkdownContent } from "./MarkdownContent"; import { ReportVersionSelector } from "./ReportVersionSelector"; import { EmptyState, ErrorState } from "./AnalysisStates"; import { formatDateTime } from "./utils"; interface ReportSidebarProps { analysis: Analysis | null; userId?: string; onCollapse?: () => void; fullscreen?: boolean; onToggleFullscreen?: () => void; } export function ReportSidebar({ analysis, userId, onCollapse, fullscreen = false, onToggleFullscreen }: ReportSidebarProps) { const [versions, setVersions] = useState([]); const [selectedVersion, setSelectedVersion] = useState(); const [detail, setDetail] = useState(null); const [loadingVersions, setLoadingVersions] = useState(false); const [loadingDetail, setLoadingDetail] = useState(false); const [generating, setGenerating] = useState(false); const [error, setError] = useState(null); const [precondition, setPrecondition] = useState(null); const loadVersions = async (analysisId: string, options: { silent?: boolean } = {}) => { setLoadingVersions(true); setError(null); try { const list = await listReportVersions(analysisId); setVersions(list); const latest = [...list].sort((a, b) => b.version - a.version)[0]; setSelectedVersion(latest?.version); } catch (err) { setVersions([]); setSelectedVersion(undefined); const isMissingReportCollection = err instanceof AgenticApiError && err.status === 404; if (!options.silent && !isMissingReportCollection) { setError(err instanceof Error ? err.message : "Failed to load report versions"); } } finally { setLoadingVersions(false); } }; useEffect(() => { setDetail(null); setPrecondition(null); setVersions([]); setSelectedVersion(undefined); if (analysis?.id) loadVersions(analysis.id, { silent: true }); }, [analysis?.id]); useEffect(() => { const loadDetail = async () => { if (!analysis?.id || selectedVersion == null) return; setLoadingDetail(true); setError(null); try { setDetail(await getReportVersion(analysis.id, selectedVersion)); } catch (err) { setError(err instanceof Error ? err.message : "Failed to load report"); } finally { setLoadingDetail(false); } }; loadDetail(); }, [selectedVersion]); const handleGenerate = async () => { if (!analysis?.id || !userId) return; setGenerating(true); setError(null); setPrecondition(null); try { const report = await generateReport(analysis.id, userId); setDetail(report); await loadVersions(analysis.id, { silent: true }); setSelectedVersion(report.version); } catch (err) { if (err instanceof AgenticApiError && err.status === 409) { setPrecondition(err.message); } else { setError(err instanceof Error ? err.message : "Failed to generate report"); } } finally { setGenerating(false); } }; return (

Report

Generate and preview report versions.

{onToggleFullscreen && ( )} {onCollapse && !fullscreen && ( )}
{!analysis ? ( ) : ( <> {precondition &&

{precondition}

} {error && } {loadingDetail ? (
Loading report
) : detail ? (
v{detail.version} generated {formatDateTime(detail.generated_at)}
{detail.rendered_markdown ? ( ) : (
{detail.executive_summary &&

{detail.executive_summary}

} {detail.findings && detail.findings.length > 0 && (

Findings

    {detail.findings.map((item, index) =>
  • {item.text}
  • )}
)} {detail.caveats && detail.caveats.length > 0 && (

Caveats

    {detail.caveats.map((item, index) =>
  • {item.text}
  • )}
)} {detail.open_questions && detail.open_questions.length > 0 && (

Open questions

    {detail.open_questions.map((item, index) =>
  • {item.text}
  • )}
)}
)}
) : ( )} )}
); }