presseportale/resources/views/web/legal-request.blade.php
Kevin Adametz 9afbedddeb recht: Meldeverfahren v2 Phasen 5+7 — DSGVO-Strukturformular, 10-€-Checkout mit KI-Vorprüfung, Triage & Panel-Modal
Phase 7 (Spur D, E2 revidiert): KI-Vorprüfung VOR der Zahlung im Modal —
rot lehnt ohne Zahlung ab, gelb/grün führt zum Stripe-Checkout
(SinglePurchaseType::Change, 10 € netto), nach Zahlungseingang übernimmt
der Webhook die geprüfte Fassung sofort (applyPaid: Snapshot, Sperre,
Verlauf). Nur einmal je PM; Obergrenze legal.change_max_distance_percent
(50 %) verhindert die verdeckte Selbst-Depublizierung.

Phase 5 (Spur B): strukturiertes Schwärzungsformular mit Pflicht-Vorschau
im verifizierten Web-Bereich UND als Modal im Kunden-Panel; Admin-Editor
wird aus payload.redaction vorbefüllt. Umsetzungsmail LegalRequestExecuted
an Antragsteller, Bestätigungsmail PressReleaseChangeApplied (Spur A/D,
neuer abbestellbarer Typ press_release_corrected).

Außerdem:
- Re-Sync-Sperre + Sitemap-Invalidierung fest in depublish() verankert
  (Lücke im bezahlten Webhook-Pfad geschlossen)
- Öffentliche „Rechtliches"-Seite als zweistufige Triage: primär der
  Portal-Anmeldelink, Formular nur Fallback mit Identifizierungs-Hinweis;
  Store auf report/dsgvo/personal_rights gehärtet
- Panel-Button „Ändern/Melden" öffnet Anliegen-Modal (4 Spuren) statt
  des Web-Formulars
- Pressekontakt-Fallback für Legacy-Bestände (30k PMs ohne Verknüpfung):
  Detailseite + pressContactEmail() nutzen PM-Kontakt → Firmen-Kontakt →
  Firmendaten
- Korrektur-Gate entity-fest (Editor-Normalisierung zählt nicht als
  Änderung), toEditorHtml() in Admin-Edit + Korrektur-Panel,
  Wochenlimit-Hinweis in Text und Bremsen-Meldung

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 13:02:57 +00:00

