diff --git a/app/src/routes/admin/stations/+page.svelte b/app/src/routes/admin/stations/+page.svelte index 5df72ad..1802b0b 100644 --- a/app/src/routes/admin/stations/+page.svelte +++ b/app/src/routes/admin/stations/+page.svelte @@ -29,12 +29,10 @@ }); stations = result; - // QR-Codes generieren + // QR-Codes mit Logo generieren const codes: Record = {}; for (const s of result) { - codes[s.qr_id] = await QRCode.toDataURL(qrUrl(s.qr_id), { - width: 200, margin: 1, color: { dark: '#0B1023', light: '#ffffff' } - }); + codes[s.qr_id] = await generateQRWithLogo(qrUrl(s.qr_id)); } qrCodes = codes; } catch { @@ -47,6 +45,41 @@ return `https://checkflo.de/s/${qrId}`; } + async function generateQRWithLogo(url: string): Promise { + const size = 400; + const canvas = document.createElement('canvas'); + canvas.width = size; + canvas.height = size; + + await QRCode.toCanvas(canvas, url, { + width: size, + margin: 1, + errorCorrectionLevel: 'H', + color: { dark: '#0B1023', light: '#ffffff' } + }); + + const ctx = canvas.getContext('2d')!; + const logoSize = Math.round(size * 0.22); + const x = (size - logoSize) / 2; + const y = (size - logoSize) / 2; + const pad = 6; + const r = 10; + + // Weißer abgerundeter Hintergrund + ctx.fillStyle = '#ffffff'; + ctx.beginPath(); + ctx.roundRect(x - pad, y - pad, logoSize + pad * 2, logoSize + pad * 2, r); + ctx.fill(); + + // Logo laden und zeichnen + const img = new Image(); + img.src = '/favicon.svg'; + await new Promise(resolve => { img.onload = () => resolve(); }); + ctx.drawImage(img, x, y, logoSize, logoSize); + + return canvas.toDataURL('image/png'); + } + function printAll() { window.print(); }