mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 14:11:13 -05:00
Refactor: Convert park filters to multi-select
This commit is contained in:
@@ -82,16 +82,14 @@ export function ParkFilters({ filters, onFiltersChange, parks }: ParkFiltersProp
|
|||||||
return (propertyOwners || []).map(p => ({ label: p.name, value: p.id }));
|
return (propertyOwners || []).map(p => ({ label: p.name, value: p.id }));
|
||||||
}, [propertyOwners]);
|
}, [propertyOwners]);
|
||||||
|
|
||||||
const parkTypes = [
|
const parkTypes: MultiSelectOption[] = [
|
||||||
{ value: 'all', label: 'All Types' },
|
{ value: 'theme_park', label: 'Theme Park' },
|
||||||
{ value: 'theme_park', label: 'Theme Parks' },
|
{ value: 'amusement_park', label: 'Amusement Park' },
|
||||||
{ value: 'amusement_park', label: 'Amusement Parks' },
|
{ value: 'water_park', label: 'Water Park' },
|
||||||
{ value: 'water_park', label: 'Water Parks' },
|
|
||||||
{ value: 'family_entertainment', label: 'Family Entertainment' }
|
{ value: 'family_entertainment', label: 'Family Entertainment' }
|
||||||
];
|
];
|
||||||
|
|
||||||
const statusOptions = [
|
const statusOptions: MultiSelectOption[] = [
|
||||||
{ value: 'all', label: 'All Status' },
|
|
||||||
{ value: 'operating', label: 'Operating' },
|
{ value: 'operating', label: 'Operating' },
|
||||||
{ value: 'seasonal', label: 'Seasonal' },
|
{ value: 'seasonal', label: 'Seasonal' },
|
||||||
{ value: 'under_construction', label: 'Under Construction' },
|
{ value: 'under_construction', label: 'Under Construction' },
|
||||||
@@ -113,9 +111,9 @@ export function ParkFilters({ filters, onFiltersChange, parks }: ParkFiltersProp
|
|||||||
const resetFilters = () => {
|
const resetFilters = () => {
|
||||||
onFiltersChange({
|
onFiltersChange({
|
||||||
search: '',
|
search: '',
|
||||||
parkType: 'all',
|
parkType: [],
|
||||||
status: 'all',
|
status: [],
|
||||||
country: 'all',
|
country: [],
|
||||||
states: [],
|
states: [],
|
||||||
cities: [],
|
cities: [],
|
||||||
operators: [],
|
operators: [],
|
||||||
@@ -145,66 +143,29 @@ export function ParkFilters({ filters, onFiltersChange, parks }: ParkFiltersProp
|
|||||||
|
|
||||||
<FilterSection title="Basic Filters">
|
<FilterSection title="Basic Filters">
|
||||||
<div className="grid grid-cols-1 gap-4">
|
<div className="grid grid-cols-1 gap-4">
|
||||||
{/* Park Type */}
|
<FilterMultiSelectCombobox
|
||||||
<div className="space-y-2">
|
label="Park Type"
|
||||||
<Label>Park Type</Label>
|
options={parkTypes}
|
||||||
<Select
|
|
||||||
value={filters.parkType}
|
value={filters.parkType}
|
||||||
onValueChange={(value) => onFiltersChange({ ...filters, parkType: value })}
|
onChange={(value) => onFiltersChange({ ...filters, parkType: value })}
|
||||||
>
|
placeholder="Select park types"
|
||||||
<SelectTrigger>
|
/>
|
||||||
<SelectValue />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
{parkTypes.map(type => (
|
|
||||||
<SelectItem key={type.value} value={type.value}>
|
|
||||||
{type.label}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Status */}
|
<FilterMultiSelectCombobox
|
||||||
<div className="space-y-2">
|
label="Status"
|
||||||
<Label>Status</Label>
|
options={statusOptions}
|
||||||
<Select
|
|
||||||
value={filters.status}
|
value={filters.status}
|
||||||
onValueChange={(value) => onFiltersChange({ ...filters, status: value })}
|
onChange={(value) => onFiltersChange({ ...filters, status: value })}
|
||||||
>
|
placeholder="Select status"
|
||||||
<SelectTrigger>
|
/>
|
||||||
<SelectValue />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
{statusOptions.map(status => (
|
|
||||||
<SelectItem key={status.value} value={status.value}>
|
|
||||||
{status.label}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Country */}
|
<FilterMultiSelectCombobox
|
||||||
<div className="space-y-2">
|
label="Country"
|
||||||
<Label>Country</Label>
|
options={countryOptions}
|
||||||
<Select
|
|
||||||
value={filters.country}
|
value={filters.country}
|
||||||
onValueChange={(value) => onFiltersChange({ ...filters, country: value })}
|
onChange={(value) => onFiltersChange({ ...filters, country: value })}
|
||||||
>
|
placeholder="Select countries"
|
||||||
<SelectTrigger>
|
/>
|
||||||
<SelectValue />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="all">All Countries</SelectItem>
|
|
||||||
{Array.from(new Set(locations?.map(l => l.country).filter(Boolean) || [])).sort().map(country => (
|
|
||||||
<SelectItem key={country} value={country}>
|
|
||||||
{country}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<FilterMultiSelectCombobox
|
<FilterMultiSelectCombobox
|
||||||
label="States/Provinces"
|
label="States/Provinces"
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ import { FilterState, SortState } from './Parks';
|
|||||||
|
|
||||||
const initialFilters: FilterState = {
|
const initialFilters: FilterState = {
|
||||||
search: '',
|
search: '',
|
||||||
parkType: 'all',
|
parkType: [],
|
||||||
status: 'all',
|
status: [],
|
||||||
country: 'all',
|
country: [],
|
||||||
minRating: 0,
|
minRating: 0,
|
||||||
maxRating: 5,
|
maxRating: 5,
|
||||||
minRides: 0,
|
minRides: 0,
|
||||||
@@ -98,9 +98,9 @@ export default function OperatorParks() {
|
|||||||
park.location?.country?.toLowerCase().includes(searchTerm);
|
park.location?.country?.toLowerCase().includes(searchTerm);
|
||||||
if (!matchesSearch) return false;
|
if (!matchesSearch) return false;
|
||||||
}
|
}
|
||||||
if (filters.parkType !== 'all' && park.park_type !== filters.parkType) return false;
|
if (filters.parkType.length > 0 && !filters.parkType.includes(park.park_type)) return false;
|
||||||
if (filters.status !== 'all' && park.status !== filters.status) return false;
|
if (filters.status.length > 0 && !filters.status.includes(park.status)) return false;
|
||||||
if (filters.country !== 'all' && park.location?.country !== filters.country) return false;
|
if (filters.country.length > 0 && !filters.country.includes(park.location?.country || '')) return false;
|
||||||
|
|
||||||
const rating = park.average_rating || 0;
|
const rating = park.average_rating || 0;
|
||||||
if (rating < filters.minRating || rating > filters.maxRating) return false;
|
if (rating < filters.minRating || rating > filters.maxRating) return false;
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ import { FilterState, SortState } from './Parks';
|
|||||||
|
|
||||||
const initialFilters: FilterState = {
|
const initialFilters: FilterState = {
|
||||||
search: '',
|
search: '',
|
||||||
parkType: 'all',
|
parkType: [],
|
||||||
status: 'all',
|
status: [],
|
||||||
country: 'all',
|
country: [],
|
||||||
minRating: 0,
|
minRating: 0,
|
||||||
maxRating: 5,
|
maxRating: 5,
|
||||||
minRides: 0,
|
minRides: 0,
|
||||||
@@ -98,9 +98,9 @@ export default function OwnerParks() {
|
|||||||
park.location?.country?.toLowerCase().includes(searchTerm);
|
park.location?.country?.toLowerCase().includes(searchTerm);
|
||||||
if (!matchesSearch) return false;
|
if (!matchesSearch) return false;
|
||||||
}
|
}
|
||||||
if (filters.parkType !== 'all' && park.park_type !== filters.parkType) return false;
|
if (filters.parkType.length > 0 && !filters.parkType.includes(park.park_type)) return false;
|
||||||
if (filters.status !== 'all' && park.status !== filters.status) return false;
|
if (filters.status.length > 0 && !filters.status.includes(park.status)) return false;
|
||||||
if (filters.country !== 'all' && park.location?.country !== filters.country) return false;
|
if (filters.country.length > 0 && !filters.country.includes(park.location?.country || '')) return false;
|
||||||
|
|
||||||
const rating = park.average_rating || 0;
|
const rating = park.average_rating || 0;
|
||||||
if (rating < filters.minRating || rating > filters.maxRating) return false;
|
if (rating < filters.minRating || rating > filters.maxRating) return false;
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ import { useAuthModal } from '@/hooks/useAuthModal';
|
|||||||
|
|
||||||
export interface FilterState {
|
export interface FilterState {
|
||||||
search: string;
|
search: string;
|
||||||
parkType: string;
|
parkType: string[];
|
||||||
status: string;
|
status: string[];
|
||||||
country: string;
|
country: string[];
|
||||||
states?: string[];
|
states?: string[];
|
||||||
cities?: string[];
|
cities?: string[];
|
||||||
operators?: string[];
|
operators?: string[];
|
||||||
@@ -65,9 +65,9 @@ export interface SortState {
|
|||||||
|
|
||||||
const initialFilters: FilterState = {
|
const initialFilters: FilterState = {
|
||||||
search: '',
|
search: '',
|
||||||
parkType: 'all',
|
parkType: [],
|
||||||
status: 'all',
|
status: [],
|
||||||
country: 'all',
|
country: [],
|
||||||
states: [],
|
states: [],
|
||||||
cities: [],
|
cities: [],
|
||||||
operators: [],
|
operators: [],
|
||||||
@@ -158,17 +158,17 @@ export default function Parks() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Park type filter
|
// Park type filter
|
||||||
if (filters.parkType !== 'all' && park.park_type !== filters.parkType) {
|
if (filters.parkType.length > 0 && !filters.parkType.includes(park.park_type)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status filter
|
// Status filter
|
||||||
if (filters.status !== 'all' && park.status !== filters.status) {
|
if (filters.status.length > 0 && !filters.status.includes(park.status)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Country filter
|
// Country filter
|
||||||
if (filters.country !== 'all' && park.location?.country !== filters.country) {
|
if (filters.country.length > 0 && !filters.country.includes(park.location?.country || '')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,9 +291,9 @@ export default function Parks() {
|
|||||||
const activeFilterCount = useMemo(() => {
|
const activeFilterCount = useMemo(() => {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
if (filters.search) count++;
|
if (filters.search) count++;
|
||||||
if (filters.parkType !== 'all') count++;
|
if (filters.parkType.length > 0) count++;
|
||||||
if (filters.status !== 'all') count++;
|
if (filters.status.length > 0) count++;
|
||||||
if (filters.country !== 'all') count++;
|
if (filters.country.length > 0) count++;
|
||||||
if (filters.minRating > 0 || filters.maxRating < 5) count++;
|
if (filters.minRating > 0 || filters.maxRating < 5) count++;
|
||||||
if (filters.minRides > 0 || filters.maxRides < 1000) count++;
|
if (filters.minRides > 0 || filters.maxRides < 1000) count++;
|
||||||
if (filters.openingYearStart || filters.openingYearEnd) count++;
|
if (filters.openingYearStart || filters.openingYearEnd) count++;
|
||||||
|
|||||||
Reference in New Issue
Block a user