244 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@extends('web.layouts.web-master')
@section('title', 'Recht & Compliance – '.$release->title)
@section('meta_description', 'Datenschutz-, Persönlichkeitsrechts- oder Meldeanfrage zu einer Pressemitteilung.')
@section('content')
{{--
Zweistufige Triage (Meldeverfahren v2, 23.07.2026): Stufe 1 wählt das
Anliegen, Stufe 2 zeigt den passenden Weg. Absender-Anliegen und
DSGVO/Persönlichkeitsrechte werden primär auf den passwortlosen
Anmeldelink ins Portal (pressekonto /anmeldelink) geleitet — dort werden
die PMs der Kontaktadresse im Konto zusammengeführt und alle
Selbstservice-Funktionen stehen bereit. Das Kontaktformular ist nur der
Fallback und weist auf die notwendige persönliche Identifizierung hin.
Meldungen rechtswidriger Inhalte gehen direkt ins Formular (DSA: jede
dritte Person darf melden).
Hinweistexte folgen dem am 06.07. freigegebenen Meldeverfahren v0.1;
die anwaltliche Freigabe des Rechtstexte-Pakets [EXTERN] umfasst auch
diese Texte.
--}}
<style>[x-cloak]{display:none!important}</style>
<section
x-data="{
concern: @js(old('type', $initialConcern)),
showFallback: @js(in_array(old('type'), ['dsgvo', 'personal_rights'], true)),
pick(value) { this.concern = value; this.showFallback = false; },
needsFallbackToggle() { return ['dsgvo', 'personal_rights'].includes(this.concern); },
formVisible() { return this.concern === 'report' || (this.needsFallbackToggle() && this.showFallback); },
emailRequired() { return ['dsgvo', 'personal_rights'].includes(this.concern); }
}"
class="max-w-2xl mx-auto px-4 sm:px-6 lg:px-8 py-10"
>
<a href="{{ route('release.detail', ['slug' => $release->slug]) }}"
class="text-[12px] text-ink-3 hover:text-ink transition-colors">← Zurück zur Pressemitteilung</a>
<div class="eyebrow muted text-[10px] mt-4 mb-2">Recht &amp; Compliance</div>
<h1 class="font-serif text-[26px] font-semibold tracking-[-0.3px] m-0 mb-2 text-ink">
Anfrage zu dieser Pressemitteilung
</h1>
<p class="text-[13px] text-ink-3 mb-1">
Betrifft: <span class="text-ink-2 font-medium">{{ $release->title }}</span>
</p>
<p class="text-[12.5px] text-ink-3 leading-relaxed mb-6">
Bitte wählen Sie zuerst Ihr Anliegen — dazu erscheint der passende Weg.
Viele Anliegen können Sie nach einer kurzen Verifizierung direkt selbst
anstoßen; alle Prüfungen sind kostenlos.
</p>
@if (session('legal-status'))
<div class="mb-6 px-4 py-3 border border-bg-rule bg-bg-elev text-[13px] text-ink-2" role="status">
{{ session('legal-status') }}
</div>
@endif
{{-- ===== Stufe 1: Anliegen wählen ===== --}}
<fieldset class="mb-6">
<legend class="block text-[12px] font-semibold text-ink mb-2">Was möchten Sie tun?</legend>
<div class="space-y-2">
@foreach ([
'owner' => ['label' => 'Korrektur, Änderung oder Depublizierung', 'desc' => 'Sie sind Absender oder hinterlegter Pressekontakt und möchten Inhalte korrigieren, ändern oder die Mitteilung offline nehmen.', 'badge' => 'Selbstservice'],
'dsgvo' => ['label' => 'Entfernung persönlicher Daten (DSGVO)', 'desc' => 'Ihr Name oder Ihre Kontaktdaten erscheinen in dieser Mitteilung und sollen entfernt werden (Art. 17 DSGVO).', 'badge' => 'kostenlos'],
'personal_rights' => ['label' => 'Verletzung von Persönlichkeitsrechten', 'desc' => 'Unwahre Tatsachenbehauptungen, Bild- oder Namensrechte — die Mitteilung betrifft Sie persönlich.', 'badge' => 'kostenlos'],
'report' => ['label' => 'Rechtswidrige Inhalte melden', 'desc' => 'Urheberrechts- oder Markenverletzung, irreführende Inhalte, Spam — Meldung als dritte Person, auch ohne eigene Betroffenheit.', 'badge' => 'kostenlos'],
] as $value => $card)
<label class="flex items-start gap-3 border border-bg-rule px-3 py-2.5 cursor-pointer hover:bg-bg-elev"
:class="concern === '{{ $value }}' ? 'border-brand bg-bg-elev' : ''">
<input type="radio" name="concern_choice" value="{{ $value }}" class="mt-0.5"
@change="pick('{{ $value }}')"
:checked="concern === '{{ $value }}'" />
<span class="text-[13px] text-ink">
<span class="font-semibold">{{ $card['label'] }}</span>
<span class="text-ink-3">· {{ $card['badge'] }}</span>
<span class="block text-[12.5px] text-ink-2">{{ $card['desc'] }}</span>
</span>
</label>
@endforeach
</div>
</fieldset>
{{-- ===== Stufe 2a: Absender-Anliegen → passwortloser Portal-Login ===== --}}
<div x-cloak x-show="concern === 'owner'" class="space-y-4">
<div class="px-4 py-3 border border-bg-rule bg-bg-elev text-[12.5px] text-ink-2 leading-relaxed">
<strong class="text-ink">So funktioniert es:</strong>
Fordern Sie im Portal einen passwortlosen Anmeldelink an Ihre hinterlegte
Pressekontakt- oder Firmenadresse an. Nach dem Klick sind Sie angemeldet und
Ihre Pressemitteilungen werden in Ihrem Konto zusammengeführt — dort können
Sie kleine Korrekturen kostenlos und sofort umsetzen, größere Änderungen
(10&nbsp;€) und die Depublizierung (35&nbsp;€) direkt beauftragen.
</div>
<a href="{{ $portalMagicLinkUrl }}"
class="inline-flex items-center px-5 py-2.5 bg-brand text-white text-[13px] font-semibold hover:opacity-90">
Anmeldelink im Portal anfordern
</a>
<p class="text-[12px] text-ink-3 leading-relaxed">
Keine erreichbare Pressekontaktadresse mehr? Dann nutzen Sie bitte das
Formular unter „Entfernung persönlicher Daten" bzw. die manuelle Prüfung
über das <a href="{{ route('melden') }}" class="underline hover:text-ink">Meldeverfahren</a> —
wir verifizieren Ihre Berechtigung anhand eines Nachweises.
</p>
</div>
{{-- ===== Stufe 2b: DSGVO ===== --}}
<div x-cloak x-show="concern === 'dsgvo'" class="space-y-4">
<div class="px-4 py-3 border border-bg-rule bg-bg-elev text-[12.5px] text-ink-2 leading-relaxed">
<strong class="text-ink">Datenschutz / DSGVO:</strong>
Als natürliche Person können Sie die Entfernung, Ersetzung oder
Anonymisierung Ihrer persönlichen Daten in dieser Pressemitteilung
verlangen (Art. 17 DSGVO) — zum Beispiel Name, Telefonnummer oder
E-Mail-Adresse. Die Prüfung und Bearbeitung ist für Sie kostenlos. Die
Pressemitteilung selbst bleibt nach der Entfernung Ihrer Daten
grundsätzlich bestehen.
</div>
<div class="px-4 py-3 border border-bg-rule text-[12.5px] text-ink-2 leading-relaxed">
<strong class="text-ink">Empfohlener Weg — passwortloser Anmeldelink ins Portal:</strong>
Sind Sie die in der Veröffentlichung hinterlegte Kontaktperson (oder haben
Zugriff auf deren Postfach), melden Sie sich per Anmeldelink im Portal an —
Ihre Mitteilungen werden dort in Ihrem Konto zusammengeführt und Sie geben
die zu entfernenden Angaben direkt mit Vorschau an. Der schnellste Weg.
</div>
<a href="{{ $portalMagicLinkUrl }}"
class="inline-flex items-center px-5 py-2.5 bg-brand text-white text-[13px] font-semibold hover:opacity-90">
Anmeldelink im Portal anfordern
</a>
<p>
<button type="button" @click="showFallback = true" x-show="!showFallback"
class="text-[12.5px] text-ink-2 underline underline-offset-2 hover:text-ink">
Ich bin nicht der hinterlegte Pressekontakt oder habe keinen Zugriff auf das Postfach
</button>
</p>
</div>
{{-- ===== Stufe 2c: Persönlichkeitsrechte ===== --}}
<div x-cloak x-show="concern === 'personal_rights'" class="space-y-4">
<div class="px-4 py-3 border border-bg-rule bg-bg-elev text-[12.5px] text-ink-2 leading-relaxed">
<strong class="text-ink">Persönlichkeitsrecht:</strong>
Wenn diese Mitteilung Ihre Persönlichkeitsrechte verletzt — z.&nbsp;B.
durch unwahre Tatsachenbehauptungen oder die Verletzung von Bild- oder
Namensrechten —, prüfen wir Ihre Anfrage sorgfältig und zeitnah und teilen
Ihnen unsere Entscheidung mit Begründung mit; bei berechtigten
Beanstandungen wird der Inhalt angepasst, gesperrt oder entfernt. Die
Prüfung ist kostenlos.
</div>
<div class="px-4 py-3 border border-bg-rule text-[12.5px] text-ink-2 leading-relaxed">
<strong class="text-ink">Schnellster Weg — passwortloser Anmeldelink ins Portal:</strong>
Sind Sie zugleich die hinterlegte Kontaktperson dieser Veröffentlichung,
melden Sie sich per Anmeldelink im Portal an und stoßen die Anpassung
direkt in Ihrem Konto an.
</div>
<a href="{{ $portalMagicLinkUrl }}"
class="inline-flex items-center px-5 py-2.5 bg-brand text-white text-[13px] font-semibold hover:opacity-90">
Anmeldelink im Portal anfordern
</a>
<p>
<button type="button" @click="showFallback = true" x-show="!showFallback"
class="text-[12.5px] text-ink-2 underline underline-offset-2 hover:text-ink">
Ich bin nicht der hinterlegte Pressekontakt — Anfrage per Formular stellen
</button>
</p>
</div>
{{-- ===== Stufe 2d: Meldung → direkt zum Formular ===== --}}
<div x-cloak x-show="concern === 'report'"
class="mb-4 px-4 py-3 border border-bg-rule bg-bg-elev text-[12.5px] text-ink-2 leading-relaxed">
<strong class="text-ink">Meldung:</strong>
Melden Sie diese Pressemitteilung, wenn Sie sie für rechtswidrig halten
oder sie Ihre Rechte verletzt — z.&nbsp;B. unwahre Tatsachenbehauptungen,
Urheberrechts- oder Markenverletzungen, irreführende Inhalte oder Spam.
Bitte benennen Sie konkret, welche Inhalte betroffen sind und warum.
Jede Meldung wird von unserem Team manuell geprüft; die Meldung ist
kostenlos. Wenn Sie eine E-Mail-Adresse angeben, erhalten Sie unverzüglich
eine Eingangsbestätigung mit Vorgangsnummer und anschließend unsere
Entscheidung mit Begründung.
</div>
{{-- ===== Formular: direkt (Meldung) bzw. Fallback (DSGVO/Persönlichkeitsrecht) ===== --}}
<form x-cloak x-show="formVisible()" method="POST"
action="{{ route('legal-request.store', ['slug' => $release->slug]) }}" class="space-y-5 mt-2">
@csrf
<input type="hidden" name="type" :value="concern" />
{{-- Identifizierungs-Hinweis nur im Fallback-Weg (DSGVO/Persönlichkeitsrecht). --}}
<div x-cloak x-show="needsFallbackToggle()"
class="px-4 py-3 border-l-2 border border-bg-rule text-[12.5px] text-ink-2 leading-relaxed">
<strong class="text-ink">Wichtig — persönliche Identifizierung erforderlich:</strong>
Da personenbezogene Daten bzw. Persönlichkeitsrechte betroffen sind, müssen
wir Ihre Berechtigung prüfen. In der Regel senden wir einen Bestätigungslink
an die betroffene Adresse; andernfalls können wir einen geeigneten
Identitäts- oder Berechtigungsnachweis verlangen. Sie erhalten unverzüglich
eine Eingangsbestätigung mit Vorgangsnummer.
</div>
<div>
<label for="requester_email" class="block text-[12px] font-semibold text-ink mb-1.5">
E-Mail-Adresse
<span class="text-ink-3 font-normal" x-show="emailRequired()">(erforderlich)</span>
<span class="text-ink-3 font-normal" x-show="!emailRequired()" x-cloak>(optional)</span>
</label>
<input id="requester_email" type="email" name="requester_email" value="{{ old('requester_email') }}"
autocomplete="email"
class="w-full border border-bg-rule px-3 py-2.5 text-[13px] bg-white text-ink focus:outline-none focus:border-brand" />
@error('requester_email')
<p class="mt-1 text-[12px] text-red-600">{{ $message }}</p>
@enderror
</div>
<div>
<label for="message" class="block text-[12px] font-semibold text-ink mb-1.5">Ihr Anliegen</label>
<textarea id="message" name="message" rows="6" required
class="w-full border border-bg-rule px-3 py-2.5 text-[13px] bg-white text-ink focus:outline-none focus:border-brand"
placeholder="Bitte beschreiben Sie Ihr Anliegen.">{{ old('message') }}</textarea>
@error('message')
<p class="mt-1 text-[12px] text-red-600">{{ $message }}</p>
@enderror
</div>
{{--
Bot-Schutz: versteckte Honeypot-Felder. Für Menschen unsichtbar
(display:none via .hidden), für Bots aber im DOM. Werden sie ausgefüllt,
verwirft der Controller die Anfrage still. Die Namen ('website',
'homepage') sind bewusst „attraktiv" für Auto-Filler. Zusätzlich greift
serverseitig ein Rate-Limit pro IP/PM.
--}}
<div class="hidden" aria-hidden="true">
<label for="website">Website</label>
<input id="website" type="text" name="website" tabindex="-1" autocomplete="off" value="{{ old('website') }}" />
<label for="homepage">Homepage</label>
<input id="homepage" type="text" name="homepage" tabindex="-1" autocomplete="off" value="{{ old('homepage') }}" />
</div>
<button type="submit"
class="bg-brand hover:bg-brand-deep text-white px-5 py-2.5 text-[13px] font-semibold transition-colors">
Anfrage absenden
</button>
</form>
<p class="mt-6 text-[11.5px] text-ink-3 leading-relaxed">
Hinweis: Diese Angaben werden ausschließlich zur Bearbeitung Ihrer Anfrage
verarbeitet. Weitere Informationen in der
<a href="{{ route('datenschutz') }}" class="underline hover:text-ink">Datenschutzerklärung</a>.
Einzelheiten zum Ablauf aller Meldewege finden Sie im
<a href="{{ route('melden') }}" class="underline hover:text-ink">Meldeverfahren</a>.
</p>
</section>
@endsection