Optimierung 5.3 (Teil 1): Contact::displayName()
Anzeigename eines Kontakts (Vor-/Nachname mit Fallback) als Model-Methode. Ersetzt die identische Inline-Logik an 6 eindeutigen Relation-$contact-Stellen (Admin: Benutzer-/PM-/Firmen-Detail; Kunde: Press-Kit-/PM-Detail). Bewusst noch offen: Select-/toBase-Varianten ($contactOption/$contactResult/ $lookupContact, stdClass-Risiko) sowie web/release-detail (User-Frontend). Test: ContactDisplayNameTest. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6bf6a091d3
commit
178adb00e2
8 changed files with 38 additions and 6 deletions
|
|
@ -63,6 +63,17 @@ class Contact extends Model
|
||||||
return $this->belongsTo(Company::class);
|
return $this->belongsTo(Company::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Anzeigename eines Kontakts (Vor- + Nachname), mit Fallback, wenn beides
|
||||||
|
* leer ist. Single Source of Truth für die Listen-/Detail-Ansichten.
|
||||||
|
*/
|
||||||
|
public function displayName(): string
|
||||||
|
{
|
||||||
|
$name = trim(($this->first_name ?? '').' '.($this->last_name ?? ''));
|
||||||
|
|
||||||
|
return $name !== '' ? $name : __('Kontakt ohne Name');
|
||||||
|
}
|
||||||
|
|
||||||
public function pressReleases(): BelongsToMany
|
public function pressReleases(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(PressRelease::class, 'press_release_contact');
|
return $this->belongsToMany(PressRelease::class, 'press_release_contact');
|
||||||
|
|
|
||||||
|
|
@ -434,7 +434,7 @@ new #[Layout('components.layouts.app'), Title('Firma anzeigen')] class extends C
|
||||||
<div class="min-w-0">
|
<div class="min-w-0">
|
||||||
<div class="flex flex-wrap items-center gap-2">
|
<div class="flex flex-wrap items-center gap-2">
|
||||||
<span class="text-[13px] font-semibold text-[color:var(--color-ink)]">
|
<span class="text-[13px] font-semibold text-[color:var(--color-ink)]">
|
||||||
{{ trim(($contact->first_name ?? '').' '.($contact->last_name ?? '')) ?: __('Kontakt ohne Name') }}
|
{{ $contact->displayName() }}
|
||||||
</span>
|
</span>
|
||||||
<span class="badge hub">{{ $contact->portal?->label() ?? __('Unbekannt') }}</span>
|
<span class="badge hub">{{ $contact->portal?->label() ?? __('Unbekannt') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -339,7 +339,7 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung')] class extends
|
||||||
@forelse ($contacts as $contact)
|
@forelse ($contacts as $contact)
|
||||||
<div class="rounded-[5px] border border-[color:var(--color-bg-rule)] bg-[color:var(--color-bg-elev)] p-3">
|
<div class="rounded-[5px] border border-[color:var(--color-bg-rule)] bg-[color:var(--color-bg-elev)] p-3">
|
||||||
<div class="text-[13px] font-semibold text-[color:var(--color-ink)]">
|
<div class="text-[13px] font-semibold text-[color:var(--color-ink)]">
|
||||||
{{ trim(($contact->first_name ?? '').' '.($contact->last_name ?? '')) ?: __('Kontakt ohne Name') }}
|
{{ $contact->displayName() }}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-[12px] text-[color:var(--color-ink-3)]">
|
<div class="text-[12px] text-[color:var(--color-ink-3)]">
|
||||||
{{ $contact->responsibility ?: __('Keine Rolle hinterlegt') }}
|
{{ $contact->responsibility ?: __('Keine Rolle hinterlegt') }}
|
||||||
|
|
|
||||||
|
|
@ -865,7 +865,7 @@ new #[Layout('components.layouts.app'), Title('Benutzer')] class extends Compone
|
||||||
<div class="flex flex-col gap-2 rounded-md bg-zinc-50 p-2 dark:bg-zinc-900 sm:flex-row sm:items-center sm:justify-between">
|
<div class="flex flex-col gap-2 rounded-md bg-zinc-50 p-2 dark:bg-zinc-900 sm:flex-row sm:items-center sm:justify-between">
|
||||||
<div class="min-w-0">
|
<div class="min-w-0">
|
||||||
<flux:text class="text-sm" weight="medium">
|
<flux:text class="text-sm" weight="medium">
|
||||||
{{ trim(($contact->first_name ?? '').' '.($contact->last_name ?? '')) ?: __('Kontakt ohne Name') }}
|
{{ $contact->displayName() }}
|
||||||
</flux:text>
|
</flux:text>
|
||||||
<flux:text class="text-xs text-zinc-500">
|
<flux:text class="text-xs text-zinc-500">
|
||||||
{{ $contact->responsibility ?? __('Keine Rolle hinterlegt') }}
|
{{ $contact->responsibility ?? __('Keine Rolle hinterlegt') }}
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,7 @@ new #[Layout('components.layouts.app'), Title('Benutzer anzeigen')] class extend
|
||||||
<div class="flex flex-col gap-2 rounded-[4px] border border-[color:var(--color-bg-rule)] bg-[color:var(--color-bg-elev)] p-2 sm:flex-row sm:items-center sm:justify-between">
|
<div class="flex flex-col gap-2 rounded-[4px] border border-[color:var(--color-bg-rule)] bg-[color:var(--color-bg-elev)] p-2 sm:flex-row sm:items-center sm:justify-between">
|
||||||
<div class="min-w-0">
|
<div class="min-w-0">
|
||||||
<div class="text-[12.5px] font-medium text-[color:var(--color-ink)]">
|
<div class="text-[12.5px] font-medium text-[color:var(--color-ink)]">
|
||||||
{{ trim(($contact->first_name ?? '').' '.($contact->last_name ?? '')) ?: __('Kontakt ohne Name') }}
|
{{ $contact->displayName() }}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-[11px] text-[color:var(--color-ink-3)]">
|
<div class="text-[11px] text-[color:var(--color-ink-3)]">
|
||||||
{{ $contact->responsibility ?? __('Keine Rolle hinterlegt') }}
|
{{ $contact->responsibility ?? __('Keine Rolle hinterlegt') }}
|
||||||
|
|
|
||||||
|
|
@ -584,7 +584,7 @@ new #[Layout('components.layouts.app'), Title('Firma')] class extends Component
|
||||||
<div class="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
|
<div class="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
|
||||||
<div class="min-w-0">
|
<div class="min-w-0">
|
||||||
<div class="text-[13px] font-semibold text-[color:var(--color-ink)]">
|
<div class="text-[13px] font-semibold text-[color:var(--color-ink)]">
|
||||||
{{ trim(($contact->first_name ?? '').' '.($contact->last_name ?? '')) ?: __('Kontakt ohne Name') }}
|
{{ $contact->displayName() }}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-[12px] text-[color:var(--color-ink-3)] mt-0.5">
|
<div class="text-[12px] text-[color:var(--color-ink-3)] mt-0.5">
|
||||||
{{ $contact->responsibility ?: __('Keine Rolle hinterlegt') }}
|
{{ $contact->responsibility ?: __('Keine Rolle hinterlegt') }}
|
||||||
|
|
|
||||||
|
|
@ -611,7 +611,7 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung')] class extends
|
||||||
@forelse ($contacts as $contact)
|
@forelse ($contacts as $contact)
|
||||||
<div class="rounded-[5px] border border-[color:var(--color-bg-rule)] bg-[color:var(--color-bg-elev)] p-3">
|
<div class="rounded-[5px] border border-[color:var(--color-bg-rule)] bg-[color:var(--color-bg-elev)] p-3">
|
||||||
<div class="text-[13px] font-semibold text-[color:var(--color-ink)]">
|
<div class="text-[13px] font-semibold text-[color:var(--color-ink)]">
|
||||||
{{ trim(($contact->first_name ?? '').' '.($contact->last_name ?? '')) ?: __('Kontakt ohne Name') }}
|
{{ $contact->displayName() }}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-[12px] text-[color:var(--color-ink-3)]">
|
<div class="text-[12px] text-[color:var(--color-ink-3)]">
|
||||||
{{ $contact->responsibility ?: __('Keine Rolle hinterlegt') }}
|
{{ $contact->responsibility ?: __('Keine Rolle hinterlegt') }}
|
||||||
|
|
|
||||||
21
tests/Feature/ContactDisplayNameTest.php
Normal file
21
tests/Feature/ContactDisplayNameTest.php
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Contact;
|
||||||
|
|
||||||
|
test('displayName joins first and last name', function () {
|
||||||
|
$contact = Contact::factory()->make(['first_name' => 'Erika', 'last_name' => 'Mustermann']);
|
||||||
|
|
||||||
|
expect($contact->displayName())->toBe('Erika Mustermann');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('displayName trims a missing part', function () {
|
||||||
|
$contact = Contact::factory()->make(['first_name' => null, 'last_name' => 'Mustermann']);
|
||||||
|
|
||||||
|
expect($contact->displayName())->toBe('Mustermann');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('displayName falls back when both names are empty', function () {
|
||||||
|
$contact = Contact::factory()->make(['first_name' => null, 'last_name' => null]);
|
||||||
|
|
||||||
|
expect($contact->displayName())->toBe(__('Kontakt ohne Name'));
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue