Update client listing to show contacts. menu buttons to add and remove contacts (not yet functional)

This commit is contained in:
Matt Young 2026-01-28 05:49:59 -06:00
parent 7f3c7aeca1
commit d5de439bb6
3 changed files with 40 additions and 6 deletions

View File

@ -3,6 +3,7 @@
namespace App\Models;
use App\Enums\ClientStatus;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
@ -30,11 +31,9 @@ class Client extends Model
->withPivot('is_primary');
}
public function primaryContact(): BelongsToMany
protected function primaryContact(): Attribute
{
return $this->belongsToMany(Contact::class)
->wherePivot('is_primary', true)
->withPivot('is_primary');
return Attribute::get(fn () => $this->contacts()->wherePivot('is_primary', true)->first());
}
public function invoices(): HasMany

View File

@ -4,6 +4,7 @@ namespace App\Models;
use App\Casts\PhoneNumberCast;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
@ -27,4 +28,11 @@ class Contact extends Model
{
return Invoice::whereIn('client_id', $this->clients()->pluck('clients.id'));
}
protected function fullName(): Attribute
{
return Attribute::make(
get: fn (mixed $value, array $attributes) => $attributes['first_name'].' '.$attributes['last_name'],
);
}
}

View File

@ -25,7 +25,9 @@ new class extends Component {
#[On('client-created')]
#[On('client-updated')]
public function refresh(): void {}
public function refresh(): void
{
}
#[Computed]
public function clients()
@ -47,6 +49,9 @@ new class extends Component {
wire:click="sort('abbreviation')">
Abbreviation
</flux:table.column>
<flux:table.column>
Contacts
</flux:table.column>
<flux:table.column sortable :sorted="$sortBy === 'audition_date'" :direction="$sortDirection"
wire:click="sort('audition_date')">
Audition Date
@ -67,6 +72,17 @@ new class extends Component {
<flux:table.row :key="$client->id">
<flux:table.cell>{{ $client->name }}</flux:table.cell>
<flux:table.cell>{{ $client->abbreviation ?? '' }}</flux:table.cell>
<flux:table.cell>
@if($client->primary_contact)
<div class="flex items-center gap-1">
<flux:icon.star variant="micro"/>
{{ $client->primary_contact?->full_name }}
</div>
@endif
@foreach($client->secondaryContacts as $contact)
<p>{{ $contact->full_name }}</p>
@endforeach
</flux:table.cell>
<flux:table.cell>{{ $client->audition_date?->local()->format('m/d/Y') ?? '' }}</flux:table.cell>
<flux:table.cell>
<flux:badge :color="$client->status->color()">
@ -82,7 +98,18 @@ new class extends Component {
<flux:navmenu>
<flux:menu.group heading="{{ $client->abbreviation }}">
<flux:menu.separator></flux:menu.separator>
<flux:menu.item wire:click="$dispatch('edit-client', { clientId: {{ $client->id }} })" icon="pencil">Edit</flux:menu.item>
<flux:menu.item
wire:click="$dispatch('edit-client', { clientId: {{ $client->id }} })"
icon="pencil">Edit Client
</flux:menu.item>
</flux:menu.group>
<flux:menu.group heading="Contacts">
<flux:menu.item
icon="user-plus">Add Contact
</flux:menu.item>
<flux:menu.item
icon="user-minus">Remove Contact
</flux:menu.item>
</flux:menu.group>
</flux:navmenu>
</flux:dropdown>