import { useState, useEffect, useCallback, lazy, Suspense } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { Header } from '@/components/layout/Header'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Card, CardContent } from '@/components/ui/card'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Dialog, DialogContent } from '@/components/ui/dialog'; import { AdminFormSkeleton } from '@/components/loading/PageSkeletons'; import { ArrowLeft, FerrisWheel, Building2, Edit } from 'lucide-react'; import { RideModel, Ride, Company } from '@/types/database'; import { supabase } from '@/lib/supabaseClient'; import { useTechnicalSpecifications } from '@/hooks/useTechnicalSpecifications'; import { getCloudflareImageUrl } from '@/lib/cloudflareImageUtils'; import { useAuthModal } from '@/hooks/useAuthModal'; import { useAuth } from '@/hooks/useAuth'; import { toast } from '@/hooks/use-toast'; import { getErrorMessage, handleNonCriticalError } from '@/lib/errorHandler'; import { ManufacturerPhotoGallery } from '@/components/companies/ManufacturerPhotoGallery'; // Lazy load admin form const RideModelForm = lazy(() => import('@/components/admin/RideModelForm').then(m => ({ default: m.RideModelForm }))); import { VersionIndicator } from '@/components/versioning/VersionIndicator'; import { EntityVersionHistory } from '@/components/versioning/EntityVersionHistory'; import { useDocumentTitle } from '@/hooks/useDocumentTitle'; import { useOpenGraph } from '@/hooks/useOpenGraph'; export default function RideModelDetail() { const { manufacturerSlug, modelSlug } = useParams<{ manufacturerSlug: string; modelSlug: string }>(); const navigate = useNavigate(); const { user } = useAuth(); const { requireAuth } = useAuthModal(); const [model, setModel] = useState(null); const [manufacturer, setManufacturer] = useState(null); const [rides, setRides] = useState([]); const [loading, setLoading] = useState(true); const [isEditModalOpen, setIsEditModalOpen] = useState(false); // Update document title when model changes useDocumentTitle(model?.name || 'Ride Model Details'); // Update Open Graph meta tags useOpenGraph({ title: model?.name ? `${model.name}${manufacturer?.name ? ` by ${manufacturer.name}` : ''}` : '', description: model?.description || (model ? `${model.name} - A ride model${manufacturer?.name ? ` by ${manufacturer.name}` : ''}` : ''), imageUrl: model?.banner_image_url, imageId: model?.banner_image_id, type: 'website', enabled: !!model }); const [statistics, setStatistics] = useState({ rideCount: 0, photoCount: 0 }); // Fetch technical specifications from relational table const { data: technicalSpecs } = useTechnicalSpecifications('ride_model', model?.id); const fetchData = useCallback(async () => { try { // Fetch manufacturer const { data: manufacturerData, error: manufacturerError } = await supabase .from('companies') .select('*') .eq('slug', manufacturerSlug || '') .eq('company_type', 'manufacturer') .maybeSingle(); if (manufacturerError) throw manufacturerError; setManufacturer(manufacturerData); if (manufacturerData) { // Fetch ride model const { data: modelData, error: modelError } = await supabase .from('ride_models') .select('*') .eq('slug', modelSlug || '') .eq('manufacturer_id', manufacturerData.id) .maybeSingle(); if (modelError) throw modelError; setModel(modelData as RideModel); if (modelData) { // Fetch rides using this model with proper joins const { data: ridesData, error: ridesError } = await supabase .from('rides') .select(` *, park:parks!inner(name, slug, location:locations(*)), manufacturer:companies!rides_manufacturer_id_fkey(*), ride_model:ride_models(id, name, slug, manufacturer_id, category) `) .eq('ride_model_id', modelData.id) .order('name'); if (ridesError) throw ridesError; setRides(ridesData as Ride[] || []); // Fetch statistics const { count: photoCount } = await supabase .from('photos') .select('*', { count: 'exact', head: true }) .eq('entity_type', 'ride_model') .eq('entity_id', modelData.id); setStatistics({ rideCount: ridesData?.length || 0, photoCount: photoCount || 0 }); } } } catch (error) { logger.error('Error fetching data', { error }); } finally { setLoading(false); } }, [manufacturerSlug, modelSlug]); useEffect(() => { if (manufacturerSlug && modelSlug) { fetchData(); } }, [manufacturerSlug, modelSlug, fetchData]); const handleEditSubmit = async (data: any) => { try { if (!user || !model) return; const submissionData = { ...data, manufacturer_id: model.manufacturer_id, }; const { submitRideModelUpdate } = await import('@/lib/entitySubmissionHelpers'); await submitRideModelUpdate(model.id, submissionData, user.id); toast({ title: "Ride Model Updated", description: "Your changes have been submitted for review." }); setIsEditModalOpen(false); fetchData(); } catch (error) { const errorMsg = getErrorMessage(error); toast({ title: "Error", description: errorMsg || "Failed to update ride model.", variant: "destructive" }); } }; const formatCategory = (category: string | null | undefined) => { if (!category) return 'Unknown'; return category.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1) ).join(' '); }; const formatRideType = (type: string | null | undefined) => { if (!type) return 'Unknown'; return type.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1) ).join(' '); }; if (loading) { return (
{[...Array(6)].map((_, i) => (
))}
); } if (!model || !manufacturer) { return (

Ride Model Not Found

); } return (
{/* Hero Section */}
{(model.banner_image_url || model.banner_image_id) && (
{model.name}
)}

{model.name}

{formatCategory(model.category)} {model.ride_type && ( {formatRideType(model.ride_type)} )} {statistics.rideCount} {statistics.rideCount === 1 ? 'ride' : 'rides'}
Overview Rides ({statistics.rideCount}) Photos ({statistics.photoCount}) History {model.description && (

About

{model.description}

)} {technicalSpecs && technicalSpecs.length > 0 && (

Technical Specifications

{technicalSpecs.map((spec) => (
{spec.spec_name.replace(/_/g, ' ')} {spec.spec_value} {spec.spec_unit || ''}
))}
)}

Rides

View all {statistics.rideCount} rides using the {model.name} model

{/* Edit Modal */} }> setIsEditModalOpen(false)} />
); }