import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdownMenu"; import { buildCSV, downloadCSV } from "@/lib/utils/csv"; import { Download, FileSpreadsheet, FileText, Loader2 } from "lucide-react"; import { useCallback, useState } from "react"; import { type DashboardData, getCSVSections } from "../utils/exportUtils"; const PDF_TAB_LABELS = ["Overview", "Provider Usage", "Model Rankings", "MCP Usage"]; interface ExportPopoverProps { getData: () => DashboardData; onPreloadData: () => Promise; onPdfExport: () => Promise; onPdfExportDone: () => void; } export function ExportPopover({ getData, onPreloadData, onPdfExport, onPdfExportDone }: ExportPopoverProps) { const [exporting, setExporting] = useState(false); const handleCsvExport = useCallback(async () => { setExporting(true); try { await onPreloadData(); const sections = getCSVSections(getData(), "all"); const parts: string[] = []; for (const section of sections) { if (section.csv.rows.length === 0) continue; parts.push(`# ${section.name}`); parts.push(buildCSV(section.csv.headers, section.csv.rows)); parts.push(""); } if (parts.length > 0) { downloadCSV(parts.join("\n"), "dashboard-export"); } } finally { setExporting(false); } }, [getData, onPreloadData]); const handlePdfExport = useCallback(async () => { setExporting(true); // Yield a frame so the spinner renders before heavy work starts await new Promise((r) => requestAnimationFrame(r)); try { const { generatePdf } = await import("@/lib/utils/pdf"); const elements = await onPdfExport(); const sections = elements.map((element, i) => ({ element, label: PDF_TAB_LABELS[i], })); await generatePdf(sections, "dashboard-export", { branding: { logoSrc: "/bifrost-logo.webp", text: "Powered by", }, }); } finally { onPdfExportDone(); setExporting(false); } }, [onPdfExport, onPdfExportDone]); return ( CSV PDF ); }