mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-24 12:11:12 -05:00
Reverted to commit 0091584677
This commit is contained in:
@@ -1,13 +1,10 @@
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Star, MapPin, Clock, Zap, FerrisWheel, Waves, Theater, Train, ArrowUp, CheckCircle, Calendar, Hammer, XCircle } from 'lucide-react';
|
||||
import { MeasurementDisplay } from '@/components/ui/measurement-display';
|
||||
import { Ride } from '@/types/database';
|
||||
import { getCloudflareImageUrl } from '@/lib/cloudflareImageUtils';
|
||||
import { queryKeys } from '@/lib/queryKeys';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
|
||||
interface RideCardProps {
|
||||
ride: Ride;
|
||||
@@ -18,47 +15,11 @@ interface RideCardProps {
|
||||
|
||||
export function RideCard({ ride, showParkName = true, className, parkSlug }: RideCardProps) {
|
||||
const navigate = useNavigate();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const handleRideClick = () => {
|
||||
const slug = parkSlug || ride.park?.slug;
|
||||
navigate(`/parks/${slug}/rides/${ride.slug}`);
|
||||
};
|
||||
|
||||
// Prefetch ride detail data on hover
|
||||
const handleMouseEnter = () => {
|
||||
const slug = parkSlug || ride.park?.slug;
|
||||
if (!slug) return;
|
||||
|
||||
// Prefetch ride detail page data
|
||||
queryClient.prefetchQuery({
|
||||
queryKey: queryKeys.rides.detail(slug, ride.slug),
|
||||
queryFn: async () => {
|
||||
const { data } = await supabase
|
||||
.from('rides')
|
||||
.select('*')
|
||||
.eq('slug', ride.slug)
|
||||
.single();
|
||||
return data;
|
||||
},
|
||||
staleTime: 5 * 60 * 1000,
|
||||
});
|
||||
|
||||
// Prefetch ride photos (first 10)
|
||||
queryClient.prefetchQuery({
|
||||
queryKey: queryKeys.photos.entity('ride', ride.id),
|
||||
queryFn: async () => {
|
||||
const { data } = await supabase
|
||||
.from('photos')
|
||||
.select('*')
|
||||
.eq('entity_type', 'ride')
|
||||
.eq('entity_id', ride.id)
|
||||
.limit(10);
|
||||
return data;
|
||||
},
|
||||
staleTime: 5 * 60 * 1000,
|
||||
});
|
||||
};
|
||||
|
||||
const getRideIcon = (category: string) => {
|
||||
switch (category) {
|
||||
@@ -100,7 +61,6 @@ export function RideCard({ ride, showParkName = true, className, parkSlug }: Rid
|
||||
<Card
|
||||
className={`group overflow-hidden border-border/50 bg-gradient-to-br from-card via-card to-card/80 hover:shadow-2xl hover:shadow-primary/20 hover:border-primary/30 transition-all duration-300 cursor-pointer hover:scale-[1.02] relative before:absolute before:inset-0 before:rounded-lg before:p-[1px] before:bg-gradient-to-br before:from-primary/20 before:via-transparent before:to-accent/20 before:-z-10 before:opacity-0 hover:before:opacity-100 before:transition-opacity before:duration-300 ${className}`}
|
||||
onClick={handleRideClick}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
>
|
||||
<div className="relative overflow-hidden">
|
||||
{/* Image/Icon Section */}
|
||||
|
||||
@@ -3,10 +3,7 @@ import { Badge } from '@/components/ui/badge';
|
||||
import { FerrisWheel } from 'lucide-react';
|
||||
import { RideModel } from '@/types/database';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { getCloudflareImageUrl } from '@/lib/cloudflareImageUtils';
|
||||
import { queryKeys } from '@/lib/queryKeys';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
|
||||
interface RideModelCardProps {
|
||||
model: RideModel;
|
||||
@@ -15,23 +12,6 @@ interface RideModelCardProps {
|
||||
|
||||
export function RideModelCard({ model, manufacturerSlug }: RideModelCardProps) {
|
||||
const navigate = useNavigate();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
// Prefetch ride model detail data on hover
|
||||
const handleMouseEnter = () => {
|
||||
queryClient.prefetchQuery({
|
||||
queryKey: queryKeys.rideModels.detail(manufacturerSlug, model.slug),
|
||||
queryFn: async () => {
|
||||
const { data } = await supabase
|
||||
.from('ride_models')
|
||||
.select('*')
|
||||
.eq('slug', model.slug)
|
||||
.single();
|
||||
return data;
|
||||
},
|
||||
staleTime: 5 * 60 * 1000,
|
||||
});
|
||||
};
|
||||
|
||||
const formatCategory = (category: string | null | undefined) => {
|
||||
if (!category) return 'Unknown';
|
||||
@@ -62,7 +42,6 @@ export function RideModelCard({ model, manufacturerSlug }: RideModelCardProps) {
|
||||
<Card
|
||||
className="group overflow-hidden border-border/50 bg-gradient-to-br from-card via-card to-card/80 hover:shadow-2xl hover:shadow-primary/20 hover:border-primary/30 transition-all duration-300 cursor-pointer hover:scale-[1.02] relative before:absolute before:inset-0 before:rounded-lg before:p-[1px] before:bg-gradient-to-br before:from-primary/20 before:via-transparent before:to-accent/20 before:-z-10 before:opacity-0 hover:before:opacity-100 before:transition-opacity before:duration-300"
|
||||
onClick={() => navigate(`/manufacturers/${manufacturerSlug}/models/${model.slug}`)}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
>
|
||||
<div className="aspect-[3/2] bg-gradient-to-br from-primary/20 via-secondary/20 to-accent/20 relative overflow-hidden">
|
||||
{(cardImageUrl || cardImageId) ? (
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { RideCard } from '@/components/rides/RideCard';
|
||||
import { useSimilarRides } from '@/hooks/rides/useSimilarRides';
|
||||
|
||||
interface SimilarRidesProps {
|
||||
currentRideId: string;
|
||||
@@ -31,9 +32,44 @@ interface SimilarRide {
|
||||
}
|
||||
|
||||
export function SimilarRides({ currentRideId, parkId, parkSlug, category }: SimilarRidesProps) {
|
||||
const { data: rides, isLoading } = useSimilarRides(currentRideId, parkId, category);
|
||||
const [rides, setRides] = useState<SimilarRide[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
if (isLoading || !rides || rides.length === 0) {
|
||||
useEffect(() => {
|
||||
async function fetchSimilarRides() {
|
||||
const { data, error } = await supabase
|
||||
.from('rides')
|
||||
.select(`
|
||||
id,
|
||||
name,
|
||||
slug,
|
||||
image_url,
|
||||
average_rating,
|
||||
status,
|
||||
category,
|
||||
description,
|
||||
max_speed_kmh,
|
||||
max_height_meters,
|
||||
duration_seconds,
|
||||
review_count,
|
||||
park:parks!inner(name, slug)
|
||||
`)
|
||||
.eq('park_id', parkId)
|
||||
.eq('category', category)
|
||||
.neq('id', currentRideId)
|
||||
.order('average_rating', { ascending: false })
|
||||
.limit(4);
|
||||
|
||||
if (!error && data) {
|
||||
setRides(data);
|
||||
}
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
fetchSimilarRides();
|
||||
}, [currentRideId, parkId, category]);
|
||||
|
||||
if (loading || rides.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user