import { useState } from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import * as z from 'zod'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Textarea } from '@/components/ui/textarea'; import { Label } from '@/components/ui/label'; import { EntityMultiImageUploader, ImageAssignments } from '@/components/upload/EntityMultiImageUploader'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { DatePicker } from '@/components/ui/date-picker'; import { SlugField } from '@/components/ui/slug-field'; import { toast } from '@/hooks/use-toast'; import { MapPin, Save, X, Plus } from 'lucide-react'; import { Badge } from '@/components/ui/badge'; import { Combobox } from '@/components/ui/combobox'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { useOperators, usePropertyOwners } from '@/hooks/useAutocompleteData'; import { useUserRole } from '@/hooks/useUserRole'; const parkSchema = z.object({ name: z.string().min(1, 'Park name is required'), slug: z.string().min(1, 'Slug is required'), // Auto-generated, validated on submit description: z.string().optional(), park_type: z.string().min(1, 'Park type is required'), status: z.string().min(1, 'Status is required'), opening_date: z.string().optional(), closing_date: z.string().optional(), website_url: z.string().url().optional().or(z.literal('')), phone: z.string().optional(), email: z.string().email().optional().or(z.literal('')), operator_id: z.string().uuid().optional(), property_owner_id: z.string().uuid().optional(), images: z.object({ uploaded: z.array(z.object({ url: z.string(), cloudflare_id: z.string().optional(), file: z.any().optional(), isLocal: z.boolean().optional(), caption: z.string().optional(), })), banner_assignment: z.number().nullable().optional(), card_assignment: z.number().nullable().optional(), }).optional() }); type ParkFormData = z.infer; interface ParkFormProps { onSubmit: (data: ParkFormData & { operator_id?: string; property_owner_id?: string; _compositeSubmission?: any; }) => Promise; onCancel?: () => void; initialData?: Partial; isEditing?: boolean; } const parkTypes = [ 'Theme Park', 'Amusement Park', 'Water Park', 'Family Entertainment Center', 'Adventure Park', 'Safari Park', 'Carnival', 'Fair' ]; const statusOptions = [ 'Operating', 'Seasonal', 'Closed Temporarily', 'Closed Permanently', 'Under Construction', 'Planned' ]; export function ParkForm({ onSubmit, onCancel, initialData, isEditing = false }: ParkFormProps) { const { isModerator } = useUserRole(); const [submitting, setSubmitting] = useState(false); // Operator state const [selectedOperatorId, setSelectedOperatorId] = useState(initialData?.operator_id || ''); const [tempNewOperator, setTempNewOperator] = useState(null); const [isOperatorModalOpen, setIsOperatorModalOpen] = useState(false); // Property Owner state const [selectedPropertyOwnerId, setSelectedPropertyOwnerId] = useState(initialData?.property_owner_id || ''); const [tempNewPropertyOwner, setTempNewPropertyOwner] = useState(null); const [isPropertyOwnerModalOpen, setIsPropertyOwnerModalOpen] = useState(false); // Fetch data const { operators, loading: operatorsLoading } = useOperators(); const { propertyOwners, loading: ownersLoading } = usePropertyOwners(); const { register, handleSubmit, setValue, watch, formState: { errors } } = useForm({ resolver: zodResolver(parkSchema), defaultValues: { name: initialData?.name || '', slug: initialData?.slug || '', description: initialData?.description || '', park_type: initialData?.park_type || '', status: initialData?.status || 'Operating', opening_date: initialData?.opening_date || '', closing_date: initialData?.closing_date || '', website_url: initialData?.website_url || '', phone: initialData?.phone || '', email: initialData?.email || '', operator_id: initialData?.operator_id || undefined, property_owner_id: initialData?.property_owner_id || undefined, images: { uploaded: [] } } }); const handleFormSubmit = async (data: ParkFormData) => { setSubmitting(true); try { // Build composite submission if new entities were created const submissionContent: any = { park: data, }; // Add new operator if created if (tempNewOperator) { submissionContent.new_operator = tempNewOperator; submissionContent.park.operator_id = null; } // Add new property owner if created if (tempNewPropertyOwner) { submissionContent.new_property_owner = tempNewPropertyOwner; submissionContent.park.property_owner_id = null; } await onSubmit({ ...data, operator_id: tempNewOperator ? undefined : (selectedOperatorId || undefined), property_owner_id: tempNewPropertyOwner ? undefined : (selectedPropertyOwnerId || undefined), _compositeSubmission: (tempNewOperator || tempNewPropertyOwner) ? submissionContent : undefined }); toast({ title: isEditing ? "Park Updated" : "Park Created", description: isEditing ? "The park information has been updated successfully." : "The new park has been created successfully." }); } catch (error: any) { toast({ title: "Error", description: error.message || "Failed to save park information.", variant: "destructive" }); } finally { setSubmitting(false); } }; return ( {isEditing ? 'Edit Park' : 'Create New Park'}
{/* Basic Information */}
{errors.name && (

{errors.name.message}

)}
setValue('slug', slug)} isModerator={isModerator()} />
{/* Description */}