layout
This commit is contained in:
59
src/pages/api/cv/[id]/pdf.ts
Normal file
59
src/pages/api/cv/[id]/pdf.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import type { APIRoute } from 'astro';
|
||||
import { getCVById, getProfileById } from '../../../../lib/db';
|
||||
|
||||
export const GET: APIRoute = async ({ params, locals, request }) => {
|
||||
const user = locals.user;
|
||||
const cv = getCVById(params.id!, user?.id);
|
||||
if (!cv) return new Response('Not Found', { status: 404 });
|
||||
|
||||
const profile = getProfileById(cv.profile_id, user?.id);
|
||||
if (!profile) return new Response('Profile Not Found', { status: 404 });
|
||||
|
||||
const name = [profile.data.personal.firstName, profile.data.personal.lastName]
|
||||
.filter(Boolean).join(' ') || cv.title;
|
||||
|
||||
const origin = new URL(request.url).origin;
|
||||
const targetUrl = `${origin}/cv/${cv.hash}`;
|
||||
|
||||
try {
|
||||
// Dynamic import – verhindert Vite-Verarbeitung
|
||||
const { default: puppeteer } = await import('puppeteer');
|
||||
|
||||
const browser = await puppeteer.launch({
|
||||
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'],
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
await page.setViewport({ width: 794, height: 1123 });
|
||||
await page.goto(targetUrl, { waitUntil: 'networkidle0', timeout: 20000 });
|
||||
|
||||
// Toolbar ausblenden
|
||||
await page.addStyleTag({
|
||||
content: `
|
||||
.cv-public-bar { display: none !important; }
|
||||
body { background: white !important; padding: 0 !important; }
|
||||
.cv-public-wrap { padding: 0 !important; background: white !important; }
|
||||
`
|
||||
});
|
||||
await page.emulateMediaType('print');
|
||||
const pdf = await page.pdf({
|
||||
format: 'A4',
|
||||
margin: { top: '0', right: '0', bottom: '0', left: '0' },
|
||||
printBackground: true,
|
||||
scale: 1,
|
||||
});
|
||||
|
||||
await browser.close();
|
||||
|
||||
return new Response(pdf, {
|
||||
headers: {
|
||||
'Content-Type': 'application/pdf',
|
||||
'Content-Disposition': `attachment; filename="${encodeURIComponent(name)}.pdf"`,
|
||||
},
|
||||
});
|
||||
|
||||
} catch (err: any) {
|
||||
console.error('[PDF]', err.message);
|
||||
return new Response(err.message, { status: 500 });
|
||||
}
|
||||
};
|
||||
57
src/pages/api/pdf/[hash].ts
Normal file
57
src/pages/api/pdf/[hash].ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import type { APIRoute } from 'astro';
|
||||
import { getCVByHash, getProfileById } from '../../../lib/db';
|
||||
|
||||
// Öffentlicher Endpunkt – kein Login nötig, CV muss public=1 sein
|
||||
export const GET: APIRoute = async ({ params, request }) => {
|
||||
const cv = getCVByHash(params.hash!);
|
||||
if (!cv) return new Response('Not Found', { status: 404 });
|
||||
|
||||
const profile = getProfileById(cv.profile_id);
|
||||
if (!profile) return new Response('Profile Not Found', { status: 404 });
|
||||
|
||||
const name = [profile.data.personal.firstName, profile.data.personal.lastName]
|
||||
.filter(Boolean).join(' ') || cv.title;
|
||||
|
||||
const origin = new URL(request.url).origin;
|
||||
const targetUrl = `${origin}/cv/${cv.hash}`;
|
||||
|
||||
try {
|
||||
const { default: puppeteer } = await import('puppeteer');
|
||||
|
||||
const browser = await puppeteer.launch({
|
||||
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'],
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
await page.setViewport({ width: 794, height: 1123 });
|
||||
await page.goto(targetUrl, { waitUntil: 'networkidle0', timeout: 20000 });
|
||||
|
||||
await page.addStyleTag({
|
||||
content: `
|
||||
.cv-public-bar { display: none !important; }
|
||||
body { background: white !important; padding: 0 !important; }
|
||||
.cv-public-wrap { padding: 0 !important; background: white !important; }
|
||||
`
|
||||
});
|
||||
|
||||
const pdf = await page.pdf({
|
||||
format: 'A4',
|
||||
margin: { top: '0mm', right: '0mm', bottom: '0mm', left: '0mm' },
|
||||
printBackground: true,
|
||||
displayHeaderFooter: false,
|
||||
});
|
||||
|
||||
await browser.close();
|
||||
|
||||
return new Response(pdf, {
|
||||
headers: {
|
||||
'Content-Type': 'application/pdf',
|
||||
'Content-Disposition': `attachment; filename="${encodeURIComponent(name)}.pdf"`,
|
||||
},
|
||||
});
|
||||
|
||||
} catch (err: any) {
|
||||
console.error('[PDF Hash]', err.message);
|
||||
return new Response(err.message, { status: 500 });
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user