feat(legal): Claims-Korrektur, zentrale Legal-Config & öffentliche Rechtsseiten (v1.7.0)
Teil 1 des Compliance-Updates (nach vollständiger Repo-Analyse): - src/config/legal.ts: zentrale, typisierte Betreiber-/Rechtskonfiguration mit sichtbaren Platzhaltern, ENV-Overrides (LEGAL_*), Build-Warnung bei offenen Pflichtangaben, echte Subprozessorenliste (aus dem Code abgeleitet) - Claims-Korrektur (20 Aussagen): 24/7, 100% Swiss Hosted, DSG/DSGVO-konform, 100% der Spende, Kein Unternehmen, "bleibt kostenlos", "sicher via Stripe", "keine Weitergabe/keine Übermittlung ins Ausland", "verschlüsselt"→"gehasht" — in page.tsx, spenden, impressum, datenschutz (Neuaufbau), settings-tab - Neue Legal-Seiten (druckbar, responsiv, versioniert, als Entwurf gekennzeichnet): /nutzungsbedingungen, /verantwortungsvolle-nutzung, /sicherheit, /unterstuetzen, /organisationen/datenschutzvereinbarung + wiederverwendbare LegalPage-Shell - Datenschutz komplett neu aufgebaut: Subprozessoren-Tabelle (#dienstleister), Auslandbekanntgabe, gehashte Passwörter, Backups/Löschung, Zahlung (Stripe), Karten/Geodienste, Rechte/EDÖB - Footer um alle Pflicht-Rechtslinks erweitert; sitemap.ts ergänzt - docs/legal/website-claims-audit.md Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
91
src/components/legal/legal-page.tsx
Normal file
91
src/components/legal/legal-page.tsx
Normal file
@@ -0,0 +1,91 @@
|
||||
'use client'
|
||||
|
||||
import Link from 'next/link'
|
||||
import { ArrowLeft, Printer } from 'lucide-react'
|
||||
import { legal } from '@/config/legal'
|
||||
|
||||
/** Pflicht-Links, die im Footer jeder öffentlichen (Rechts-)Seite erscheinen. */
|
||||
export const LEGAL_LINKS: { href: string; label: string }[] = [
|
||||
{ href: '/impressum', label: 'Impressum' },
|
||||
{ href: '/datenschutz', label: 'Datenschutz' },
|
||||
{ href: '/nutzungsbedingungen', label: 'Nutzungsbedingungen' },
|
||||
{ href: '/verantwortungsvolle-nutzung', label: 'Verantwortungsvolle Nutzung' },
|
||||
{ href: '/sicherheit', label: 'Sicherheit' },
|
||||
{ href: '/organisationen/datenschutzvereinbarung', label: 'Datenschutzvereinbarung (Org.)' },
|
||||
{ href: '/unterstuetzen', label: 'Unterstützen' },
|
||||
]
|
||||
|
||||
export function LegalFooterLinks() {
|
||||
return (
|
||||
<nav aria-label="Rechtliche Seiten" className="mt-10 border-t border-border pt-6 print:hidden">
|
||||
<ul className="flex flex-wrap gap-x-4 gap-y-2 text-sm text-muted-foreground">
|
||||
{LEGAL_LINKS.map(l => (
|
||||
<li key={l.href}>
|
||||
<Link href={l.href} className="hover:text-foreground underline underline-offset-2">{l.label}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
interface LegalPageProps {
|
||||
title: string
|
||||
/** Versionsangabe, z.B. legal.documents.terms.version */
|
||||
version?: string
|
||||
/** Veröffentlichungsdatum ISO */
|
||||
publishedAt?: string
|
||||
/** Als sorgfältiger Entwurf kennzeichnen (juristisch noch nicht geprüft) */
|
||||
draft?: boolean
|
||||
/** Kurzer Einleitungssatz unter dem Titel */
|
||||
intro?: string
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
/**
|
||||
* Einheitliche, responsive, druckbare Hülle für alle öffentlichen Rechtsseiten.
|
||||
* Enthält Zurück-Link, Drucken-Button, Version/Datum, Entwurfshinweis und die Pflicht-Footer-Links.
|
||||
*/
|
||||
export function LegalPage({ title, version, publishedAt, draft = true, intro, children }: LegalPageProps) {
|
||||
return (
|
||||
<div className="min-h-screen bg-background px-4 py-10 print:py-0 print:bg-white">
|
||||
<div className="max-w-3xl mx-auto">
|
||||
<div className="flex items-center justify-between mb-6 print:hidden">
|
||||
<Link href="/" className="text-sm text-muted-foreground hover:text-foreground inline-flex items-center gap-1">
|
||||
<ArrowLeft className="w-3.5 h-3.5" /> Zur Startseite
|
||||
</Link>
|
||||
<button
|
||||
onClick={() => window.print()}
|
||||
className="text-sm text-muted-foreground hover:text-foreground inline-flex items-center gap-1"
|
||||
>
|
||||
<Printer className="w-3.5 h-3.5" /> Drucken
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<article className="bg-card rounded-xl border border-border shadow-sm p-6 md:p-10 print:border-0 print:shadow-none print:p-0">
|
||||
<h1 className="text-3xl font-bold text-foreground">{title}</h1>
|
||||
|
||||
<div className="mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground">
|
||||
{version && <span>Version {version}</span>}
|
||||
{publishedAt && <span>· Stand: {publishedAt}</span>}
|
||||
<span>· {legal.projectName} ({legal.siteDomain})</span>
|
||||
</div>
|
||||
|
||||
{intro && <p className="mt-4 text-sm text-muted-foreground leading-relaxed">{intro}</p>}
|
||||
|
||||
{draft && (
|
||||
<div className="mt-4 rounded-lg border border-amber-300 bg-amber-50 dark:bg-amber-950/30 dark:border-amber-800 px-4 py-3 text-sm text-amber-800 dark:text-amber-300">
|
||||
<strong>Sorgfältiger Entwurf.</strong> {legal.draftNotice}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="legal-prose mt-6 space-y-6 text-sm leading-relaxed text-muted-foreground [&_h2]:text-lg [&_h2]:font-semibold [&_h2]:text-foreground [&_h2]:mb-2 [&_h2]:mt-2 [&_h3]:font-semibold [&_h3]:text-foreground [&_strong]:text-foreground [&_a]:text-red-600 [&_a]:underline [&_ul]:list-disc [&_ul]:pl-5 [&_ul]:space-y-1 [&_ol]:list-decimal [&_ol]:pl-5 [&_ol]:space-y-1">
|
||||
{children}
|
||||
</div>
|
||||
|
||||
<LegalFooterLinks />
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user