mirror of
https://github.com/pacnpal/thrillwiki_laravel.git
synced 2025-12-20 08:51:11 -05:00
feat: implement search functionality with real-time filtering and pagination
This commit is contained in:
136
app/Livewire/SearchComponent.php
Normal file
136
app/Livewire/SearchComponent.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Models\Park;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
class SearchComponent extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
|
||||
// Filter properties
|
||||
public string $search = '';
|
||||
public string $location = '';
|
||||
public ?float $minRating = null;
|
||||
public ?float $maxRating = null;
|
||||
public ?int $minRides = null;
|
||||
public ?int $minCoasters = null;
|
||||
public bool $filtersApplied = false;
|
||||
|
||||
// Querystring parameters
|
||||
protected $queryString = [
|
||||
'search' => ['except' => ''],
|
||||
'location' => ['except' => ''],
|
||||
'minRating' => ['except' => ''],
|
||||
'maxRating' => ['except' => ''],
|
||||
'minRides' => ['except' => ''],
|
||||
'minCoasters' => ['except' => '']
|
||||
];
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->filtersApplied = $this->hasActiveFilters();
|
||||
}
|
||||
|
||||
public function render(): View
|
||||
{
|
||||
return view('livewire.search', [
|
||||
'results' => $this->getFilteredParks()
|
||||
]);
|
||||
}
|
||||
|
||||
public function updatedSearch(): void
|
||||
{
|
||||
$this->resetPage();
|
||||
$this->filtersApplied = $this->hasActiveFilters();
|
||||
}
|
||||
|
||||
public function updatedLocation(): void
|
||||
{
|
||||
$this->resetPage();
|
||||
$this->filtersApplied = $this->hasActiveFilters();
|
||||
}
|
||||
|
||||
public function updatedMinRating(): void
|
||||
{
|
||||
$this->resetPage();
|
||||
$this->filtersApplied = $this->hasActiveFilters();
|
||||
}
|
||||
|
||||
public function updatedMaxRating(): void
|
||||
{
|
||||
$this->resetPage();
|
||||
$this->filtersApplied = $this->hasActiveFilters();
|
||||
}
|
||||
|
||||
public function updatedMinRides(): void
|
||||
{
|
||||
$this->resetPage();
|
||||
$this->filtersApplied = $this->hasActiveFilters();
|
||||
}
|
||||
|
||||
public function updatedMinCoasters(): void
|
||||
{
|
||||
$this->resetPage();
|
||||
$this->filtersApplied = $this->hasActiveFilters();
|
||||
}
|
||||
|
||||
public function clearFilters(): void
|
||||
{
|
||||
$this->reset([
|
||||
'search',
|
||||
'location',
|
||||
'minRating',
|
||||
'maxRating',
|
||||
'minRides',
|
||||
'minCoasters'
|
||||
]);
|
||||
$this->filtersApplied = false;
|
||||
$this->resetPage();
|
||||
}
|
||||
|
||||
protected function getFilteredParks()
|
||||
{
|
||||
return Park::query()
|
||||
->select('parks.*')
|
||||
->with(['location', 'photos'])
|
||||
->when($this->search, function (Builder $query) {
|
||||
$query->where(function (Builder $query) {
|
||||
$query->where('name', 'like', "%{$this->search}%")
|
||||
->orWhere('description', 'like', "%{$this->search}%");
|
||||
});
|
||||
})
|
||||
->when($this->location, function (Builder $query) {
|
||||
$query->whereHas('location', function (Builder $query) {
|
||||
$query->where('address_text', 'like', "%{$this->location}%");
|
||||
});
|
||||
})
|
||||
->when($this->minRating, function (Builder $query) {
|
||||
$query->where('average_rating', '>=', $this->minRating);
|
||||
})
|
||||
->when($this->maxRating, function (Builder $query) {
|
||||
$query->where('average_rating', '<=', $this->maxRating);
|
||||
})
|
||||
->when($this->minRides, function (Builder $query) {
|
||||
$query->where('ride_count', '>=', $this->minRides);
|
||||
})
|
||||
->when($this->minCoasters, function (Builder $query) {
|
||||
$query->where('coaster_count', '>=', $this->minCoasters);
|
||||
})
|
||||
->paginate(10);
|
||||
}
|
||||
|
||||
protected function hasActiveFilters(): bool
|
||||
{
|
||||
return !empty($this->search)
|
||||
|| !empty($this->location)
|
||||
|| !empty($this->minRating)
|
||||
|| !empty($this->maxRating)
|
||||
|| !empty($this->minRides)
|
||||
|| !empty($this->minCoasters);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user