Generate Muster-Widerrufsformular PDF live from company-settings instead of a static upload

The "An:" address used to be baked into a hand-crafted PDF and silently
went stale whenever an admin updated the Impressum's Anbieterdaten
without also re-exporting/re-uploading the file by hand — exactly what
happened 2026-07-29. New /api/muster-widerrufsformular route renders it
on-the-fly via @react-pdf/renderer using the same getCompanySettings()
data as AnbieterAngaben.tsx's Impressum block, so the two can never drift
apart again. Disables react-pdf's default hyphenation, which otherwise
split the seller's email address mid-word to fit the line.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Marco
2026-07-29 22:30:51 +00:00
parent 22fef4fe49
commit 70abe20250
2 changed files with 169 additions and 10 deletions
+14 -10
View File
@@ -75,14 +75,19 @@ export default async function WiderrufPage() {
<p className="text-body text-text-muted">Inhalte werden gerade aktualisiert.</p>
)}
{page?.attachment && (
<a
href={page.attachment.url}
target="_blank"
rel="noopener noreferrer"
download
className="group flex items-center gap-5 bg-bg-muted hover:bg-bg-white border border-border rounded-md p-6 transition-colors"
>
{/* Generated live from company-settings (/api/muster-widerrufsformular)
instead of the CMS attachment field — see that route's own
comment on why: the static uploaded PDF's "An:" address
silently went stale whenever an admin updated the
Impressum's Anbieterdaten without also re-exporting this
file by hand. */}
<a
href="/api/muster-widerrufsformular"
target="_blank"
rel="noopener noreferrer"
download="Muster-Widerrufsformular.pdf"
className="group flex items-center gap-5 bg-bg-muted hover:bg-bg-white border border-border rounded-md p-6 transition-colors"
>
<div className="flex size-12 shrink-0 items-center justify-center rounded-sm bg-bg-white border border-border text-brand">
<svg viewBox="0 0 24 24" className="size-6" fill="none" aria-hidden="true">
<path
@@ -103,7 +108,7 @@ export default async function WiderrufPage() {
</div>
<div className="flex flex-col gap-0.5 flex-1 min-w-0">
<p className="font-semibold text-body text-text-primary">
{page.attachment.title || "Muster-Widerrufsformular (PDF)"}
Muster-Widerrufsformular (PDF)
</p>
<p className="text-body-sm text-text-muted">Herunterladen</p>
</div>
@@ -116,7 +121,6 @@ export default async function WiderrufPage() {
<path d="M12 4v13m0 0-5-5m5 5 5-5M5 21h14" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</a>
)}
</div>
</div>