sortBy === $column) { $this->sortDir = $this->sortDir === 'asc' ? 'desc' : 'asc'; } else { $this->sortBy = $column; $this->sortDir = 'asc'; } $this->resetPage(); } public function updatedSearch(): void { $this->resetPage(); } public function updatedStatusFilter(): void { $this->resetPage(); } public function updatedClassificationFilter(): void { $this->resetPage(); } public function updatedPortalFilter(): void { $this->resetPage(); } public function updatedLanguageFilter(): void { $this->resetPage(); } public function updatedCategoryFilter(): void { $this->resetPage(); } public function updatedUserFilter(): void { $this->resetPage(); } public function updatedCompanyFilter(): void { $this->resetPage(); } public function updatedContactFilter(): void { $this->resetPage(); } public function clearUserFilter(): void { $this->userFilter = 'all'; $this->userLookup = ''; $this->resetPage(); } public function clearCompanyFilter(): void { $this->companyFilter = 'all'; $this->companyLookup = ''; $this->resetPage(); } public function clearContactFilter(): void { $this->contactFilter = 'all'; $this->contactLookup = ''; $this->resetPage(); } public function resetEntityFilters(): void { $this->clearUserFilter(); $this->clearCompanyFilter(); $this->clearContactFilter(); } public function setView(string $view): void { $this->statusFilter = $view; $this->resetPage(); } public function resetFilters(): void { $this->search = ''; $this->statusFilter = 'all'; $this->classificationFilter = 'all'; $this->portalFilter = 'all'; $this->languageFilter = 'all'; $this->categoryFilter = 'all'; $this->clearUserFilter(); $this->clearCompanyFilter(); $this->clearContactFilter(); $this->resetPage(); } public function publish(int $id): void { $pr = PressRelease::withoutGlobalScopes()->findOrFail($id); try { app(PressReleaseService::class)->publish($pr); } catch (BlacklistViolationException $e) { Flux::toast( heading: __('Automatisch abgelehnt'), text: __('Unzulässiges Wort gefunden: ":word".', ['word' => $e->word]), variant: 'danger', duration: 8000, ); return; } catch (\LogicException $e) { Flux::toast(text: $e->getMessage(), variant: 'danger'); return; } Flux::toast(text: __('Pressemitteilung veröffentlicht.'), variant: 'success'); } public function reject(int $id): void { $pr = PressRelease::withoutGlobalScopes()->findOrFail($id); try { app(PressReleaseService::class)->reject($pr, __('Bitte überarbeiten Sie die Pressemitteilung.')); } catch (\LogicException $e) { Flux::toast(text: $e->getMessage(), variant: 'danger'); return; } Flux::toast(text: __('Pressemitteilung abgelehnt.'), variant: 'warning'); } public function archive(int $id): void { $pr = PressRelease::withoutGlobalScopes()->findOrFail($id); try { app(PressReleaseService::class)->archive($pr); } catch (\LogicException $e) { Flux::toast(text: $e->getMessage(), variant: 'danger'); return; } Flux::toast(text: __('Pressemitteilung archiviert.'), variant: 'success'); } public function with(): array { $query = PressRelease::withoutGlobalScopes() ->with(['company:id,name', 'category.translations', 'user:id,name']) ->when(filled($this->search), function ($q): void { $term = trim($this->search); $q->where(function ($q) use ($term): void { if ($this->supportsFullTextSearch($term)) { $q->whereFullText(['title', 'keywords'], $term) ->orWhereHas('company', fn ($q) => $q->whereFullText(['name', 'email', 'slug'], $term)); return; } $q->where('title', 'like', '%'.$term.'%') ->orWhere('keywords', 'like', '%'.$term.'%') ->orWhereHas('company', fn ($q) => $q->where('name', 'like', '%'.$term.'%')); }); }) ->when($this->statusFilter !== 'all', fn ($q) => $q->where('status', $this->statusFilter)) ->when($this->classificationFilter !== 'all', fn ($q) => $q->where('classification', $this->classificationFilter)) ->when($this->portalFilter !== 'all', fn ($q) => $q->where('portal', $this->portalFilter)) ->when($this->languageFilter !== 'all', fn ($q) => $q->where('language', $this->languageFilter)) ->when($this->categoryFilter !== 'all', fn ($q) => $q->where('category_id', (int) $this->categoryFilter)) ->when($this->userFilter !== 'all', fn ($q) => $q->where('user_id', (int) $this->userFilter)) ->when($this->companyFilter !== 'all', fn ($q) => $q->where('company_id', (int) $this->companyFilter)) ->when($this->contactFilter !== 'all', fn ($q) => $q->whereHas('contacts', fn ($contactQuery) => $contactQuery->where('contacts.id', (int) $this->contactFilter))) ->orderBy(in_array($this->sortBy, ['title', 'status', 'portal', 'hits', 'created_at']) ? $this->sortBy : 'created_at', $this->sortDir) ->paginate(50); return [ 'pressReleases' => $query, 'stats' => $this->pressReleaseStats(), 'statusOptions' => PressReleaseStatus::cases(), 'portalOptions' => Portal::cases(), 'categoryOptions' => $this->categoryOptions(), 'userLookupResults' => $this->userLookupResults(), 'companyLookupResults' => $this->companyLookupResults(), 'contactLookupResults' => $this->contactLookupResults(), ]; } /** * @return array{total: int, published: int, review: int, draft: int, rejected: int, archived: int} */ private function pressReleaseStats(): array { return app(AdminPerformanceCache::class)->remember(AdminPerformanceCache::PressReleaseStats, AdminPerformanceCache::StatsTtl, function (): array { $stats = PressRelease::withoutGlobalScopes() ->toBase() ->selectRaw('COUNT(*) as total') ->selectRaw('SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) as published', [PressReleaseStatus::Published->value]) ->selectRaw('SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) as review', [PressReleaseStatus::Review->value]) ->selectRaw('SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) as draft', [PressReleaseStatus::Draft->value]) ->selectRaw('SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) as rejected', [PressReleaseStatus::Rejected->value]) ->selectRaw('SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) as archived', [PressReleaseStatus::Archived->value]) ->first(); return [ 'total' => (int) ($stats->total ?? 0), 'published' => (int) ($stats->published ?? 0), 'review' => (int) ($stats->review ?? 0), 'draft' => (int) ($stats->draft ?? 0), 'rejected' => (int) ($stats->rejected ?? 0), 'archived' => (int) ($stats->archived ?? 0), ]; }); } private function categoryOptions() { return app(AdminPerformanceCache::class)->remember(AdminPerformanceCache::PressReleaseCategoryOptions, AdminPerformanceCache::OptionsTtl, fn () => Category::query() ->select(['id', 'is_active']) ->with(['translations:id,category_id,locale,name,slug']) ->where('is_active', true) ->orderBy('id') ->get()); } private function userLookupResults() { $term = trim($this->userLookup); if ($term === '' && $this->userFilter === 'all') { return collect(); } return User::query() ->select(['id', 'name', 'email']) ->where(function ($query) use ($term): void { if ($this->userFilter !== 'all') { $query->where('id', (int) $this->userFilter); } if ($term !== '') { $query->orWhere(function ($searchQuery) use ($term): void { $searchQuery ->where('name', 'like', '%'.$term.'%') ->orWhere('email', 'like', '%'.$term.'%'); }); } }) ->orderBy('name') ->limit(20) ->get(); } private function companyLookupResults() { $term = trim($this->companyLookup); if ($term === '' && $this->companyFilter === 'all') { return collect(); } return Company::withoutGlobalScopes() ->select(['id', 'name', 'slug', 'email']) ->where(function ($query) use ($term): void { if ($this->companyFilter !== 'all') { $query->where('id', (int) $this->companyFilter); } if ($term !== '') { $query->orWhere(function ($searchQuery) use ($term): void { $searchQuery ->where('name', 'like', '%'.$term.'%') ->orWhere('slug', 'like', '%'.$term.'%') ->orWhere('email', 'like', '%'.$term.'%'); }); } }) ->orderBy('name') ->limit(20) ->get(); } private function contactLookupResults() { $term = trim($this->contactLookup); if ($term === '' && $this->contactFilter === 'all') { return collect(); } return Contact::withoutGlobalScopes() ->select(['id', 'company_id', 'first_name', 'last_name', 'email']) ->with('company:id,name') ->where(function ($query) use ($term): void { if ($this->contactFilter !== 'all') { $query->where('id', (int) $this->contactFilter); } if ($term !== '') { $query->orWhere(function ($searchQuery) use ($term): void { $searchQuery ->where('first_name', 'like', '%'.$term.'%') ->orWhere('last_name', 'like', '%'.$term.'%') ->orWhere('email', 'like', '%'.$term.'%'); }); } }) ->orderBy('last_name') ->orderBy('first_name') ->limit(20) ->get(); } private function supportsFullTextSearch(string $term): bool { return mb_strlen($term) >= 3 && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'], true); } }; ?>
{{ __('Übersicht aller PMs beider Portale, mit Filter, Status-Workflow und Schnellaktionen.') }}
{{ __('Passen Sie die Filter an oder setzen Sie alle Filter zurück, um wieder alle PMs zu sehen.') }}
{{ __('Sobald Kunden PMs anlegen oder einreichen, erscheinen sie hier zur Bearbeitung.') }}