Contact management is working.
This commit is contained in:
parent
304238ec98
commit
a1c7ee43f7
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Contact;
|
||||
use Livewire\Component;
|
||||
use Livewire\Attributes\Computed;
|
||||
use Livewire\Attributes\On;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
new class extends Component {
|
||||
use WithPagination;
|
||||
|
||||
public string $sortBy = 'last_name';
|
||||
public string $sortDirection = 'asc';
|
||||
|
||||
public function sort($column): void
|
||||
{
|
||||
if ($this->sortBy === $column) {
|
||||
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
|
||||
} else {
|
||||
$this->sortBy = $column;
|
||||
$this->sortDirection = 'asc';
|
||||
}
|
||||
}
|
||||
|
||||
#[On('contact-created')]
|
||||
#[On('contact-updated')]
|
||||
public function refresh(): void {}
|
||||
|
||||
#[Computed]
|
||||
public function contacts()
|
||||
{
|
||||
return Contact::orderBy($this->sortBy, $this->sortDirection)->paginate(10);
|
||||
}
|
||||
};
|
||||
?>
|
||||
|
||||
<!--suppress RequiredAttributes -->
|
||||
<div>
|
||||
<flux:table :paginate="$this->contacts">
|
||||
<flux:table.columns>
|
||||
<flux:table.column sortable :sorted="$sortBy === 'first_name'" :direction="$sortDirection"
|
||||
wire:click="sort('first_name')">
|
||||
First Name
|
||||
</flux:table.column>
|
||||
<flux:table.column sortable :sorted="$sortBy === 'last_name'" :direction="$sortDirection"
|
||||
wire:click="sort('last_name')">
|
||||
Last Name
|
||||
</flux:table.column>
|
||||
<flux:table.column sortable :sorted="$sortBy === 'email'" :direction="$sortDirection"
|
||||
wire:click="sort('email')">
|
||||
Email
|
||||
</flux:table.column>
|
||||
<flux:table.column sortable :sorted="$sortBy === 'phone'" :direction="$sortDirection"
|
||||
wire:click="sort('phone')">
|
||||
Phone
|
||||
</flux:table.column>
|
||||
<flux:table.column sortable :sorted="$sortBy === 'created_at'" :direction="$sortDirection"
|
||||
wire:click="sort('created_at')">
|
||||
Created
|
||||
</flux:table.column>
|
||||
<flux:table.column></flux:table.column>
|
||||
</flux:table.columns>
|
||||
|
||||
<flux:table.rows>
|
||||
@foreach($this->contacts as $contact)
|
||||
<flux:table.row :key="$contact->id">
|
||||
<flux:table.cell>{{ $contact->first_name }}</flux:table.cell>
|
||||
<flux:table.cell>{{ $contact->last_name }}</flux:table.cell>
|
||||
<flux:table.cell>{{ $contact->email }}</flux:table.cell>
|
||||
<flux:table.cell>{{ $contact->phone }}</flux:table.cell>
|
||||
<flux:table.cell>{{ $contact->created_at->local()->format('m/d/Y | g:i A') }}</flux:table.cell>
|
||||
<flux:table.cell>
|
||||
<flux:dropdown position="bottom" align="start">
|
||||
<flux:button variant="ghost" size="sm" icon="ellipsis-horizontal"
|
||||
inset="top bottom"></flux:button>
|
||||
|
||||
<flux:navmenu>
|
||||
<flux:menu.group heading="{{ $contact->first_name }} {{ $contact->last_name }}">
|
||||
<flux:menu.separator></flux:menu.separator>
|
||||
<flux:menu.item wire:click="$dispatch('edit-contact', { contactId: {{ $contact->id }} })" icon="pencil">Edit</flux:menu.item>
|
||||
</flux:menu.group>
|
||||
</flux:navmenu>
|
||||
</flux:dropdown>
|
||||
</flux:table.cell>
|
||||
</flux:table.row>
|
||||
@endforeach
|
||||
</flux:table.rows>
|
||||
</flux:table>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Contact;
|
||||
use Livewire\Component;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Flux\Flux;
|
||||
|
||||
new class extends Component {
|
||||
#[Validate('required|string|max:255')]
|
||||
public string $first_name = '';
|
||||
|
||||
#[Validate('required|string|max:255')]
|
||||
public string $last_name = '';
|
||||
|
||||
#[Validate('required|email|max:255|unique:contacts,email')]
|
||||
public string $email = '';
|
||||
|
||||
#[Validate('nullable|string|max:20')]
|
||||
public string $phone = '';
|
||||
|
||||
public function save(): void
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
Contact::create([
|
||||
'first_name' => $this->first_name,
|
||||
'last_name' => $this->last_name,
|
||||
'email' => $this->email,
|
||||
'phone' => $this->phone ?: null,
|
||||
]);
|
||||
|
||||
$this->reset();
|
||||
Flux::modal('create-contact')->close();
|
||||
$this->dispatch('contact-created');
|
||||
}
|
||||
};
|
||||
?>
|
||||
|
||||
<div>
|
||||
<flux:modal.trigger name="create-contact">
|
||||
<flux:button icon="plus" variant="primary">
|
||||
New Contact
|
||||
</flux:button>
|
||||
</flux:modal.trigger>
|
||||
|
||||
<flux:modal name="create-contact" class="md:w-96">
|
||||
<form wire:submit="save" class="space-y-6">
|
||||
<flux:heading size="lg">Create Contact</flux:heading>
|
||||
|
||||
<flux:input label="First Name" wire:model="first_name" />
|
||||
<flux:input label="Last Name" wire:model="last_name" />
|
||||
<flux:input label="Email" wire:model="email" type="email" />
|
||||
<flux:input label="Phone" wire:model="phone" type="tel" />
|
||||
|
||||
<div class="flex gap-2">
|
||||
<flux:spacer />
|
||||
<flux:button type="submit" variant="primary">Create</flux:button>
|
||||
</div>
|
||||
</form>
|
||||
</flux:modal>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Contact;
|
||||
use Livewire\Component;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Attributes\On;
|
||||
use Flux\Flux;
|
||||
|
||||
new class extends Component {
|
||||
public ?int $contactId = null;
|
||||
|
||||
#[Validate('required|string|max:255')]
|
||||
public string $first_name = '';
|
||||
|
||||
#[Validate('required|string|max:255')]
|
||||
public string $last_name = '';
|
||||
|
||||
#[Validate('required|email|max:255')]
|
||||
public string $email = '';
|
||||
|
||||
#[Validate('nullable|string|max:20')]
|
||||
public string $phone = '';
|
||||
|
||||
#[On('edit-contact')]
|
||||
public function edit(int $contactId): void
|
||||
{
|
||||
$this->contactId = $contactId;
|
||||
$contact = Contact::findOrFail($contactId);
|
||||
|
||||
$this->first_name = $contact->first_name;
|
||||
$this->last_name = $contact->last_name;
|
||||
$this->email = $contact->email;
|
||||
$this->phone = $contact->phone ?? '';
|
||||
|
||||
$this->resetValidation();
|
||||
Flux::modal('edit-contact')->show();
|
||||
}
|
||||
|
||||
public function save(): void
|
||||
{
|
||||
$this->validate([
|
||||
'first_name' => 'required|string|max:255',
|
||||
'last_name' => 'required|string|max:255',
|
||||
'email' => 'required|email|max:255|unique:contacts,email,' . $this->contactId,
|
||||
'phone' => 'nullable|string|max:20',
|
||||
]);
|
||||
|
||||
$contact = Contact::findOrFail($this->contactId);
|
||||
$contact->update([
|
||||
'first_name' => $this->first_name,
|
||||
'last_name' => $this->last_name,
|
||||
'email' => $this->email,
|
||||
'phone' => $this->phone ?: null,
|
||||
]);
|
||||
|
||||
$this->reset();
|
||||
Flux::modal('edit-contact')->close();
|
||||
$this->dispatch('contact-updated');
|
||||
}
|
||||
};
|
||||
?>
|
||||
|
||||
<div>
|
||||
<flux:modal name="edit-contact" class="md:w-96">
|
||||
<form wire:submit="save" class="space-y-6">
|
||||
<flux:heading size="lg">Edit Contact</flux:heading>
|
||||
|
||||
<flux:input label="First Name" wire:model="first_name" />
|
||||
<flux:input label="Last Name" wire:model="last_name" />
|
||||
<flux:input label="Email" wire:model="email" type="email" />
|
||||
<flux:input label="Phone" wire:model="phone" type="tel" />
|
||||
|
||||
<div class="flex gap-2">
|
||||
<flux:spacer />
|
||||
<flux:button type="submit" variant="primary">Save</flux:button>
|
||||
</div>
|
||||
</form>
|
||||
</flux:modal>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<x-layouts::app :title="__('Contacts')">
|
||||
<div class="max-w-7xl mx-auto space-y-4">
|
||||
<div class="flex justify-end">
|
||||
<livewire:create-contact />
|
||||
</div>
|
||||
<livewire:contact-list />
|
||||
<livewire:edit-contact />
|
||||
</div>
|
||||
</x-layouts::app>
|
||||
Loading…
Reference in New Issue