This commit is contained in:
betalabor.de
2026-04-27 19:29:23 +02:00
parent 50f02268d8
commit aa4057fd9d
13 changed files with 4195 additions and 733 deletions

View File

@@ -0,0 +1,121 @@
// printExport.js
// Einbinden: <script src="/scripts/printExport.js"></script>
// Aufruf: window.printCV(element, cvTitle, cvSettings, template)
window.printCV = async function (el, cvTitle, cvSettings, template) {
// ── 1. Lokale CSS-Datei direkt fetchen (kein CORS-Problem) ──────
let globalCss = '';
try {
globalCss = await fetch('/styles/global.css').then(r => r.text());
} catch (e) {
console.warn('global.css nicht geladen', e);
}
// ── 2. Inline <style> Tags sammeln (Astro Scoped CSS) ───────────
const inlineStyles = Array.from(document.querySelectorAll('style'))
.map(s => s.textContent).join('\n');
// ── 3. Google Fonts URL ─────────────────────────────────────────
const fontUrl = 'https://fonts.googleapis.com/css2?family=Inter:wght@400;600&family=Lora:ital,wght@0,400;0,600;1,400&family=Merriweather:wght@400;700&family=Montserrat:wght@300;400;600;700&family=Outfit:wght@300;400;600&family=Oswald:wght@400;600&family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=Roboto:wght@300;400;700&display=swap';
// ── 4. Sidebar-Body-Gradient (wiederholt sich auf jeder Seite) ──
const SIDEBAR_WIDTH = { 1: '220px', 2: '0', 3: '160px', 4: '240px' };
const sw = SIDEBAR_WIDTH[template] || '0';
const color = (cvSettings && cvSettings.primaryColor) || '#1B2A5E';
const sidebarCss = sw !== '0' ? `
body {
background: linear-gradient(to right, ${color} ${sw}, white ${sw}) !important;
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
/* Sidebar transparent Farbe kommt von body-Hintergrund */
.t1-sidebar { background: transparent !important; }
.t3-left { background: transparent !important; }
.t4-left { background: transparent !important; }
` : '';
// ── 5. Komplettes HTML zusammenbauen ────────────────────────────
const html = `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${cvTitle || 'Lebenslauf'}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="${fontUrl}" rel="stylesheet">
<style>
/* ── global.css ── */
${globalCss}
/* ── Astro Scoped Styles ── */
${inlineStyles}
/* ── Print Overrides (am Ende = höchste Priorität) ── */
@page {
size: A4 portrait;
margin: 0;
}
html {
margin: 0;
padding: 0;
}
body {
margin: 0 !important;
padding: 0 !important;
display: flex;
justify-content: center;
background: white;
}
${sidebarCss}
.cv-a4 {
width: 210mm !important;
min-height: 297mm !important;
box-shadow: none !important;
margin: 0 !important;
}
* {
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
.t1-entry, .t1-sec,
.t2-tl-item, .t2-sec,
.t3-entry, .t3-sec,
.t4-entry, .t4-sec {
break-inside: avoid;
}
</style>
</head>
<body>${el.innerHTML}</body>
</html>`;
// ── 6. Blob-URL statt document.write ────────────────────────────
const blob = new Blob([html], { type: 'text/html; charset=utf-8' });
const blobUrl = URL.createObjectURL(blob);
const win = window.open(blobUrl, '_blank', 'width=900,height=1200');
if (!win) {
alert('Popup wurde blockiert. Bitte Popup-Blocker deaktivieren.');
URL.revokeObjectURL(blobUrl);
return;
}
win.addEventListener('load', () => {
// Blob-URL freigeben sobald geladen
URL.revokeObjectURL(blobUrl);
// Fonts + base64-PNGs (Icons) etwas Zeit geben
setTimeout(() => {
win.focus();
win.print();
win.addEventListener('afterprint', () => win.close());
}, 1000);
});
};