import { useState, useRef, useEffect } from "react"; import type { StudentReport } from "../../App"; interface ReportViewerProps { reports: StudentReport[]; isGenerating: boolean; onBack: () => void; onExportAllHtml: () => void; onSaveToDb?: () => Promise<{ students_saved: number }>; } export function ReportViewer({ reports, isGenerating, onBack, onExportAllHtml, onSaveToDb, }: ReportViewerProps) { const [activeIndex, setActiveIndex] = useState(0); const [saveState, setSaveState] = useState<"idle" | "saving" | "saved" | "error">("idle"); const [saveMsg, setSaveMsg] = useState(""); const iframeRef = useRef(null); const handleSaveToDb = async () => { if (!onSaveToDb) return; setSaveState("saving"); setSaveMsg(""); try { const res = await onSaveToDb(); setSaveState("saved"); setSaveMsg(`已儲存 ${res.students_saved} 位學生成績`); } catch (e) { setSaveState("error"); setSaveMsg(e instanceof Error ? e.message : "儲存失敗"); } }; // Auto-switch to the report currently being generated useEffect(() => { const generatingIdx = reports.findIndex((r) => r.status === "generating"); if (generatingIdx >= 0) { setActiveIndex(generatingIdx); } else { // When generation finishes, show the last completed one let lastDone = -1; for (let j = reports.length - 1; j >= 0; j--) { if (reports[j].status === "done") { lastDone = j; break; } } if (lastDone >= 0) setActiveIndex(lastDone); } }, [reports]); const activeReport = reports[activeIndex]; const doneCount = reports.filter((r) => r.status === "done").length; const errorCount = reports.filter((r) => r.status === "error").length; const handleDownloadSingle = () => { if (!activeReport?.html) return; const blob = new Blob([activeReport.html], { type: "text/html" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = `classlens-${activeReport.studentName}.html`; a.click(); URL.revokeObjectURL(url); }; return (
{/* Progress bar */} {isGenerating && (
生成進度 {doneCount + errorCount} / {reports.length}
)} {/* Action bar */}
{activeReport?.status === "done" && ( )} {doneCount > 1 && ( )} {onSaveToDb && !isGenerating && doneCount > 0 && ( )}
{saveMsg && (

{saveMsg}

)} {/* Student tabs */}
{reports.map((r, i) => ( ))}
{/* Report content */}
{activeReport?.status === "done" && (