2026-08-16 00:57:07 +02:00
|
|
|
<?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;
|
2026-08-16 12:23:28 +02:00
|
|
|
|
|
|
|
|
if ($tracker !== null) {
|
|
|
|
|
$this->syncFrom($tracker);
|
|
|
|
|
}
|
2026-08-16 00:57:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function initialise(): void
|
|
|
|
|
{
|
|
|
|
|
$this->validate();
|
|
|
|
|
|
|
|
|
|
$tracker = Tracker::current() ?? Tracker::create([
|
|
|
|
|
'label' => 'Counter',
|
|
|
|
|
'unit' => 'units',
|
|
|
|
|
'count' => $this->value,
|
|
|
|
|
]);
|
|
|
|
|
|
2026-08-16 12:23:28 +02:00
|
|
|
$this->syncFrom($tracker);
|
2026-08-16 00:57:07 +02:00
|
|
|
$this->needsOnboarding = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function increment(): void
|
|
|
|
|
{
|
|
|
|
|
$tracker = Tracker::current();
|
|
|
|
|
|
|
|
|
|
if (! $tracker || $tracker->count >= self::MAX_COUNT) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$tracker->increment('count');
|
|
|
|
|
|
2026-08-16 12:23:28 +02:00
|
|
|
$this->syncFrom($tracker->refresh());
|
2026-08-16 00:57:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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]);
|
|
|
|
|
|
2026-08-16 12:23:28 +02:00
|
|
|
$this->syncFrom($tracker);
|
2026-08-16 00:57:07 +02:00
|
|
|
$this->editing = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function cancel(): void
|
|
|
|
|
{
|
|
|
|
|
$this->value = $this->count;
|
|
|
|
|
$this->resetValidation();
|
|
|
|
|
$this->editing = false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-16 12:23:28 +02:00
|
|
|
/**
|
|
|
|
|
* 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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-16 00:57:07 +02:00
|
|
|
public function render(): View
|
|
|
|
|
{
|
|
|
|
|
return view('livewire.counter')->layout('layouts.app');
|
|
|
|
|
}
|
|
|
|
|
}
|