Files
thrillwiki_laravel/app/Livewire/ParkListComponent.php

134 lines
4.1 KiB
PHP

<?php
namespace App\Livewire;
use App\Models\Park;
use App\Enums\ParkStatus;
use Livewire\Component;
use Livewire\WithPagination;
use Illuminate\Database\Eloquent\Builder;
class ParkListComponent extends Component
{
use WithPagination;
public string $search = '';
public string $status = '';
public string $sort = 'name';
public string $direction = 'asc';
public ?string $operator = null;
public string $viewMode = 'grid';
/** @var array<string, string> */
public array $sortOptions = [
'name' => 'Name',
'opening_date' => 'Opening Date',
'ride_count' => 'Ride Count',
'coaster_count' => 'Coaster Count',
'size_acres' => 'Size',
];
protected $queryString = [
'search' => ['except' => ''],
'status' => ['except' => ''],
'sort' => ['except' => 'name'],
'direction' => ['except' => 'asc'],
'operator' => ['except' => ''],
'viewMode' => ['except' => 'grid'],
];
public function mount(): void
{
$this->resetPage('parks-page');
}
public function updatedSearch(): void
{
$this->resetPage('parks-page');
}
public function updatedStatus(): void
{
$this->resetPage('parks-page');
}
public function updatedOperator(): void
{
$this->resetPage('parks-page');
}
public function updatedViewMode(): void
{
// No need to reset page when changing view mode
}
public function sortBy(string $field): void
{
if ($this->sort === $field) {
$this->direction = $this->direction === 'asc' ? 'desc' : 'asc';
} else {
$this->sort = $field;
$this->direction = 'asc';
}
}
public function getStatusOptions(): array
{
return collect(ParkStatus::cases())
->mapWithKeys(fn (ParkStatus $status) => [$status->value => $status->label()])
->prepend('All Statuses', '')
->toArray();
}
public function getOperatorOptions(): array
{
return \App\Models\Operator::orderBy('name')
->pluck('name', 'id')
->prepend('All Operators', '')
->toArray();
}
public function render()
{
$query = Park::query()
->with(['operator', 'location'])
->when($this->search, function (Builder $query) {
$query->where(function (Builder $q) {
$q->where('name', 'like', '%' . $this->search . '%')
->orWhere('description', 'like', '%' . $this->search . '%');
});
})
->when($this->status, function (Builder $query) {
$query->where('status', $this->status);
})
->when($this->operator, function (Builder $query) {
$query->where('operator_id', $this->operator);
})
->when($this->sort === 'name', function (Builder $query) {
$query->orderBy('name', $this->direction);
})
->when($this->sort === 'opening_date', function (Builder $query) {
$query->orderBy('opening_date', $this->direction)
->orderBy('name', 'asc');
})
->when($this->sort === 'ride_count', function (Builder $query) {
$query->orderBy('ride_count', $this->direction)
->orderBy('name', 'asc');
})
->when($this->sort === 'coaster_count', function (Builder $query) {
$query->orderBy('coaster_count', $this->direction)
->orderBy('name', 'asc');
})
->when($this->sort === 'size_acres', function (Builder $query) {
$query->orderBy('size_acres', $this->direction)
->orderBy('name', 'asc');
});
return view('livewire.park-list-component', [
'parks' => $query->paginate(12, pageName: 'parks-page'),
'statusOptions' => $this->getStatusOptions(),
'operatorOptions' => $this->getOperatorOptions(),
'viewMode' => $this->viewMode,
]);
}
}