Files
thrillwiki_laravel/app/Livewire/RidesListingUniversal.php
pacnpal 97a7682eb7 Add Livewire components for parks, rides, and manufacturers
- Implemented ParksLocationSearch component with loading state and refresh functionality.
- Created ParksMapView component with similar structure and functionality.
- Added RegionalParksListing component for displaying regional parks.
- Developed RidesListingUniversal component for universal listing integration.
- Established ManufacturersListing view with navigation and Livewire integration.
- Added feature tests for various Livewire components including OperatorHierarchyView, OperatorParksListing, OperatorPortfolioCard, OperatorsListing, OperatorsRoleFilter, ParksListing, ParksLocationSearch, ParksMapView, and RegionalParksListing to ensure proper rendering and adherence to patterns.
2025-06-23 21:31:05 -04:00

158 lines
4.2 KiB
PHP

<?php
namespace App\Livewire;
use App\Models\Ride;
use Livewire\Component;
use Livewire\WithPagination;
use Illuminate\Support\Facades\Cache;
use Livewire\Attributes\Url;
class RidesListingUniversal extends Component
{
use WithPagination;
// Universal Listing System integration
public string $entityType = 'rides';
// Search and filter properties with URL binding
#[Url(as: 'q')]
public string $search = '';
#[Url(as: 'categories')]
public array $categories = [];
#[Url(as: 'opening_year_from')]
public string $openingYearFrom = '';
#[Url(as: 'opening_year_to')]
public string $openingYearTo = '';
#[Url(as: 'sort')]
public string $sortBy = 'name';
#[Url(as: 'view')]
public string $viewMode = 'grid';
/**
* Get rides data for Universal Listing System
*/
public function getRidesProperty()
{
$cacheKey = 'rides_listing_' . md5(serialize([
'search' => $this->search,
'categories' => $this->categories,
'openingYearFrom' => $this->openingYearFrom,
'openingYearTo' => $this->openingYearTo,
'sortBy' => $this->sortBy,
'page' => $this->getPage(),
]));
return Cache::remember($cacheKey, 300, function () {
return $this->buildQuery()->paginate(12);
});
}
/**
* Build the optimized query
*/
protected function buildQuery()
{
$query = Ride::query()
->with(['park', 'manufacturer', 'designer', 'photos' => function ($q) {
$q->where('is_featured', true)->limit(1);
}]);
// Multi-term search with Django parity
if (!empty($this->search)) {
$terms = explode(' ', trim($this->search));
foreach ($terms as $term) {
$query->where(function ($subQuery) use ($term) {
$subQuery->where('name', 'ilike', "%{$term}%")
->orWhere('description', 'ilike', "%{$term}%")
->orWhereHas('park', fn($q) => $q->where('name', 'ilike', "%{$term}%"))
->orWhereHas('manufacturer', fn($q) => $q->where('name', 'ilike', "%{$term}%"))
->orWhereHas('designer', fn($q) => $q->where('name', 'ilike', "%{$term}%"));
});
}
}
// Apply filters
if (!empty($this->categories)) {
$query->whereIn('ride_type', $this->categories);
}
if (!empty($this->openingYearFrom)) {
$query->where('opening_date', '>=', "{$this->openingYearFrom}-01-01");
}
if (!empty($this->openingYearTo)) {
$query->where('opening_date', '<=', "{$this->openingYearTo}-12-31");
}
// Apply sorting
switch ($this->sortBy) {
case 'opening_year':
$query->orderBy('opening_date', 'desc');
break;
case 'thrill_rating':
$query->orderBy('thrill_rating', 'desc');
break;
case 'height_meters':
$query->orderBy('height_meters', 'desc');
break;
default:
$query->orderBy('name');
}
return $query;
}
/**
* Reset pagination when filters change
*/
public function updatedSearch(): void
{
$this->resetPage();
}
public function updatedCategories(): void
{
$this->resetPage();
}
public function updatedOpeningYearFrom(): void
{
$this->resetPage();
}
public function updatedOpeningYearTo(): void
{
$this->resetPage();
}
public function updatedSortBy(): void
{
$this->resetPage();
}
/**
* Clear all filters
*/
public function clearFilters(): void
{
$this->reset(['search', 'categories', 'openingYearFrom', 'openingYearTo']);
$this->resetPage();
}
/**
* Render the component using Universal Listing System
*/
public function render()
{
return view('livewire.rides-listing-universal', [
'items' => $this->rides,
'entityType' => $this->entityType,
]);
}
}