Optimize recent changes query

This commit is contained in:
gpt-engineer-app[bot]
2025-10-30 22:40:23 +00:00
parent 8623291c62
commit 46ca1c29bc
6 changed files with 253 additions and 60 deletions

View File

@@ -24,6 +24,8 @@ import { getErrorMessage } from '@/lib/errorHandler';
import { useAuthModal } from '@/hooks/useAuthModal';
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
import { useOpenGraph } from '@/hooks/useOpenGraph';
import { useRides } from '@/hooks/rides/useRides';
import { Pagination } from '@/components/common/Pagination';
export default function Rides() {
useDocumentTitle('Rides & Attractions');
@@ -31,45 +33,35 @@ export default function Rides() {
const { user } = useAuth();
const { isModerator } = useUserRole();
const { requireAuth } = useAuthModal();
const [rides, setRides] = useState<Ride[]>([]);
const [loading, setLoading] = useState(true);
const [searchQuery, setSearchQuery] = useState('');
const [sortBy, setSortBy] = useState('name');
const [filters, setFilters] = useState<RideFilterState>(defaultRideFilters);
const [showFilters, setShowFilters] = useState(false);
const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
const [sidebarCollapsed, setSidebarCollapsed] = useState(() => {
const saved = localStorage.getItem('rides-sidebar-collapsed');
return saved ? JSON.parse(saved) : false;
});
useEffect(() => {
fetchRides();
}, []);
// Use TanStack Query hook for data fetching with caching
const { data: rides = [], isLoading: loading, error } = useRides();
useEffect(() => {
localStorage.setItem('rides-sidebar-collapsed', JSON.stringify(sidebarCollapsed));
}, [sidebarCollapsed]);
const fetchRides = async () => {
try {
const { data } = await supabase
.from('rides')
.select(`
*,
park:parks!inner(name, slug, location:locations(*)),
manufacturer:companies!rides_manufacturer_id_fkey(*),
designer:companies!rides_designer_id_fkey(*)
`)
.order('name');
setRides(data || []);
} catch (error) {
console.error('Error fetching rides:', error);
} finally {
setLoading(false);
// Show error toast if query fails
useEffect(() => {
if (error) {
toast({
title: "Error loading rides",
description: error instanceof Error ? error.message : 'Failed to load rides',
variant: "destructive"
});
}
};
}, [error]);
const handleCreateSubmit = async (data: any) => {
try {
@@ -138,8 +130,8 @@ export default function Rides() {
// Parks filter
if (filters.parks.length > 0) {
const parkId = (ride.park as Park)?.id;
if (!parkId || !filters.parks.includes(parkId)) {
// Use park_id from the ride object, not the nested park
if (!ride.park_id || !filters.parks.includes(ride.park_id)) {
return false;
}
}
@@ -284,6 +276,21 @@ export default function Rides() {
return filtered;
}, [rides, searchQuery, sortBy, filters]);
// Pagination for display
const ITEMS_PER_PAGE = 24;
const paginatedRides = React.useMemo(() => {
const start = (currentPage - 1) * ITEMS_PER_PAGE;
const end = start + ITEMS_PER_PAGE;
return filteredAndSortedRides.slice(start, end);
}, [filteredAndSortedRides, currentPage]);
const totalPages = Math.ceil(filteredAndSortedRides.length / ITEMS_PER_PAGE);
// Reset to page 1 when filters change
useEffect(() => {
setCurrentPage(1);
}, [filters, sortBy, searchQuery]);
const generateDescription = () => {
if (!filteredAndSortedRides.length) return 'Discover thrilling rides and roller coasters worldwide';
@@ -488,15 +495,24 @@ export default function Rides() {
{/* Results Area */}
<div className="flex-1 min-w-0">
{filteredAndSortedRides.length > 0 ? (
viewMode === 'grid' ? (
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6 3xl:grid-cols-7 gap-4 lg:gap-5 xl:gap-4 2xl:gap-5">
{filteredAndSortedRides.map((ride) => (
<RideCard key={ride.id} ride={ride} showParkName={true} />
))}
</div>
) : (
<RideListView rides={filteredAndSortedRides} onRideClick={(ride) => navigate(`/parks/${ride.park?.slug}/rides/${ride.slug}`)} />
)
<div>
{viewMode === 'grid' ? (
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6 3xl:grid-cols-7 gap-4 lg:gap-5 xl:gap-4 2xl:gap-5">
{paginatedRides.map((ride) => (
<RideCard key={ride.id} ride={ride} showParkName={true} />
))}
</div>
) : (
<RideListView rides={paginatedRides} onRideClick={(ride) => navigate(`/parks/${ride.park?.slug}/rides/${ride.slug}`)} />
)}
<Pagination
currentPage={currentPage}
totalPages={totalPages}
onPageChange={setCurrentPage}
isLoading={loading}
/>
</div>
) : (
<div className="text-center py-12">
<FerrisWheel className="w-16 h-16 mb-4 mx-auto text-muted-foreground" />