Refactor: Convert park filters to multi-select

This commit is contained in:
gpt-engineer-app[bot]
2025-10-28 15:44:31 +00:00
parent 477844310f
commit c48509efc4
4 changed files with 53 additions and 92 deletions

View File

@@ -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} onChange={(value) => onFiltersChange({ ...filters, parkType: value })}
onValueChange={(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} onChange={(value) => onFiltersChange({ ...filters, status: value })}
onValueChange={(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} onChange={(value) => onFiltersChange({ ...filters, country: value })}
onValueChange={(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"

View File

@@ -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;

View File

@@ -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;

View File

@@ -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++;