From c4dd22b9c19af155bd99b5f72a6b7af317777e3a Mon Sep 17 00:00:00 2001 From: CycroftX Date: Tue, 3 Feb 2026 20:35:49 +0530 Subject: [PATCH] Add Create Event sheet with form matching API spec --- .../events/components/CreateEventSheet.tsx | 349 ++++++++++++++++++ src/pages/Events.tsx | 17 +- 2 files changed, 359 insertions(+), 7 deletions(-) create mode 100644 src/features/events/components/CreateEventSheet.tsx diff --git a/src/features/events/components/CreateEventSheet.tsx b/src/features/events/components/CreateEventSheet.tsx new file mode 100644 index 0000000..fb007bf --- /dev/null +++ b/src/features/events/components/CreateEventSheet.tsx @@ -0,0 +1,349 @@ + +import { useState } from "react"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import * as z from "zod"; +import { CalendarIcon, Loader2, Upload } from "lucide-react"; +import { format } from "date-fns"; + +import { + Sheet, + SheetContent, + SheetDescription, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "@/components/ui/sheet"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { Textarea } from "@/components/ui/textarea"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { Calendar } from "@/components/ui/calendar"; +import { cn } from "@/lib/utils"; +import { toast } from "sonner"; + +const formSchema = z.object({ + title: z.string().min(2, "Title must be at least 2 characters"), + category: z.string().min(1, "Please select a category"), + date: z.date({ required_error: "Start date is required" }), + endDate: z.date().optional(), + location: z.string().min(2, "Location name is required"), + address: z.string().min(5, "Full address is required"), + description: z.string().optional(), + imageUrl: z.string().url("Please enter a valid image URL").optional().or(z.literal("")), + source: z.enum(["official", "community"]).default("official"), + mapUrl: z.string().url().optional().or(z.literal("")), +}); + +type FormValues = z.infer; + +interface CreateEventSheetProps { + children: React.ReactNode; +} + +export function CreateEventSheet({ children }: CreateEventSheetProps) { + const [open, setOpen] = useState(false); + const [isSubmitting, setIsSubmitting] = useState(false); + + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: { + title: "", + category: "", + location: "", + address: "", + description: "", + imageUrl: "", + source: "official", + mapUrl: "", + }, + }); + + async function onSubmit(data: FormValues) { + setIsSubmitting(true); + // Simulate API call + await new Promise((resolve) => setTimeout(resolve, 1500)); + + console.log("Form submitted:", data); + toast.success("Event created successfully"); + + setIsSubmitting(false); + setOpen(false); + form.reset(); + } + + return ( + + + {children} + + + + Create New Event + + Add a new event to the platform. Fill in legal details and publishing info. + + + +
+ + + ( + + Event Title + + + + + + )} + /> + +
+ ( + + Category + + + + )} + /> + + ( + + Source type + + + + )} + /> +
+ +
+ ( + + Start Date + + + + + + + + + date < new Date(new Date().setHours(0, 0, 0, 0)) + } + initialFocus + /> + + + + + )} + /> + + ( + + End Date (Optional) + + + + + + + + + date < new Date(new Date().setHours(0, 0, 0, 0)) + } + initialFocus + /> + + + + + )} + /> +
+ + ( + + Venue Name + + + + + + )} + /> + + ( + + Full Address + + + + + + )} + /> + + ( + + Banner Image URL + +
+ + +
+
+ + Provide a direct link to the event banner image. + + +
+ )} + /> + + ( + + Description + +