homeos/app/Livewire/Modals/ManagePerson.php

95 lines
2.7 KiB
PHP

<?php
namespace App\Livewire\Modals;
use App\Models\Person;
use App\Services\UnifiClient;
use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\Rule;
use Livewire\Features\SupportFileUploads\WithFileUploads;
use LivewireUI\Modal\ModalComponent;
/** Add or edit a person — name, the device (UniFi client MAC) that marks presence, and an avatar. */
class ManagePerson extends ModalComponent
{
use WithFileUploads;
public ?string $personUuid = null;
public bool $editing = false;
public string $name = '';
public string $mac = '';
public $avatar = null;
public ?string $currentAvatarUrl = null;
/** @var array<int, array{mac:string,label:string}> */
public array $clientOptions = [];
public bool $unifiError = false;
public static function modalMaxWidth(): string
{
return 'lg';
}
public function mount(UnifiClient $unifi, ?string $person = null): void
{
try {
$this->clientOptions = collect($unifi->clients())
->map(fn ($c) => ['mac' => strtolower($c->mac ?? ''), 'label' => $c->name ?? $c->hostname ?? ($c->mac ?? '?')])
->filter(fn ($o) => $o['mac'] !== '')
->sortBy('label', SORT_NATURAL | SORT_FLAG_CASE)
->values()->all();
} catch (\Throwable) {
$this->unifiError = true;
}
if ($person !== null) {
$model = Person::where('uuid', $person)->firstOrFail();
$this->editing = true;
$this->personUuid = $model->uuid;
$this->name = $model->name;
$this->mac = $model->mac ?? '';
$this->currentAvatarUrl = $model->avatarUrl();
}
}
public function save()
{
$this->validate([
'name' => 'required|string|max:100',
'mac' => ['nullable', 'string', 'max:32', Rule::unique('persons', 'mac')->ignore($this->personUuid, 'uuid')],
'avatar' => ['nullable', 'image', 'max:4096'],
]);
$person = $this->editing
? Person::where('uuid', $this->personUuid)->firstOrFail()
: new Person(['presence' => 'unknown']);
$person->name = $this->name;
$person->mac = $this->mac ?: null;
if ($this->avatar !== null) {
if ($person->avatar_path) {
Storage::disk('public')->delete($person->avatar_path);
}
$person->avatar_path = $this->avatar->store('avatars', 'public');
}
$person->save();
$this->closeModal();
return redirect()->route('persons.index');
}
public function render()
{
return view('livewire.modals.manage-person');
}
}