diff --git a/apps/web/src/app/api/create/calendar/generate/route.ts b/apps/web/src/app/api/create/calendar/generate/route.ts index 161161d5..f5e8b394 100644 --- a/apps/web/src/app/api/create/calendar/generate/route.ts +++ b/apps/web/src/app/api/create/calendar/generate/route.ts @@ -37,6 +37,7 @@ export async function POST(request: NextRequest) { // Generate SVGs using server-side rendering (API routes can use react-dom/server) const daysInMonth = getDaysInMonth(year, month) + let previewSvg: string | null = null if (format === 'monthly') { // Generate single composite SVG for monthly calendar (prevents multi-page overflow) @@ -49,6 +50,7 @@ export async function POST(request: NextRequest) { if (!compositeSvg || compositeSvg.trim().length === 0) { throw new Error(`Generated empty composite calendar SVG`) } + previewSvg = compositeSvg writeFileSync(join(tempDir, 'calendar.svg'), compositeSvg) } catch (error: any) { console.error(`Error generating composite calendar:`, error.message) @@ -121,18 +123,18 @@ export async function POST(request: NextRequest) { ) } - // Read and return PDF + // Read PDF const pdfBuffer = readFileSync(pdfPath) // Clean up temp directory rmSync(tempDir, { recursive: true, force: true }) tempDir = null - return new NextResponse(pdfBuffer, { - headers: { - 'Content-Type': 'application/pdf', - 'Content-Disposition': `attachment; filename="calendar-${year}-${String(month).padStart(2, '0')}.pdf"`, - }, + // Return JSON with both PDF and SVG preview + return NextResponse.json({ + pdf: pdfBuffer.toString('base64'), + svg: previewSvg, + filename: `calendar-${year}-${String(month).padStart(2, '0')}.pdf`, }) } catch (error) { console.error('Error generating calendar:', error) @@ -146,6 +148,17 @@ export async function POST(request: NextRequest) { } } - return NextResponse.json({ error: 'Failed to generate calendar' }, { status: 500 }) + // Surface the actual error for debugging + const errorMessage = error instanceof Error ? error.message : String(error) + const errorStack = error instanceof Error ? error.stack : undefined + + return NextResponse.json( + { + error: 'Failed to generate calendar', + message: errorMessage, + ...(process.env.NODE_ENV === 'development' && { stack: errorStack }) + }, + { status: 500 } + ) } } diff --git a/apps/web/src/app/create/calendar/page.tsx b/apps/web/src/app/create/calendar/page.tsx index 574c0933..877d2fac 100644 --- a/apps/web/src/app/create/calendar/page.tsx +++ b/apps/web/src/app/create/calendar/page.tsx @@ -15,6 +15,7 @@ export default function CalendarCreatorPage() { const [format, setFormat] = useState<'monthly' | 'daily'>('monthly') const [paperSize, setPaperSize] = useState<'us-letter' | 'a4' | 'a3' | 'tabloid'>('us-letter') const [isGenerating, setIsGenerating] = useState(false) + const [previewSvg, setPreviewSvg] = useState(null) const handleGenerate = async () => { setIsGenerating(true) @@ -34,21 +35,31 @@ export default function CalendarCreatorPage() { }) if (!response.ok) { - throw new Error('Failed to generate calendar') + const errorData = await response.json().catch(() => ({})) + throw new Error(errorData.message || 'Failed to generate calendar') } - const blob = await response.blob() + const data = await response.json() + + // Store SVG preview for display + if (data.svg) { + setPreviewSvg(data.svg) + } + + // Convert base64 PDF to blob and trigger download + const pdfBytes = Uint8Array.from(atob(data.pdf), c => c.charCodeAt(0)) + const blob = new Blob([pdfBytes], { type: 'application/pdf' }) const url = window.URL.createObjectURL(blob) const a = document.createElement('a') a.href = url - a.download = `calendar-${year}-${String(month).padStart(2, '0')}.pdf` + a.download = data.filename document.body.appendChild(a) a.click() window.URL.revokeObjectURL(url) document.body.removeChild(a) } catch (error) { console.error('Error generating calendar:', error) - alert('Failed to generate calendar. Please try again.') + alert(`Failed to generate calendar: ${error instanceof Error ? error.message : 'Unknown error'}`) } finally { setIsGenerating(false) } @@ -122,7 +133,7 @@ export default function CalendarCreatorPage() { /> {/* Preview */} - +