sortBy === $column) { $this->sortDir = $this->sortDir === 'asc' ? 'desc' : 'asc'; } else { $this->sortBy = $column; $this->sortDir = 'asc'; } $this->resetPage(); } public function setView(string $view): void { $this->statusFilter = $view; $this->resetPage(); } public function resetFilters(): void { $this->search = ''; $this->statusFilter = 'all'; $this->portalFilter = 'all'; if ($this->companyFilter !== 'all') { $this->companyFilter = 'all'; } $this->resetPage(); } public function updatedSearch(): void { $this->resetPage(); } public function updatedStatusFilter(): void { $this->resetPage(); } public function updatedCompanyFilter(): void { $this->resetPage(); } public function updatedPortalFilter(): void { $this->resetPage(); } public function submitForReview(int $id): void { $pr = $this->findMyPR($id); if (!$pr) { return; } try { app(PressReleaseService::class)->submitForReview($pr); Flux::toast( heading: __('Eingereicht'), text: __('Pressemitteilung zur Prüfung eingereicht.'), variant: 'success', ); } catch (BlacklistViolationException $e) { Flux::toast( heading: __('Automatisch abgelehnt'), text: __('Unzulässiges Wort gefunden: ":word".', ['word' => $e->word]), variant: 'danger', duration: 8000, ); } catch (\LogicException $e) { Flux::toast(text: $e->getMessage(), variant: 'danger'); } } public function with(): array { $userId = auth()->id(); $context = app(CustomerCompanyContext::class); $selectedCompanyId = $context->selectedCompanyId(auth()->user()); $base = PressRelease::withoutGlobalScopes() ->where('user_id', $userId) ->when($selectedCompanyId !== null, fn($q) => $q->where('company_id', $selectedCompanyId)) ->when($selectedCompanyId === null && $this->companyFilter === 'assigned', fn($q) => $q->whereNotNull('company_id')) ->when($selectedCompanyId === null && $this->companyFilter === 'unassigned', fn($q) => $q->whereNull('company_id')); $statusCountsRaw = (clone $base)->toBase()->selectRaw('status, COUNT(*) as aggregate')->groupBy('status')->pluck('aggregate', 'status'); $statusCounts = [ 'all' => (int) $statusCountsRaw->sum(), PressReleaseStatus::Published->value => (int) ($statusCountsRaw[PressReleaseStatus::Published->value] ?? 0), PressReleaseStatus::Draft->value => (int) ($statusCountsRaw[PressReleaseStatus::Draft->value] ?? 0), PressReleaseStatus::Review->value => (int) ($statusCountsRaw[PressReleaseStatus::Review->value] ?? 0), PressReleaseStatus::Rejected->value => (int) ($statusCountsRaw[PressReleaseStatus::Rejected->value] ?? 0), PressReleaseStatus::Archived->value => (int) ($statusCountsRaw[PressReleaseStatus::Archived->value] ?? 0), ]; $prs = (clone $base) ->with('company:id,name') ->when(filled($this->search), function ($q): void { $term = $this->search; $q->where('title', 'like', '%' . $term . '%'); }) ->when($this->statusFilter !== 'all', fn($q) => $q->where('status', $this->statusFilter)) ->when($this->portalFilter !== 'all', fn($q) => $q->where('portal', $this->portalFilter)) ->orderBy(in_array($this->sortBy, ['title', 'status', 'created_at']) ? $this->sortBy : 'created_at', $this->sortDir) ->paginate(25); return [ 'pressReleases' => $prs, 'statusOptions' => PressReleaseStatus::cases(), 'portalOptions' => Portal::cases(), 'selectedCompany' => $context->selectedCompany(auth()->user()), 'hasGlobalCompanyContext' => $selectedCompanyId === null, 'statusCounts' => $statusCounts, ]; } private function findMyPR(int $id): ?PressRelease { return PressRelease::withoutGlobalScopes() ->where('id', $id) ->where('user_id', auth()->id()) ->first(); } }; ?> @php $hasAnyFilter = $search !== '' || $statusFilter !== 'all' || $portalFilter !== 'all' || ($hasGlobalCompanyContext && $companyFilter !== 'all'); $hasAnyPR = $statusCounts['all'] > 0; @endphp
{{-- Flash-Banner ersetzt durch im Layout. --}} {{-- ============== PAGE HEADER ============== --}}
{{ __('User Backend') }} {{ __('Mein Bereich · Pressemitteilungen') }}

