incr/app/Livewire/Counter.php

111 lines
2.3 KiB
PHP
Raw Permalink Normal View History

<?php
declare(strict_types=1);
namespace App\Livewire;
use App\Models\Tracker;
use Illuminate\Contracts\View\View;
use Livewire\Attributes\Locked;
use Livewire\Attributes\Validate;
use Livewire\Component;
class Counter extends Component
{
// Ceiling of the unsigned int column backing trackers.count.
public const MAX_COUNT = 4294967295;
#[Locked]
public int $count = 0;
#[Locked]
public bool $needsOnboarding = false;
public bool $editing = false;
#[Validate('required|integer|min:0|max:'.self::MAX_COUNT)]
public ?int $value = null;
public function mount(): void
{
$tracker = Tracker::current();
$this->needsOnboarding = $tracker === null;
if ($tracker !== null) {
$this->syncFrom($tracker);
}
}
public function initialise(): void
{
$this->validate();
$tracker = Tracker::current() ?? Tracker::create([
'label' => 'Counter',
'unit' => 'units',
'count' => $this->value,
]);
$this->syncFrom($tracker);
$this->needsOnboarding = false;
}
public function increment(): void
{
$tracker = Tracker::current();
if (! $tracker || $tracker->count >= self::MAX_COUNT) {
return;
}
$tracker->increment('count');
$this->syncFrom($tracker->refresh());
}
public function edit(): void
{
$this->value = $this->count;
$this->resetValidation();
$this->editing = true;
}
public function save(): void
{
$this->validate();
$tracker = Tracker::current();
if (! $tracker) {
return;
}
$tracker->update(['count' => $this->value]);
$this->syncFrom($tracker);
$this->editing = false;
}
public function cancel(): void
{
$this->value = $this->count;
$this->resetValidation();
$this->editing = false;
}
/**
* The tracker is the source of truth; the form input always mirrors it.
*/
private function syncFrom(Tracker $tracker): void
{
$this->count = $tracker->count;
$this->value = $this->count;
}
public function render(): View
{
return view('livewire.counter')->layout('layouts.app');
}
}