import { useState } from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import * as z from 'zod'; import { Button } from '@/components/ui/button'; import type { RideModelTechnicalSpec } from '@/types/database'; import { getErrorMessage } from '@/lib/errorHandler'; import { handleError } from '@/lib/errorHandler'; import { Input } from '@/components/ui/input'; import { Textarea } from '@/components/ui/textarea'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { SlugField } from '@/components/ui/slug-field'; import { Layers, Save, X } from 'lucide-react'; import { useUserRole } from '@/hooks/useUserRole'; import { EntityMultiImageUploader, ImageAssignments } from '@/components/upload/EntityMultiImageUploader'; import { TechnicalSpecsEditor } from './editors/TechnicalSpecsEditor'; import { TechnicalSpecification } from '@/types/company'; const rideModelSchema = z.object({ name: z.string().min(1, 'Name is required'), slug: z.string().min(1, 'Slug is required'), category: z.string().min(1, 'Category is required'), ride_type: z.string().min(1, 'Ride type is required'), description: z.string().optional(), source_url: z.string().url().optional().or(z.literal('')), submission_notes: z.string().max(1000).optional().or(z.literal('')), images: z.object({ uploaded: z.array(z.object({ url: z.string(), cloudflare_id: z.string().optional(), file: z.instanceof(File).optional(), isLocal: z.boolean().optional(), caption: z.string().optional() })), banner_assignment: z.number().nullable().optional(), card_assignment: z.number().nullable().optional() }).optional() }); type RideModelFormData = z.infer; interface RideModelFormProps { manufacturerName: string; manufacturerId?: string; onSubmit: (data: RideModelFormData & { manufacturer_id?: string; _technical_specifications?: TechnicalSpecification[] }) => void; onCancel: () => void; initialData?: Partial; } const categories = [ 'roller_coaster', 'flat_ride', 'water_ride', 'dark_ride', 'kiddie_ride', 'transportation' ]; export function RideModelForm({ manufacturerName, manufacturerId, onSubmit, onCancel, initialData }: RideModelFormProps) { const { isModerator } = useUserRole(); const [technicalSpecs, setTechnicalSpecs] = useState<{ spec_name: string; spec_value: string; spec_type: 'string' | 'number' | 'boolean' | 'date'; category?: string; unit?: string; display_order: number; }[]>([]); const { register, handleSubmit, setValue, watch, formState: { errors } } = useForm({ resolver: zodResolver(rideModelSchema), defaultValues: { name: initialData?.name || '', slug: initialData?.slug || '', category: initialData?.category || '', ride_type: initialData?.ride_type || '', description: initialData?.description || '', source_url: initialData?.source_url || '', submission_notes: initialData?.submission_notes || '', images: initialData?.images || { uploaded: [] } } }); const handleFormSubmit = (data: RideModelFormData) => { try { // Include relational technical specs with extended type onSubmit({ ...data, manufacturer_id: manufacturerId, _technical_specifications: technicalSpecs }); } catch (error: unknown) { handleError(error, { action: initialData?.id ? 'Update Ride Model' : 'Create Ride Model' }); // Re-throw so parent can handle modal closing throw error; } }; return ( {initialData ? 'Edit Ride Model' : 'Create New Ride Model'}
For manufacturer: {manufacturerName}
{/* Basic Information */}
{errors.name && (

{errors.name.message}

)}
setValue('slug', slug)} isModerator={isModerator()} />
{/* Category and Type */}
{errors.category && (

{errors.category.message}

)}
{errors.ride_type && (

{errors.ride_type.message}

)}
{/* Description */}