Files
thrillwiki_laravel/app/Livewire/AutocompleteComponent.php

87 lines
2.2 KiB
PHP

<?php
namespace App\Livewire;
use App\Models\Park;
use App\Models\Ride;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Builder;
use Livewire\Component;
class AutocompleteComponent extends Component
{
public string $query = '';
public string $type = 'park';
public array $suggestions = [];
public ?string $selectedId = null;
protected $queryString = [
'query' => ['except' => ''],
'type' => ['except' => 'park']
];
public function mount(string $type = 'park'): void
{
$this->type = $type;
}
public function render(): View
{
return view('livewire.autocomplete', [
'suggestions' => $this->suggestions
]);
}
public function updatedQuery(): void
{
if (strlen($this->query) < 2) {
$this->suggestions = [];
return;
}
$this->suggestions = match ($this->type) {
'park' => $this->getParkSuggestions(),
'ride' => $this->getRideSuggestions(),
default => [],
};
}
protected function getParkSuggestions(): array
{
return Park::query()
->select(['id', 'name', 'slug'])
->where('name', 'like', "%{$this->query}%")
->orderBy('name')
->limit(5)
->get()
->map(fn($park) => [
'id' => $park->id,
'text' => $park->name,
'url' => route('parks.show', $park->slug)
])
->toArray();
}
protected function getRideSuggestions(): array
{
return Ride::query()
->select(['id', 'name', 'slug', 'park_id'])
->with('park:id,name')
->where('name', 'like', "%{$this->query}%")
->orderBy('name')
->limit(5)
->get()
->map(fn($ride) => [
'id' => $ride->id,
'text' => "{$ride->name} at {$ride->park->name}",
'url' => route('rides.show', $ride->slug)
])
->toArray();
}
public function selectSuggestion(string $id): void
{
$this->selectedId = $id;
$this->dispatch('suggestion-selected', id: $id);
}
}