Files
klz-cables.com/app/api/pages/[slug]/pdf/route.tsx

112 lines
3.6 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { getPayload } from 'payload';
import configPromise from '@payload-config';
import { renderToStream } from '@react-pdf/renderer';
import React from 'react';
import { PDFPage } from '@/lib/pdf-page';
import fs from 'fs';
import path from 'path';
export async function GET(req: NextRequest, { params }: { params: Promise<{ slug: string }> }) {
try {
const { slug } = await params;
// Handle AGBs specifically - either fetch from collection or use fallback file
if (slug === 'agbs') {
const payload = await getPayload({ config: configPromise });
const currentAgbs = await payload.find({
collection: 'agbs-collection',
where: {
isCurrent: { equals: true },
},
limit: 1,
});
if (currentAgbs.totalDocs > 0) {
const agb = currentAgbs.docs[0];
const media = agb.file as any;
if (media && media.url) {
// If it's a remote URL or absolute path, we might need to fetch it
// For now assume it's a local file in public/media
const filePath = path.join(process.cwd(), 'public', media.url);
if (fs.existsSync(filePath)) {
const fileBuffer = fs.readFileSync(filePath);
return new NextResponse(fileBuffer, {
status: 200,
headers: {
'Content-Type': 'application/pdf',
'Content-Disposition': `attachment; filename="${media.filename}"`,
},
});
}
}
}
// Fallback for hardcoded legacy AGB
const filePath = path.join(process.cwd(), 'public', 'AVB-KLZ-4-2026.pdf');
if (fs.existsSync(filePath)) {
const fileBuffer = fs.readFileSync(filePath);
return new NextResponse(fileBuffer, {
status: 200,
headers: {
'Content-Type': 'application/pdf',
'Content-Disposition': `attachment; filename="AVB-KLZ-4-2026.pdf"`,
},
});
}
}
// Get Payload App
const payload = await getPayload({ config: configPromise });
// Fetch the page
const pages = await payload.find({
collection: 'pages',
where: {
slug: { equals: slug },
_status: { equals: 'published' },
},
limit: 1,
});
if (pages.totalDocs === 0) {
return new NextResponse('Page not found', { status: 404 });
}
const page = pages.docs[0];
// Determine locale from searchParams or default to 'de'
const searchParams = req.nextUrl.searchParams;
const locale = (searchParams.get('locale') as 'en' | 'de') || 'de';
// Render the React-PDF document into a stream
const stream = await renderToStream(<PDFPage page={page} locale={locale} />);
// Pipe the Node.js Readable stream into a valid fetch/Web Response stream
const body = new ReadableStream({
start(controller) {
stream.on('data', (chunk) => controller.enqueue(chunk));
stream.on('end', () => controller.close());
stream.on('error', (err) => controller.error(err));
},
cancel() {
(stream as any).destroy?.();
},
});
const filename = `${slug}.pdf`;
return new NextResponse(body, {
status: 200,
headers: {
'Content-Type': 'application/pdf',
'Content-Disposition': `attachment; filename="${filename}"`,
// Cache control if needed, skip for now.
},
});
} catch (error) {
console.error('Error generating PDF:', error);
return new NextResponse('Internal Server Error', { status: 500 });
}
}