selectedExistingContactId) { $this->attachExistingContact(); } } public function mount(int $id): void { $this->id = $id; $companyExists = Company::query()->whereKey($id)->exists(); if (! $companyExists) { session()->flash('error', __('Die angeforderte Firma wurde nicht gefunden.')); $this->redirect(route('admin.companies.index'), navigate: true); return; } } public function setTab(string $tab): void { if (in_array($tab, ['overview', 'contacts'], true)) { $this->activeTab = $tab; } } public function updatedContactLookup(): void { $this->selectedExistingContactId = null; } /** * Hängt einen bestehenden Kontakt an diese Firma um. Die Seite ist für * Editoren lesbar, die Aktion schreibt aber — daher `companies:write` * direkt an der Mutation (Sicherheitsaudit 07.10.2026, S-02). Greift auch * für den Aufruf über updatedSelectedExistingContactId(). */ public function attachExistingContact(): void { $this->authorize('companies:write'); if (! $this->selectedExistingContactId) { return; } $company = Company::query()->find($this->id); if (! $company) { session()->flash('error', __('Die angeforderte Firma wurde nicht gefunden.')); return; } $contact = Contact::query()->find($this->selectedExistingContactId); if (! $contact) { session()->flash('error', __('Der ausgewählte Kontakt wurde nicht gefunden.')); return; } if ($contact->company_id === $company->id) { session()->flash('info', __('Der Kontakt ist bereits dieser Firma zugeordnet.')); return; } $contact->update(['company_id' => $company->id]); $this->contactLookup = ''; $this->selectedExistingContactId = null; session()->flash('success', __('Kontakt wurde der Firma zugeordnet.')); } public function with(): array { $company = Company::query() ->with([ 'pressReleases' => fn ($query) => $query->latest('id')->limit(10), 'users:id,name,email', ]) ->withCount(['pressReleases', 'contacts', 'users']) ->find($this->id); if (! $company) { return [ 'company' => Company::make([ 'id' => $this->id, 'name' => __('Unbekannte Firma'), 'is_active' => false, ]), 'filteredContacts' => collect(), 'filteredContactsTotal' => 0, 'contactLookupResults' => collect(), 'recentPressReleases' => collect(), 'unreachableEmails' => [], 'domainCheck' => null, ]; } $filteredContacts = collect(); $filteredContactsTotal = 0; if ($this->activeTab === 'contacts') { $contactsQuery = Contact::query() ->where('company_id', $company->id) ->when(filled($this->contactSearch), function ($query): void { $search = trim($this->contactSearch); if ($this->supportsFullTextSearch($search)) { $query->whereFullText(['first_name', 'last_name', 'email', 'responsibility'], $search); return; } $query->where(function ($query) use ($search): void { $query->where('first_name', 'like', '%'.$search.'%') ->orWhere('last_name', 'like', '%'.$search.'%') ->orWhere('email', 'like', '%'.$search.'%') ->orWhere('responsibility', 'like', '%'.$search.'%'); }); }); $filteredContactsTotal = (clone $contactsQuery)->count(); $filteredContacts = $contactsQuery ->orderBy('last_name') ->orderBy('first_name') ->limit(100) ->get(['id', 'company_id', 'portal', 'first_name', 'last_name', 'responsibility', 'email']); } $contactLookupResults = collect(); $lookupTerm = trim($this->contactLookup); if ($this->activeTab === 'contacts' && mb_strlen($lookupTerm) >= 1 && auth()->user()->can('companies:write')) { $contactLookupResults = Contact::withoutGlobalScopes() ->with('company:id,name') ->where('company_id', '!=', $company->id) ->where(function ($query) use ($lookupTerm): void { if ($this->supportsFullTextSearch($lookupTerm)) { $query->whereFullText(['first_name', 'last_name', 'email', 'responsibility'], $lookupTerm); return; } $query ->where('first_name', 'like', '%'.$lookupTerm.'%') ->orWhere('last_name', 'like', '%'.$lookupTerm.'%') ->orWhere('email', 'like', '%'.$lookupTerm.'%'); }) ->orderBy('last_name') ->orderBy('first_name') ->limit(50) ->get(['id', 'company_id', 'first_name', 'last_name', 'email']); } // Bounce-Suppression (Roadmap 1b.6): Firmen-E-Mail und Kontaktadressen, // die nicht erreichbar sind — als Markierung im Kopf und an der Zeile. $unreachableEmails = app(\App\Services\Mail\EmailSuppressionService::class)->suppressedAmong(array_values(array_filter([ $company->email, ...$filteredContacts->pluck('email')->all(), ]))); // Kontakterreichbarkeit: DNS-Befund der Firmen-Domain, nur aus dem // Speicher — die Seite fragt kein DNS. $domain = \App\Rules\PlausibleEmailDomain::domainOf($company->email); $domainCheck = $domain === null ? null : \App\Models\EmailDomainCheck::query()->where('domain', $domain)->first(); return [ 'company' => $company, 'domainCheck' => $domainCheck, 'unreachableEmails' => $unreachableEmails, 'filteredContacts' => $filteredContacts, 'filteredContactsTotal' => $filteredContactsTotal, 'contactLookupResults' => $contactLookupResults, 'recentPressReleases' => $company->pressReleases, ]; } }; ?>
@if (session('success'))
{{ session('success') }}
@endif @if (session('error'))
{{ session('error') }}
@endif @if (session('info'))
{{ session('info') }}
@endif {{-- ============== PAGE HEADER ============== --}} @php($logoUrl = $company->logoUrl()) {{-- ============== KPI-Reihe ============== --}}
{{ __('insgesamt') }} {{ __('Content-Output dieser Firma') }} {{ __('Ansprechpartner') }} {{ __('für PMs verfügbar') }} {{ __('Owner & Co-Editors') }} {{ __('Backend-Zugriff') }}
{{-- ============== TABS ============== --}} @if ($activeTab === 'overview')
{{ __('Kontaktinformationen') }}
{{ __('E-Mail') }}
{{ $company->email ?: __('Keine E-Mail hinterlegt') }} @if ($company->email && in_array(mb_strtolower(trim($company->email)), $unreachableEmails, true)) {{ __('nicht erreichbar') }} @endif
{{ __('Telefon') }}
{{ $company->phone ?: __('Kein Telefon hinterlegt') }}
{{ __('Website') }}
{{ $company->website ?: __('Keine Website hinterlegt') }}
{{ __('Adresse') }}
{{ __('Anschrift') }}
{{ $company->address ?: __('Keine Adresse hinterlegt') }}
{{ __('Land') }}
{{ $company->country_code ?: __('Kein Land hinterlegt') }}
@endif @if ($activeTab === 'contacts')
{{ __('Ansprechpartner') }} {{ $filteredContactsTotal }} {{ __('Einträge') }}
@can('companies:write') {{ __('Neu') }} @endcan
@can('companies:write')
{{ __('Bestehenden Kontakt zuordnen') }}
@foreach ($contactLookupResults as $lookupContact) @php($lookupName = trim(($lookupContact->first_name ?? '').' '.($lookupContact->last_name ?? '')) ?: __('Kontakt ohne Name')) {{ $lookupName }} @if ($lookupContact->email) · {{ $lookupContact->email }} @endif · {{ $lookupContact->company?->name ?? __('Unbekannte Firma') }} @endforeach @if (blank(trim($contactLookup))) {{ __('Mindestens 1 Zeichen eingeben…') }} @else {{ __('Kein Kontakt gefunden.') }} @endif
@endcan
@forelse ($filteredContacts as $contact)
{{ $contact->displayName() }} {{ $contact->portal?->label() ?? __('Unbekannt') }}
{{ $contact->responsibility ?: __('Keine Rolle hinterlegt') }}
@if ($contact->email && in_array(mb_strtolower(trim($contact->email)), $unreachableEmails, true)) {{ __('nicht erreichbar') }} @endif @if ($contact->email) {{ $contact->email }} @endif
@if (\Illuminate\Support\Facades\Route::has('admin.contacts.edit')) @endif
@empty
{{ __('Keine Kontakte gefunden') }}
@endforelse
@if ($filteredContactsTotal > $filteredContacts->count())

{{ __('Es werden die ersten :count Kontakte angezeigt. Bitte Suche eingrenzen, um weitere Treffer zu finden.', ['count' => $filteredContacts->count()]) }}

@endif
@endif