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

@@ -29,6 +29,12 @@ import {
import { ReviewsSection } from '@/components/reviews/ReviewsSection';
import { MeasurementDisplay } from '@/components/ui/measurement-display';
import { RidePhotoGallery } from '@/components/rides/RidePhotoGallery';
import { RatingDistribution } from '@/components/rides/RatingDistribution';
import { RideHighlights } from '@/components/rides/RideHighlights';
import { SimilarRides } from '@/components/rides/SimilarRides';
import { FormerNames } from '@/components/rides/FormerNames';
import { RecentPhotosPreview } from '@/components/rides/RecentPhotosPreview';
import { ParkLocationMap } from '@/components/maps/ParkLocationMap';
import { Ride } from '@/types/database';
import { supabase } from '@/integrations/supabase/client';
@@ -37,6 +43,7 @@ export default function RideDetail() {
const navigate = useNavigate();
const [ride, setRide] = useState<Ride | null>(null);
const [loading, setLoading] = useState(true);
const [activeTab, setActiveTab] = useState("overview");
useEffect(() => {
if (parkSlug && rideSlug) {
@@ -54,7 +61,7 @@ export default function RideDetail() {
.maybeSingle();
if (parkData) {
// Then get ride details
// Then get ride details with park_id stored separately
const { data: rideData } = await supabase
.from('rides')
.select(`
@@ -67,6 +74,11 @@ export default function RideDetail() {
.eq('slug', rideSlug)
.maybeSingle();
if (rideData) {
// Store park_id for easier access
(rideData as any).currentParkId = parkData.id;
}
setRide(rideData);
}
} catch (error) {
@@ -193,14 +205,35 @@ export default function RideDetail() {
</div>
{ride.average_rating > 0 && (
<div className="bg-black/20 backdrop-blur-sm rounded-lg p-4 text-center">
<div className="flex items-center gap-2 text-white mb-1">
<Star className="w-5 h-5 fill-yellow-400 text-yellow-400" />
<span className="text-2xl font-bold">{ride.average_rating.toFixed(1)}</span>
<div className="bg-black/30 backdrop-blur-md rounded-lg p-6 text-center min-w-[160px]">
<div className="flex items-center justify-center gap-2 text-white mb-2">
<Star className="w-6 h-6 fill-yellow-400 text-yellow-400" />
<span className="text-3xl font-bold">
{ride.average_rating.toFixed(1)}
</span>
</div>
<div className="text-white/70 text-sm">
{ride.review_count} reviews
<div className="flex items-center justify-center gap-1 mb-3">
{[1, 2, 3, 4, 5].map((star) => (
<Star
key={star}
className={`w-4 h-4 ${
star <= Math.round(ride.average_rating)
? 'fill-yellow-400 text-yellow-400'
: 'text-white/40'
}`}
/>
))}
</div>
<div className="text-white/90 text-sm mb-3">
{ride.review_count} {ride.review_count === 1 ? "review" : "reviews"}
</div>
<Button
size="sm"
variant="secondary"
onClick={() => setActiveTab("reviews")}
>
Write Review
</Button>
</div>
)}
</div>
@@ -323,7 +356,7 @@ export default function RideDetail() {
)}
{/* Main Content */}
<Tabs defaultValue="overview" className="w-full">
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
<TabsList className="grid w-full grid-cols-4">
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="specs">Specifications</TabsTrigger>
@@ -347,9 +380,32 @@ export default function RideDetail() {
</CardContent>
</Card>
)}
<RideHighlights ride={ride} />
{ride.former_names && ride.former_names.length > 0 && (
<FormerNames formerNames={ride.former_names} currentName={ride.name} />
)}
<SimilarRides
currentRideId={ride.id}
parkId={(ride as any).currentParkId}
parkSlug={parkSlug || ''}
category={ride.category}
/>
<RecentPhotosPreview
rideId={ride.id}
onViewAll={() => setActiveTab("photos")}
/>
</div>
<div className="space-y-6">
<RatingDistribution
rideId={ride.id}
totalReviews={ride.review_count}
averageRating={ride.average_rating}
/>
{/* Ride Information */}
<Card>
<CardHeader>
@@ -457,6 +513,22 @@ export default function RideDetail() {
</div>
</CardContent>
</Card>
{ride.park?.location?.latitude && ride.park?.location?.longitude && (
<Card>
<CardHeader>
<CardTitle>Location</CardTitle>
</CardHeader>
<CardContent>
<ParkLocationMap
latitude={ride.park.location.latitude}
longitude={ride.park.location.longitude}
parkName={ride.park.name}
className="h-48"
/>
</CardContent>
</Card>
)}
</div>
</div>
</TabsContent>