import { useState } from 'react'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Checkbox } from '@/components/ui/checkbox'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { useAppStore } from '@/stores/app-store'; import { useSettingsStore } from '@/stores/settings-store'; import { useExportSource } from '@/hooks/use-export-source'; import { toast } from '@/lib/toast'; import { ExportDialogFooter } from './ExportDialogFooter'; import { ipc } from '@/lib/ipc'; import { generateHtml } from '@/lib/html-export'; const MARGIN_MAP = { normal: { top: 25, right: 25, bottom: 25, left: 25 }, narrow: { top: 15, right: 15, bottom: 15, left: 15 }, wide: { top: 35, right: 35, bottom: 35, left: 35 }, } as const; export function ExportPdfDialog({ sourcePath }: { sourcePath: string }) { const closeModal = useAppStore((s) => s.closeModal); const { fontSize, pdfFormat, pdfMargins, pdfEmbedFonts, renderTablesAsAscii } = useSettingsStore(); const [format, setFormat] = useState<'letter' | 'a4' | 'legal'>(pdfFormat); const [margins, setMargins] = useState<'normal' | 'narrow' | 'wide'>(pdfMargins); const [embed, setEmbed] = useState(pdfEmbedFonts); const [ascii, setAscii] = useState(renderTablesAsAscii); const [submitting, setSubmitting] = useState(false); const [error, setError] = useState(null); const source = useExportSource(); const handleSubmit = async () => { if (!source) { setError('No file open.'); return; } setSubmitting(true); setError(null); try { // Renderer-side: build the standalone HTML and hand it to the main // process for native print-to-PDF. const html = generateHtml({ source: source.source, title: source.title, standalone: true, highlightStyle: 'github', renderTablesAsAscii: ascii, }); const fmt = format === 'a4' ? { width: '210mm', height: '297mm' } : format === 'legal' ? { width: '8.5in', height: '14in' } : { width: '8.5in', height: '11in' }; const m = MARGIN_MAP[margins]; const pageCss = `@page { size: ${fmt.width} ${fmt.height}; margin: ${m.top}mm ${m.right}mm ${m.bottom}mm ${m.left}mm; }`; const finalHtml = html.replace('', `${pageCss}`); const result = await ipc.print.show({ html: finalHtml, withStyles: embed }); if (!result.ok) { const msg = result.error?.message ?? 'PDF export failed'; toast.error(`Export failed: ${msg}`); setError(msg); setSubmitting(false); return; } toast.success(`Sent ${source.title} to printer`); closeModal(); } catch (err) { const msg = err instanceof Error ? err.message : String(err); toast.error(`Export failed: ${msg}`); setError(msg); setSubmitting(false); } }; return ( !o && closeModal()}> Export to PDF {sourcePath}
{error && (
{error}
)}
); }