feat: Enhance ride detail page with new sections

This commit is contained in:
gpt-engineer-app[bot]
2025-09-29 18:58:22 +00:00
parent cf9fab4f8a
commit 13223fd833
6 changed files with 510 additions and 8 deletions

View File

@@ -0,0 +1,102 @@
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 { Star } from 'lucide-react';
interface SimilarRidesProps {
currentRideId: string;
parkId: string;
parkSlug: string;
category: string;
}
interface SimilarRide {
id: string;
name: string;
slug: string;
image_url: string | null;
average_rating: number;
status: string;
}
export function SimilarRides({ currentRideId, parkId, parkSlug, category }: SimilarRidesProps) {
const [rides, setRides] = useState<SimilarRide[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchSimilarRides() {
const { data, error } = await supabase
.from('rides')
.select('id, name, slug, image_url, average_rating, status')
.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;
}
return (
<Card>
<CardHeader>
<CardTitle>Similar Rides You Might Enjoy</CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{rides.map((ride) => (
<Link
key={ride.id}
to={`/parks/${parkSlug}/rides/${ride.slug}`}
className="group block"
>
<div className="border border-border rounded-lg overflow-hidden hover:shadow-lg transition-shadow">
{ride.image_url ? (
<div className="aspect-video overflow-hidden">
<img
src={ride.image_url}
alt={ride.name}
className="w-full h-full object-cover group-hover:scale-105 transition-transform"
/>
</div>
) : (
<div className="aspect-video bg-accent flex items-center justify-center">
<span className="text-muted-foreground">No image</span>
</div>
)}
<div className="p-3">
<h4 className="font-medium mb-1 group-hover:text-primary transition-colors">
{ride.name}
</h4>
<div className="flex items-center gap-2 text-sm">
<Star className="w-3 h-3 fill-yellow-400 text-yellow-400" />
<span>{ride.average_rating.toFixed(1)}</span>
<span className="text-muted-foreground"></span>
<span className="text-muted-foreground capitalize">{ride.status}</span>
</div>
</div>
</div>
</Link>
))}
</div>
<div className="mt-4 text-center">
<Button variant="outline" asChild>
<Link to={`/parks/${parkSlug}/rides`}>View All Rides</Link>
</Button>
</div>
</CardContent>
</Card>
);
}