From 6925ffee45c4b81758f09953b6bb7687de9bbeae Mon Sep 17 00:00:00 2001 From: Peter Meier Date: Fri, 19 Jun 2026 13:50:09 +0200 Subject: [PATCH] feat(termin): vollwertige Detailseite + QR/Detail-Link im Kalender MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /termin/ ist jetzt echte Seite statt Redirect: - alle Infos ungekürzt (Datum/Zeit in Europe/Berlin, Ort+Maps, Tags, Bild+Lightbox, volle Beschreibung, Anhang, externer Link) - alle Aktionen: ICS, Google, Link kopieren, Teilen, QR, Social-Bild - Link zum Kalender drunter (kein Auto-Redirect mehr) - Breite via Layout-.container-custom (gleich wie andere Seiten) - SEO: OG/Twitter/canonical zentral aus Layout (kein Doppel-Tag), Event-JSON-LD + Breadcrumb für Rich Results / Share-Preview CalendarBlock: QR-Button + "Details →"-Link je Termin (→ /termin//). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../components/blocks/CalendarBlock.svelte | 47 ++- src/routes/termin/[slug]/+page.server.ts | 148 ++++++++-- src/routes/termin/[slug]/+page.svelte | 274 ++++++++++++++++-- 3 files changed, 413 insertions(+), 56 deletions(-) diff --git a/src/lib/components/blocks/CalendarBlock.svelte b/src/lib/components/blocks/CalendarBlock.svelte index a04d8c6..b5f5962 100644 --- a/src/lib/components/blocks/CalendarBlock.svelte +++ b/src/lib/components/blocks/CalendarBlock.svelte @@ -17,6 +17,7 @@ import Icon from "@iconify/svelte"; import ImageModal from "$lib/components/ImageModal.svelte"; import SocialImageModal from "$lib/components/SocialImageModal.svelte"; + import QrModal from "$lib/components/QrModal.svelte"; type EventCardItem = CalendarItemData & { start: Date; @@ -458,6 +459,18 @@ socialModal = null; } + // QR-Code zum direkten Ausgeben/Scannen (Aushang, Infostand). Nutzt die + // canonical /termin/-URL (hat OG-Tags + Redirect), Fallback = Hash- + // Anchor im Kalender wenn kein Slug. + let qrModal = $state<{ value: string; label: string } | null>(null); + + function openQr(item: EventCardItem) { + const url = item._slug + ? `${window.location.origin}/termin/${encodeURIComponent(item._slug)}/` + : `${window.location.origin}${window.location.pathname}#${eventId(item)}`; + qrModal = { value: url, label: item.title || "Termin" }; + } + function eventId(item: EventCardItem): string { if (item._slug) return `event-${item._slug}`; const titlePart = (item.title || "event") @@ -781,8 +794,21 @@
- {#if eventHref || locText || item.attachment?.src} + {#if item._slug || eventHref || locText || item.attachment?.src} {/if} @@ -1325,6 +1361,15 @@ /> {/if} +{#if qrModal} + (qrModal = null)} + /> +{/if} +