import React, { useEffect, useMemo, useState } from 'react'; import * as XLSX from 'xlsx'; import { FaCheckSquare, FaDownload, FaFileExcel, FaFileExport, FaFilePdf, FaSpinner, FaSquare, FaTimes, } from 'react-icons/fa'; export interface QueryReportColumn { fieldname: string; label?: string; } export type QueryReportExportFormat = 'excel' | 'pdf'; export interface QueryReportExportModalProps { isOpen: boolean; onClose: () => void; title?: string; columns: QueryReportColumn[]; rows: Record[]; fileNamePrefix?: string; } function formatCellValue(value: unknown): string { if (value === null || value === undefined || value === '') return ''; return String(value); } function downloadExcel( rows: Record[], columns: QueryReportColumn[], fileName: string, ) { const wsData = [ columns.map((c) => c.label || c.fieldname), ...rows.map((row) => columns.map((c) => formatCellValue(row[c.fieldname]))), ]; const ws = XLSX.utils.aoa_to_sheet(wsData); const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, 'Export'); XLSX.writeFile(wb, fileName); } function downloadPdf( rows: Record[], columns: QueryReportColumn[], reportTitle: string, ) { const printWindow = window.open('', '_blank'); if (!printWindow) { window.alert('Please allow popups for this site to export PDF.'); return; } const tableHTML = ` ${reportTitle}

${reportTitle}

Generated on: ${new Date().toLocaleString()} | Total Records: ${rows.length}
${columns.map((c) => ``).join('')} ${rows.map((row) => ` ${columns.map((c) => ``).join('')} `).join('')}
${c.label || c.fieldname}
${formatCellValue(row[c.fieldname]) || '—'}
`; printWindow.document.write(tableHTML); printWindow.document.close(); } const QueryReportExportModal: React.FC = ({ isOpen, onClose, title = 'Export Report', columns, rows, fileNamePrefix = 'report', }) => { const [format, setFormat] = useState('excel'); const [checkedKeys, setCheckedKeys] = useState>(new Set()); const [isExporting, setIsExporting] = useState(false); const columnOptions = useMemo( () => columns.filter((c) => c.fieldname), [columns], ); useEffect(() => { if (!isOpen) return; setFormat('excel'); setCheckedKeys(new Set(columnOptions.map((c) => c.fieldname))); }, [isOpen, columnOptions]); if (!isOpen) return null; const chosenColumns = columnOptions.filter((c) => checkedKeys.has(c.fieldname)); const canExport = rows.length > 0 && chosenColumns.length > 0; const toggleColumn = (key: string) => { setCheckedKeys((prev) => { const next = new Set(prev); if (next.has(key)) next.delete(key); else next.add(key); return next; }); }; const selectAll = () => setCheckedKeys(new Set(columnOptions.map((c) => c.fieldname))); const selectNone = () => setCheckedKeys(new Set()); const handleExport = async () => { if (!canExport) return; setIsExporting(true); try { const datePart = new Date().toISOString().split('T')[0]; if (format === 'excel') { downloadExcel(rows, chosenColumns, `${fileNamePrefix}_${datePart}.xlsx`); } else { downloadPdf(rows, chosenColumns, title); } onClose(); } catch (err) { console.error('Export failed:', err); window.alert(`Export failed: ${err instanceof Error ? err.message : 'Unknown error'}`); } finally { setIsExporting(false); } }; return (

{title}

File format

Columns to export

{columnOptions.map((col) => { const checked = checkedKeys.has(col.fieldname); return ( ); })}

{checkedKeys.size} of {columnOptions.length} columns selected · {rows.length} row{rows.length !== 1 ? 's' : ''}

); }; export default QueryReportExportModal;