web/admin/pdf: gemeinsame Bildnachweis-Auflösung, Detailfenster am Artikelbild, Bestätigungsstand in Kunden- und Adminansicht, Wortwahl „automatisierte Prüfung" (Bildkennzeichnung Block D)

- App\Support\ImageCredit: Foto/Quelle-Zeile, KI-Hinweis mit Herkunft, Verantwortlich-Zeile nur mit Protokoll, sichere Links; PDF-Zeilen mit Bestätigungskennung
- Artikelseite: Overlay (eigenes i-Zeichen, Alpine ohne Plugin, Bottom-Sheet auf Mobil) mit Nachweis, Lizenz, Quelle, KI-Hinweis, Verantwortlich-Zeile, „Bild melden"
- Richtlinien 0.2: Prüfung als automatisiert beschrieben, Abschnitt „Bilder" (Decision-Update 3.5); Taglines, Suche, Newsrooms, Startseiten-CTA, Mails ohne „qualitätsgeprüft"
- Cache-Invalidierung bei Bildwechsel an veröffentlichten Meldungen; PHPStan-Baseline für das Resource bereinigt

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-09-22 09:44:34 +00:00
parent 65ac72ce05
commit 2124ffd1f2
26 changed files with 578 additions and 199 deletions

View file

@ -213,14 +213,25 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung')] class extends
@php
$adminTitleImage = $pr->images->sortByDesc('is_preview')->first();
@endphp
@if ($adminTitleImage && ($adminTitleImage->copyright || $adminTitleImage->is_ai_generated || $adminTitleImage->ai_declaration?->publicLabel()))
{{-- Bildnachweis + KI-Kennzeichnung (Art. 50 EU AI Act) --}}
@if ($adminTitleImage && ($adminCreditInfo = \App\Support\ImageCredit::for($adminTitleImage, $pr->company))->hasDetails())
{{-- Bildnachweis, KI-Kennzeichnung, Herkunft und Bestätigungsstand
(Bildkennzeichnung D.1/D.3) --}}
<div class="flex flex-wrap items-center gap-2 border-t border-[color:var(--color-bg-rule)] px-5 py-2.5 text-[12px] text-[color:var(--color-ink-3)]">
@if ($aiImageBadge = $adminTitleImage->ai_declaration?->publicLabel() ?? ($adminTitleImage->is_ai_generated ? __('KI-generiert') : null))
<span class="badge hub">{{ $aiImageBadge }}</span>
@if ($adminCreditInfo->aiLabel)
<span class="badge hub">{{ $adminCreditInfo->aiLabel }}</span>
@if ($adminCreditInfo->aiSourceLabel)
<span class="text-[color:var(--color-ink-4)]">({{ $adminCreditInfo->aiSourceLabel }})</span>
@endif
@endif
@if ($adminTitleImage->copyright)
<span>{{ $adminTitleImage->copyright }}</span>
@if ($adminCreditInfo->credit)
<span>{{ $adminCreditInfo->creditLabel }}: {{ $adminCreditInfo->credit }}</span>
@endif
@if ($adminCreditInfo->confirmation)
<span class="text-[color:var(--color-ink-4)]">· {{ __('Rechte bestätigt am :date (:key, AGB :agb, :channel)', ['date' => $adminCreditInfo->confirmation->confirmed_at->format('d.m.Y H:i'), 'key' => $adminCreditInfo->confirmation->legal_text_key, 'agb' => $adminCreditInfo->confirmation->agb_version ?? '–', 'channel' => $adminCreditInfo->confirmation->channel->value]) }}</span>
@elseif ($adminTitleImage->awaitsCustomerConfirmation())
<span class="badge">{{ __('wartet auf Kundenbestätigung') }}</span>
@elseif ($adminCreditInfo->isLegacy)
<span class="text-[color:var(--color-ink-4)]">· {{ __('Bestand ohne Bestätigungsprotokoll') }}</span>
@endif
</div>
@endif

View file

@ -1748,15 +1748,20 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung')] class extends
<flux:icon.photo variant="micro" class="size-3.5" />
<span>{{ __('Platzhalter-Titelbild — laden Sie im Editor ein eigenes Bild hoch.') }}</span>
</div>
@elseif ($titleImage && ($titleImage->copyright || $titleImage->is_ai_generated || $titleImage->ai_declaration?->publicLabel()))
{{-- Bildnachweis + KI-Kennzeichnung (Art. 50 EU AI Act): kurzes
Badge („KI-generiert" / „KI-bearbeitet"), kein Satz-Wortlaut. --}}
@elseif ($titleImage && ($imageCreditInfo = \App\Support\ImageCredit::for($titleImage, $pr->company))->hasDetails())
{{-- Bildnachweis, KI-Kennzeichnung und Bestätigungsstand aus der
gemeinsamen Auflösung (Bildkennzeichnung D.1/D.3). --}}
<div class="flex flex-wrap items-center gap-2 border-t border-[color:var(--color-bg-rule)] px-5 py-2.5 text-[12px] text-[color:var(--color-ink-3)]">
@if ($aiImageBadge = $titleImage->ai_declaration?->publicLabel() ?? ($titleImage->is_ai_generated ? __('KI-generiert') : null))
<span class="badge hub">{{ $aiImageBadge }}</span>
@if ($imageCreditInfo->aiLabel)
<span class="badge hub">{{ $imageCreditInfo->aiLabel }}</span>
@endif
@if ($titleImage->copyright)
<span>{{ $titleImage->copyright }}</span>
@if ($imageCreditInfo->credit)
<span>{{ $imageCreditInfo->creditLabel }}: {{ $imageCreditInfo->credit }}</span>
@endif
@if ($imageCreditInfo->confirmation)
<span class="text-[color:var(--color-ink-4)]">· {{ __('Rechte bestätigt am :date (:key, AGB :agb, :channel)', ['date' => $imageCreditInfo->confirmation->confirmed_at->format('d.m.Y H:i'), 'key' => $imageCreditInfo->confirmation->legal_text_key, 'agb' => $imageCreditInfo->confirmation->agb_version ?? '–', 'channel' => $imageCreditInfo->confirmation->channel->value]) }}</span>
@elseif ($titleImage->awaitsCustomerConfirmation())
<span class="badge">{{ __('wartet auf Ihre Bestätigung') }}</span>
@endif
</div>
@endif