/** * Study Report Viewer * Displays the STUDY_REPORT.md file with proper markdown rendering * Includes math equation support via KaTeX and syntax highlighting */ import { useState, useEffect } from 'react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import remarkMath from 'remark-math'; import rehypeKatex from 'rehype-katex'; import 'katex/dist/katex.min.css'; import { FileText, X, ExternalLink, RefreshCw } from 'lucide-react'; interface StudyReportViewerProps { studyId: string; studyPath?: string; } export function StudyReportViewer({ studyId, studyPath }: StudyReportViewerProps) { const [isOpen, setIsOpen] = useState(false); const [markdown, setMarkdown] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const fetchReport = async () => { setLoading(true); setError(null); try { const response = await fetch(`/api/optimization/studies/${studyId}/report`); if (!response.ok) { if (response.status === 404) { setError('No STUDY_REPORT.md found for this study'); } else { throw new Error(`HTTP ${response.status}`); } return; } const data = await response.json(); setMarkdown(data.content); } catch (err) { setError(`Failed to load report: ${err}`); } finally { setLoading(false); } }; useEffect(() => { if (isOpen && !markdown) { fetchReport(); } }, [isOpen, studyId]); if (!isOpen) { return ( ); } return (
{/* Header */}

Study Report

{studyId}/STUDY_REPORT.md

{studyPath && ( )}
{/* Content */}
{loading && (
)} {error && (

{error}

)} {markdown && !loading && (
(

{children}

), h2: ({children}) => (

{children}

), h3: ({children}) => (

{children}

), h4: ({children}) => (

{children}

), // Paragraph styling p: ({children}) => (

{children}

), // List styling ul: ({children}) => (
    {children}
), ol: ({children}) => (
    {children}
), li: ({children}) => (
  • {children}
  • ), // Strong/bold text strong: ({children}) => ( {children} ), // Emphasis/italic em: ({children}) => ( {children} ), // Links a: ({href, children}) => ( {children} ), // Inline code code: ({className, children, ...props}) => { const isInline = !className; if (isInline) { return ( {children} ); } // Code block return ( {children} ); }, // Code blocks with pre wrapper pre: ({children}) => (
                          {children}
                        
    ), // Blockquotes blockquote: ({children}) => (
    {children}
    ), // Tables table: ({children}) => (
    {children}
    ), thead: ({children}) => ( {children} ), th: ({children}) => ( {children} ), td: ({children}) => ( {children} ), tr: ({children}) => ( {children} ), // Horizontal rule hr: () => (
    ), // Images img: ({src, alt}) => ( {alt ), }} > {markdown}
    )}
    ); }