{{ __('Meine Pressemitteilungen') }}

{{-- Counter-Strip + Kontext-Hinweis --}} @if ($hasAnyPR)
{{ $statusCounts['all'] }} {{ __('Mitteilungen') }} @if ($statusCounts[\App\Enums\PressReleaseStatus::Published->value] > 0) {{ $statusCounts[\App\Enums\PressReleaseStatus::Published->value] }} {{ __('veröffentlicht') }} @endif @if ($statusCounts[\App\Enums\PressReleaseStatus::Review->value] > 0) {{ $statusCounts[\App\Enums\PressReleaseStatus::Review->value] }} {{ __('in Prüfung') }} @endif @if ($statusCounts[\App\Enums\PressReleaseStatus::Draft->value] > 0) {{ $statusCounts[\App\Enums\PressReleaseStatus::Draft->value] }} {{ __('Entwürfe') }} @endif @if ($statusCounts[\App\Enums\PressReleaseStatus::Rejected->value] > 0) {{ $statusCounts[\App\Enums\PressReleaseStatus::Rejected->value] }} {{ __('abgelehnt') }} @endif
@endif @if ($selectedCompany)

{{ __('Gefiltert auf :company', ['company' => $selectedCompany->name]) }}

@elseif (!$hasAnyPR)

{{ __('Übersicht aller PMs Ihres Kundenkontos, mit Filter und Schnellaktionen.') }}

@endif
{{ __('Neue Pressemitteilung') }}
{{-- ============== SAVED-VIEWS-TABS ============== --}} @if ($hasAnyPR) @endif {{-- ============== FILTER + SUCHE ============== --}} @if ($hasAnyPR)
@foreach ($portalOptions as $p) @endforeach @if ($hasGlobalCompanyContext) @endif
{{-- Active-Chips --}} @if ($hasAnyFilter)
{{ __('Aktiv') }} @if ($statusFilter !== 'all') @php $statusEnum = \App\Enums\PressReleaseStatus::tryFrom($statusFilter); @endphp {{ __('Status') }}: {{ $statusEnum?->label() ?? $statusFilter }} @endif @if ($portalFilter !== 'all') @php $portalEnum = \App\Enums\Portal::tryFrom($portalFilter); @endphp {{ __('Portal') }}: {{ $portalEnum?->label() ?? $portalFilter }} @endif @if ($hasGlobalCompanyContext && $companyFilter !== 'all') {{ __('Firma') }}: {{ $companyFilter === 'assigned' ? __('Mit Firma') : __('Ohne Firma') }} @endif @if ($search !== '') {{ __('Suche') }}: „{{ \Illuminate\Support\Str::limit($search, 40) }}" @endif
@endif
@endif {{-- ============== TABELLE / EMPTY ============== --}}
@if ($pressReleases->isNotEmpty())
@if ($statusFilter !== 'all') @php $sEnum = \App\Enums\PressReleaseStatus::tryFrom($statusFilter); @endphp {{ $sEnum?->label() ?? __('Pressemitteilungen') }} @else {{ __('Alle Pressemitteilungen') }} @endif {{ __(':count Einträge', ['count' => $pressReleases->total()]) }}
{{ __('Status') }} {{ __('Titel') }} {{ __('Portal') }} {{ __('Firma') }} {{ __('Datum') }} {{ __('Aktionen') }} @foreach ($pressReleases as $pr) @php $status = $pr->status->value; $rowClass = match ($status) { 'review' => 'is-row-warn', 'rejected' => 'is-row-err', default => '', }; $badgeClass = match ($status) { 'published' => 'ok', 'review' => 'warn', 'rejected' => 'err', 'archived', 'draft' => 'muted', default => 'hub', }; $portal = $pr->portal?->value ?? 'both'; $showPe = in_array($portal, ['presseecho', 'both'], true); $showBp = in_array($portal, ['businessportal24', 'both'], true); $dateSubLabel = match ($status) { 'published' => __('veröffentlicht'), 'review' => __('eingereicht'), 'rejected' => __('abgelehnt'), 'draft' => __('erstellt'), 'archived' => __('archiviert'), default => __('erstellt'), }; $primaryDate = match (true) { $status === 'published' && $pr->published_at => $pr->published_at, default => $pr->created_at, }; @endphp
{{ $pr->status->label() }} @if ($status === 'draft') @endif
{{ $pr->title }}
PM-{{ $pr->id }}
@if ($showPe) presseecho @endif @if ($showBp) businessportal24 @endif
@if ($pr->company) {{ $pr->company->name }} @else {{ __('— keine —') }} @endif
{{ $primaryDate?->format('d.m.Y') }}
{{ $dateSubLabel }} · {{ $primaryDate?->format('H:i') }}
@if ($status === 'review' && $pr->scheduled_at && $pr->scheduled_at->isFuture())
{{ __('geplant') }} · {{ $pr->scheduled_at->format('d.m. H:i') }}
@endif @if ($pr->embargo_at && $pr->embargo_at->isFuture())
{{ __('Embargo bis') }} {{ $pr->embargo_at->format('d.m.') }}
@endif
@if (in_array($status, ['draft', 'rejected'])) @endif
@endforeach
{{ $pressReleases->links('components.portal.pagination') }}
@elseif ($hasAnyPR && $search !== '') {{-- Empty: Suche ohne Treffer --}}

