'use client'; import { useForm } from 'react-hook-form'; import { z } from 'zod'; import { zodResolver } from '@hookform/resolvers/zod'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; // Define the schema using Zod const eventSchema = z .object({ name: z.string().min(1, { message: 'Event name is required' }), description: z.string().min(1, { message: 'Description is required' }), capacity: z .number({ invalid_type_error: 'Capacity must be a number' }) .min(1, { message: 'Capacity must be at least 1' }) .refine((val) => Number.isInteger(val), { message: 'Capacity must be an integer', }), ticketPrice: z .number({ invalid_type_error: 'Ticket price must be a number' }) .min(0, { message: 'Ticket price must be at least 0' }) .refine((val) => Number.isInteger(val), { message: 'Ticket price must be in cents', }), eventDate: z.coerce.date({ message: 'Event date is required' }).refine( (date) => { const today = new Date(); today.setHours(0, 0, 0, 0); // Remove time component return date >= today; }, { message: 'Event date must be today or in the future', } ), eventStartTime: z.string().regex(/^(?:[01]\d|2[0-3]):[0-5]\d$/, { message: 'Invalid start time format', }), eventEndTime: z.string().regex(/^(?:[01]\d|2[0-3]):[0-5]\d$/, { message: 'Invalid end time format', }), images: z .array( z .string() .url() .regex( /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/, { message: 'Invalid image URL format' } ) ) .optional(), }) .superRefine((d, ctx) => { // Parse event start time const startTime = new Date(d.eventDate); const [startHours, startMinutes] = d.eventStartTime.split(':').map(Number); startTime.setHours(startHours, startMinutes, 0, 0); // Parse event end time const endTime = new Date(d.eventDate); const [endHours, endMinutes] = d.eventEndTime.split(':').map(Number); endTime.setHours(endHours, endMinutes, 0, 0); const currentDateTime = new Date(); // Check if event start time is in the future if (startTime <= currentDateTime) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Event start time must be in the future', path: ['eventStartTime'], }); } // Check if event end time is after start time if (endTime <= startTime) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Event end time must be after the start time', path: ['eventEndTime'], }); } }); // Define the TypeScript type based on the Zod schema type EventFormData = z.infer; interface EventFormProps { onSubmit: (data: EventFormData) => void; } const EventForm = ({ onSubmit }: EventFormProps) => { const { register, handleSubmit, formState: { errors }, setValue, watch, } = useForm({ resolver: zodResolver(eventSchema), mode: 'onChange', }); const handleFileChange = (e: React.ChangeEvent) => { if (e.target.files) { const filesArray = Array.from(e.target.files).map((file) => URL.createObjectURL(file) ); setValue('images', filesArray, { shouldValidate: true }); } }; const images = watch('images') || []; return (
{errors.name &&

{errors.name.message}

}