import { useState, useEffect, useCallback } 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 { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Dialog, DialogContent } from '@/components/ui/dialog'; import { ArrowLeft, Filter, SlidersHorizontal, FerrisWheel, Plus } from 'lucide-react'; import { RideModel, Company, Park } from '@/types/database'; import { RideModelSubmissionData } from '@/types/submission-data'; import { supabase } from '@/lib/supabaseClient'; import { RideModelCard } from '@/components/rides/RideModelCard'; import { RideModelForm } from '@/components/admin/RideModelForm'; import { AutocompleteSearch } from '@/components/search/AutocompleteSearch'; import { useAuth } from '@/hooks/useAuth'; import { toast } from '@/hooks/use-toast'; import { useAuthModal } from '@/hooks/useAuthModal'; import { useDocumentTitle } from '@/hooks/useDocumentTitle'; import { useOpenGraph } from '@/hooks/useOpenGraph'; import { handleNonCriticalError } from '@/lib/errorHandler'; import { SubmissionErrorBoundary } from '@/components/error/SubmissionErrorBoundary'; interface RideModelWithCount extends RideModel { ride_count: number; } export default function ManufacturerModels() { const { manufacturerSlug } = useParams<{ manufacturerSlug: string }>(); const navigate = useNavigate(); const { user } = useAuth(); const { requireAuth } = useAuthModal(); const [manufacturer, setManufacturer] = useState(null); const [models, setModels] = useState([]); const [loading, setLoading] = useState(true); // Update document title when manufacturer changes useDocumentTitle(manufacturer ? `${manufacturer.name} - Models` : 'Manufacturer Models'); const [searchQuery, setSearchQuery] = useState(''); const [sortBy, setSortBy] = useState('name'); const [filterCategory, setFilterCategory] = useState('all'); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); 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 models with ride count let query = supabase .from('ride_models') .select(` *, rides:rides(count) `) .eq('manufacturer_id', manufacturerData.id); if (filterCategory !== 'all') { query = query.eq('category', filterCategory); } switch (sortBy) { case 'name': query = query.order('name'); break; default: query = query.order('name'); } const { data: modelsData, error: modelsError } = await query; if (modelsError) throw modelsError; // Transform data to include ride count const modelsWithCounts: RideModelWithCount[] = (modelsData || []).map(model => ({ ...model, ride_count: Array.isArray(model.rides) ? model.rides[0]?.count || 0 : 0 })) as RideModelWithCount[]; setModels(modelsWithCounts); } } catch (error) { handleNonCriticalError(error, { action: 'Fetch manufacturer models', metadata: { manufacturerSlug } }); } finally { setLoading(false); } }, [manufacturerSlug, sortBy, filterCategory]); useEffect(() => { if (manufacturerSlug) { fetchData(); } }, [manufacturerSlug, fetchData]); const filteredModels = models.filter(model => model.name.toLowerCase().includes(searchQuery.toLowerCase()) || model.description?.toLowerCase().includes(searchQuery.toLowerCase()) ); useOpenGraph({ title: manufacturer ? `${manufacturer.name} - Ride Models` : 'Manufacturer Models', description: manufacturer ? `Browse ${filteredModels.length} ride models by ${manufacturer.name}` : undefined, imageUrl: manufacturer?.banner_image_url || filteredModels[0]?.banner_image_url, imageId: manufacturer?.banner_image_id || filteredModels[0]?.banner_image_id, type: 'website', enabled: !!manufacturer && !loading }); const handleCreateSubmit = async (data: any) => { try { if (!manufacturer) { toast({ title: "Error", description: "Manufacturer information is missing.", variant: "destructive" }); return; } const submissionData: RideModelSubmissionData = { ...data, manufacturer_id: manufacturer.id, ride_type: data.ride_type ?? undefined, }; const { submitRideModelCreation } = await import('@/lib/entitySubmissionHelpers'); await submitRideModelCreation(submissionData as any, user!.id); toast({ title: "Ride Model Submitted", description: "Your ride model submission has been sent for review." }); setIsCreateModalOpen(false); fetchData(); } catch (error) { const message = error instanceof Error ? error.message : "Failed to submit ride model."; toast({ title: "Error", description: message, variant: "destructive" }); } }; const categories = [ { value: 'all', label: 'All Categories' }, { value: 'roller_coaster', label: 'Roller Coasters' }, { value: 'flat_ride', label: 'Flat Rides' }, { value: 'water_ride', label: 'Water Rides' }, { value: 'dark_ride', label: 'Dark Rides' }, { value: 'kiddie_ride', label: 'Kiddie Rides' }, { value: 'transportation', label: 'Transportation' } ]; if (loading) { return (
{[...Array(8)].map((_, i) => (
))}
); } if (!manufacturer) { return (

Manufacturer Not Found

); } return (

Models by {manufacturer.name}

Explore all ride models manufactured by {manufacturer.name}

{filteredModels.length} models
setSearchQuery(query)} showRecentSearches={false} />
{filteredModels.length > 0 ? (
{filteredModels.map((model) => ( ))}
) : (

No models found

{manufacturer.name} doesn't have any models matching your criteria

)}
setIsCreateModalOpen(false)} />
); }