{{ __('Keine Treffer für „:term"', ['term' => $search]) }}

{{ __('Wir konnten zu Ihrer Suche nichts finden. Prüfen Sie die Schreibweise oder schränken Sie den Suchbegriff ein.') }}

{{ __('Suche zurücksetzen') }}
@elseif ($hasAnyPR && $hasAnyFilter) {{-- Empty: Filter ohne Treffer --}}

{{ __('Keine Mitteilungen mit diesen Filtern') }}

{{ __('Aktive Filter passen auf keine Einträge. Setzen Sie einen Filter zurück oder probieren Sie eine breitere Auswahl.') }}

{{ __('Alle Filter zurücksetzen') }}
@else {{-- Empty: gar keine PMs überhaupt --}}

{{ __('Noch keine Pressemitteilungen') }}

{{ __('Starten Sie mit Ihrer ersten Mitteilung. Nach redaktioneller Prüfung erscheint sie i. d. R. binnen 4 Stunden werktags auf beiden Portalen.') }}

{{ __('Erste Pressemitteilung erstellen') }}
01
{{ __('Firma zuordnen') }}
02
{{ __('Mitteilung verfassen') }}
03
{{ __('Zur Prüfung senden') }}
@endif
{{-- ============== STATUS-AKTIONEN-LEGENDE ============== --}} @if ($hasAnyPR)
{{ __('Aktionen je Status') }}

{{ __('Welche Aktionen pro Status verfügbar sind.') }}

{{ __('Entwurf') }}
  • {{ __('Bearbeiten') }}
  • {{ __('Vorschau') }}
  • {{ __('→ Zur Prüfung senden') }}
{{ __('In Prüfung') }}
  • {{ __('Vorschau') }}
  • {{ __('Warten auf Redaktion') }}
{{ __('Veröffentlicht') }}
  • {{ __('Vorschau') }}
  • {{ __('Statistik (bald)') }}
{{ __('Abgelehnt') }}
  • {{ __('Bearbeiten') }}
  • {{ __('→ Erneut einreichen') }}
{{ __('Archiviert') }}
  • {{ __('Vorschau') }}
@endif