sortBy === $column) { $this->sortDir = $this->sortDir === 'asc' ? 'desc' : 'asc'; } else { $this->sortBy = $column; $this->sortDir = 'asc'; } $this->resetPage(); } public function with(): array { $sortable = ['name', 'email', 'is_active', 'press_releases_count', 'contacts_count', 'created_at']; $sort = in_array($this->sortBy, $sortable) ? $this->sortBy : 'name'; $sortsByCount = in_array($sort, ['press_releases_count', 'contacts_count'], true); $companiesQuery = Company::query() ->when($sortsByCount, fn ($query) => $query->withCount(['pressReleases', 'contacts'])) ->when($this->search, function ($query): void { $term = trim($this->search); if ($this->supportsFullTextSearch($term)) { $query->whereFullText(['name', 'email', 'slug'], $term); return; } $query->where(function ($searchQuery): void { $searchQuery->where('name', 'like', '%'.$this->search.'%')->orWhere('email', 'like', '%'.$this->search.'%'); }); }) ->when($this->activeFilter !== 'all', function ($query): void { $query->where('is_active', $this->activeFilter === 'active'); }) ->when($this->portalFilter !== 'all', function ($query): void { $query->where('portal', $this->portalFilter); }) ->when($this->userFilter !== 'all', function ($query): void { $query->where(function ($userScopedQuery): void { $userScopedQuery ->where('owner_user_id', (int) $this->userFilter) ->orWhereHas('users', fn ($userQuery) => $userQuery->where('users.id', (int) $this->userFilter)); }); }) ->when($this->contactFilter !== 'all', function ($query): void { $query->whereHas('contacts', fn ($contactQuery) => $contactQuery->where('contacts.id', (int) $this->contactFilter)); }) ->when($this->qualityFilter !== 'all', function ($query): void { match ($this->qualityFilter) { 'with_press_releases' => $query->whereHas('pressReleases'), 'without_press_releases' => $query->whereDoesntHave('pressReleases'), 'with_contacts' => $query->whereHas('contacts'), 'without_contacts' => $query->whereDoesntHave('contacts'), default => null, }; }) ->orderBy($sort, $this->sortDir); $companies = $companiesQuery->paginate(50); if (! $sortsByCount) { $this->hydrateCounts($companies); } return [ 'companies' => $companies, 'stats' => $this->stats(), 'portalOptions' => Portal::cases(), 'userLookupResults' => $this->userLookupResults(), 'contactLookupResults' => $this->contactLookupResults(), ]; } /** * @return array{total: int, active: int, inactive: int} */ private function stats(): array { $portal = CurrentPortalContext::get()?->value ?? 'all'; $cache = app(AdminPerformanceCache::class); return $cache->remember($cache->companiesStatsKey($portal), AdminPerformanceCache::StatsTtl, function (): array { $stats = Company::query() ->toBase() ->selectRaw('COUNT(*) as total') ->selectRaw('SUM(CASE WHEN is_active = ? THEN 1 ELSE 0 END) as active', [true]) ->selectRaw('SUM(CASE WHEN is_active = ? THEN 1 ELSE 0 END) as inactive', [false]) ->first(); return [ 'total' => (int) ($stats->total ?? 0), 'active' => (int) ($stats->active ?? 0), 'inactive' => (int) ($stats->inactive ?? 0), ]; }); } private function hydrateCounts($companies): void { $companyIds = $companies->getCollection()->pluck('id'); if ($companyIds->isEmpty()) { return; } $pressReleaseCounts = PressRelease::query() ->whereIn('company_id', $companyIds) ->selectRaw('company_id, COUNT(*) as aggregate') ->groupBy('company_id') ->pluck('aggregate', 'company_id'); $contactCounts = Contact::query() ->whereIn('company_id', $companyIds) ->selectRaw('company_id, COUNT(*) as aggregate') ->groupBy('company_id') ->pluck('aggregate', 'company_id'); $companies->getCollection()->each(function (Company $company) use ($pressReleaseCounts, $contactCounts): void { $company->setAttribute('press_releases_count', (int) $pressReleaseCounts->get($company->id, 0)); $company->setAttribute('contacts_count', (int) $contactCounts->get($company->id, 0)); }); } private function supportsFullTextSearch(string $term): bool { return mb_strlen($term) >= 3 && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'], true); } public function updatedSearch(): void { $this->resetPage(); } public function updatedActiveFilter(): void { $this->resetPage(); } public function updatedPortalFilter(): void { $this->resetPage(); } public function updatedUserFilter(): void { if (blank($this->userFilter)) { $this->userFilter = 'all'; } $this->userLookup = ''; $this->resetPage(); } public function updatedContactFilter(): void { if (blank($this->contactFilter)) { $this->contactFilter = 'all'; } $this->contactLookup = ''; $this->resetPage(); } public function updatedQualityFilter(): void { $this->resetPage(); } public function clearUserSearch(): void { $this->userFilter = 'all'; $this->userLookup = ''; $this->resetPage(); } public function clearContactSearch(): void { $this->contactFilter = 'all'; $this->contactLookup = ''; $this->resetPage(); } private function portalBadgeColor(?Portal $portal): string { return match ($portal) { Portal::Presseecho => 'blue', Portal::Businessportal24 => 'purple', Portal::Both => 'zinc', default => 'zinc', }; } 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 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(); } }; ?>
{{ __('Übersicht aller Firmen beider Portale, mit Filter, Datenqualität und Schnellaktionen.') }}
{{ __('Passen Sie die Filter an oder legen Sie eine neue Firma an.') }}