feat: Implement comprehensive entity filtering

This commit is contained in:
gpt-engineer-app[bot]
2025-10-28 14:55:37 +00:00
parent 73377d7464
commit cedd33cc34
14 changed files with 1572 additions and 254 deletions

View File

@@ -5,10 +5,13 @@ import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Dialog, DialogContent } from '@/components/ui/dialog';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Filter, SlidersHorizontal, FerrisWheel, Plus } from 'lucide-react';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
import { Card, CardContent } from '@/components/ui/card';
import { Filter, SlidersHorizontal, FerrisWheel, Plus, ChevronDown } from 'lucide-react';
import { AutocompleteSearch } from '@/components/search/AutocompleteSearch';
import { RideCard } from '@/components/rides/RideCard';
import { RideForm } from '@/components/admin/RideForm';
import { RideFilters, RideFilterState, defaultRideFilters } from '@/components/rides/RideFilters';
import { Ride } from '@/types/database';
import { supabase } from '@/integrations/supabase/client';
import { useAuth } from '@/hooks/useAuth';
@@ -26,51 +29,25 @@ export default function Rides() {
const [loading, setLoading] = useState(true);
const [searchQuery, setSearchQuery] = useState('');
const [sortBy, setSortBy] = useState('name');
const [filterCategory, setFilterCategory] = useState('all');
const [filterStatus, setFilterStatus] = useState('all');
const [filters, setFilters] = useState<RideFilterState>(defaultRideFilters);
const [showFilters, setShowFilters] = useState(false);
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
useEffect(() => {
fetchRides();
}, [sortBy, filterCategory, filterStatus]);
}, []);
const fetchRides = async () => {
try {
let query = supabase
const { data } = await supabase
.from('rides')
.select(`
*,
park:parks!inner(name, slug, location:locations(*)),
manufacturer:companies!rides_manufacturer_id_fkey(*)
`);
// Apply filters
if (filterCategory !== 'all') {
query = query.eq('category', filterCategory);
}
if (filterStatus !== 'all') {
query = query.eq('status', filterStatus);
}
// Apply sorting
switch (sortBy) {
case 'rating':
query = query.order('average_rating', { ascending: false });
break;
case 'speed':
query = query.order('max_speed_kmh', { ascending: false, nullsFirst: false });
break;
case 'height':
query = query.order('max_height_meters', { ascending: false, nullsFirst: false });
break;
case 'reviews':
query = query.order('review_count', { ascending: false });
break;
default:
query = query.order('name');
}
const { data } = await query;
manufacturer:companies!rides_manufacturer_id_fkey(*),
designer:companies!rides_designer_id_fkey(*)
`)
.order('name');
setRides(data || []);
} catch (error) {
console.error('Error fetching rides:', error);
@@ -207,34 +184,27 @@ export default function Rides() {
</SelectContent>
</Select>
<Select value={filterCategory} onValueChange={setFilterCategory}>
<SelectTrigger className="w-[160px]">
<Filter className="w-4 h-4 mr-2" />
<SelectValue />
</SelectTrigger>
<SelectContent>
{categories.map(category => (
<SelectItem key={category.value} value={category.value}>
{category.label}
</SelectItem>
))}
</SelectContent>
</Select>
<Select value={filterStatus} onValueChange={setFilterStatus}>
<SelectTrigger className="w-[140px]">
<SelectValue />
</SelectTrigger>
<SelectContent>
{statusOptions.map(status => (
<SelectItem key={status.value} value={status.value}>
{status.label}
</SelectItem>
))}
</SelectContent>
</Select>
<Button
variant="outline"
onClick={() => setShowFilters(!showFilters)}
className="gap-2"
>
<Filter className="w-4 h-4" />
Filters
<ChevronDown className={`w-4 h-4 transition-transform ${showFilters ? 'rotate-180' : ''}`} />
</Button>
</div>
</div>
<Collapsible open={showFilters} onOpenChange={setShowFilters}>
<CollapsibleContent>
<Card>
<CardContent className="pt-6">
<RideFilters filters={filters} onFiltersChange={setFilters} rides={rides} />
</CardContent>
</Card>
</CollapsibleContent>
</Collapsible>
</div>
{/* Rides Grid */}