import React, { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import * as z from "zod"; import Page from "../../../components/Page"; import DayPicker from "../../../components/DayPicker"; import { useMutation, useQuery } from "@apollo/client"; import { EVENT_MUTATION, DELETE_EVENT_MUTATION, MODIFY_EVENT_MUTATION, } from "../../../gql/eventMutation"; import Upload from "../../../components/upload/UploadAntDesign"; import { useToasts } from "react-toast-notifications"; import SelectField from "../../../components/SelectField"; import Modal from "../../../components/Modal"; import { TAG_QUERY, TagName } from "../../../gql/tagsQuery"; import { Dialog, Transition } from "@headlessui/react"; import { UserI } from "../../../types"; import { getUser } from "../../../utils/getUser"; import { UseQueryResult, useQuery as reactUseQuery } from "react-query"; import { ALLINITIATIVES_QUERY, InitiativeData, } from "../../../gql/allInitiativesQuery"; import { IMAGE_MUTATION } from "../../../gql/imageMutation"; import StaffDropdown from "../../../components/StaffDropdown"; import "./styles.css"; import TimePicker from "../../../components/TimePicker"; import Button from "../../../components/Button"; import Breadcrumb from "../../../components/Breadcrumb"; import { EVENTS_QUERY, EventsData } from "../../../gql/eventsQuery"; import { HiOutlineExclamation, HiX } from "react-icons/hi"; const initialFormValues = { action: "", title: "", description: "", eventdate: null, eventtime: "", location: "", initiative: "", staffPresenter: [], guestPresenter: "", tags: [], }; export interface selectedStaffI { id: number; name: string; } // const urlSchema = z.string().url({ message: "Please enter a valid URL" }).optional(); // const validateUrl = async (url: any) => { // try { // await urlSchema.parse(url); // return true; // } catch (error) { // return false; // } // }; export default function UpdateEventForm() { const [selectedDepartment, setSelectedDepartment] = useState(""); const [filenames, setFileNames] = useState([]); const [action, setAction] = useState(""); const [isActionSelected, setIsActionSelected] = useState(false); const [staffPresenters, setStaffPresenters] = useState([]); const [time, setTime] = useState("12:00"); const user: UseQueryResult = reactUseQuery("user", getUser); const { addToast } = useToasts(); const [isModalOpen, setIsModalOpen] = useState(false); const [isRemoveModalOpen, setIsRemoveModalOpen] = useState(false); const openModal = () => { setIsModalOpen(true); }; const closeModal = () => { setIsModalOpen(false); }; const openRemoveModal = () => { setIsRemoveModalOpen(true); }; const closeRemoveModal = () => { setIsRemoveModalOpen(false); }; const handlePurposeChange = (event: React.ChangeEvent) => { setAction(event.target.value); setIsActionSelected(event.target.value !== "Select an Action"); }; const { data: pastEvents } = useQuery(EVENTS_QUERY, { variables: { pastEvents: true, futureEvents: null }, }); const { data: allEvents } = useQuery(EVENTS_QUERY, { variables: { pastEvents: null, futureEvents: null }, }); const [eventSelected, setEventSelected] = useState(false); const [selectedEvent, setSelectedEvent] = useState(""); const [pastEventSelected, setPastEventSelected] = useState(false); const [selectedPastEvent, setSelectedPastEvent] = useState(-1); const handleEventChange = (event: any) => { setEventSelected(true); setSelectedEvent(event.target.value); }; const eventToRemove = allEvents?.allEvents.find( (Event) => Event.title === selectedEvent ); const eventToModify = allEvents?.allEvents.find( (Event) => Event.id === selectedPastEvent ); const isValidUrl = (url: string) => { return !url || /^https?:\/\/.*/i.test(url); }; const [validationErrors, setValidationErrors] = useState({ slides: '', videoUrl: '' }); const handleSlideChange = (event: React.ChangeEvent) => { setSlides(event.target.value); if (!isValidUrl(event.target.value)) { setValidationErrors(prev => ({ ...prev, slides: 'Please enter a valid URL for slides' })); } else { setValidationErrors(prev => ({ ...prev, slides: '' })); } }; const handleVideoUrlChange = (event: React.ChangeEvent) => { setVideoUrl(event.target.value); if (!isValidUrl(event.target.value)) { setValidationErrors(prev => ({ ...prev, videoUrl: 'Please enter a valid URL for video' })); } else { setValidationErrors(prev => ({ ...prev, videoUrl: '' })); } }; const urlValidation = (url: string) => /^https?:\/\/.*/i.test(url); const [slides, setSlides] = useState(eventToModify?.slides || ""); const [videoUrl, setVideoUrl] = useState(eventToModify?.videoUrl || ""); // const handleSlideChange = (event: React.ChangeEvent) => { // setSlides(event.target.value); // }; // const handleVideoUrlChange = (event: React.ChangeEvent) => { // setVideoUrl(event.target.value); // }; const [eventDate, setEventDate] = useState(""); const originalDateString = eventToRemove?.date; useEffect(() => { if (originalDateString) { const date = new Date(originalDateString); const weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; const months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ]; let hours = date.getUTCHours(); const amOrPm = hours >= 12 ? "PM" : "AM"; hours = hours % 12 || 12; const formattedDate = `${ weekdays[date.getUTCDay()] }, ${date.getUTCDate()} ${months[date.getUTCMonth()]} ${date .getUTCFullYear() .toString() .slice(-2)} at ${hours}:${date .getUTCMinutes() .toString() .padStart(2, "0")} ${amOrPm}`; setEventDate(formattedDate); } else { console.log("Date is undefined."); } }, [originalDateString]); const getZodSchema = (action: string) => { switch (action) { case "Add an Event": return z.object({ action: z .string() .nonempty("Select an action from the dropdown") .refine((value) => value !== "", { message: "Select an action from the dropdown", }), title: z.string().nonempty("Please enter an event name"), description: z.string().nonempty("Please enter an event description"), eventdate: z .date() .nullable() .refine((date: Date | null) => date !== null, { message: "Select an event date", }), location: z.string().nonempty("Please enter location of event"), initiative: z.string().nonempty("An initiative must be selected"), staffPresenter: z.array(z.number()), guestPresenter: z.string(), tags: z.string().array(), }); case "Update Past Event": return z.object({ action: z.string(), slides: z.string().refine(urlValidation, { message: "Please enter a valid URL for slides" }).optional(), videoUrl: z.string().refine(urlValidation, { message: "Please enter a valid URL for video" }).optional(), }); default: return z.object({ action: z.string(), }); } }; useEffect(() => { if (eventToModify) { setSlides(eventToModify.slides || ""); setVideoUrl(eventToModify.videoUrl || ""); } }, [eventToModify]); const formSchema = getZodSchema(action); const { register, handleSubmit, formState: { errors }, control, reset, } = useForm({ resolver: zodResolver(formSchema), defaultValues: { ...initialFormValues, department: selectedDepartment, // slides: eventToModify?.slides || "", // videoUrl: eventToModify?.videoUrl || "", }, }); const [newEvent] = useMutation(EVENT_MUTATION); const [moveImageFromTemp] = useMutation(IMAGE_MUTATION); const [deleteEvent] = useMutation(DELETE_EVENT_MUTATION); const [modifyEvent] = useMutation(MODIFY_EVENT_MUTATION); const onSubmit = async (data: any) => { try { if (data.action === "Add an Event") { var imageResponse; if (filenames.length) { imageResponse = await moveImageFromTemp({ variables: { filenames: filenames, paths: filenames.map( (filename) => `events/${data.title}/${filename}` ), }, }); } const response = await newEvent({ variables: { title: data.title, description: data.description, date: data.eventdate.toLocaleDateString("en-GB", { month: "2-digit", day: "2-digit", year: "numeric", }), eventTime: time, location: data.location, initiativeId: selectedInitiativeId, guestPresenters: data.guestPresenter, staffPresenters: staffPresenters.map((presenter) => presenter.id), tags: [...data.tags], banner: encodeURIComponent( imageResponse?.data?.uploadImageFile.filenames[0] ), user: `${user.data?.givenName} ${user.data?.surname}`, }, }); if (response.data) { addToast("Form submitted successfully", { appearance: "success" }); reset(initialFormValues); setStaffPresenters([]); // Add a delay of 5 seconds before refreshing the page setTimeout(() => { window.location.reload(); }, 2000); } else { console.error("Error submitting the form:", response.errors); addToast("An error occurred while submitting the form", { appearance: "error", }); } } else if (data.action === "Remove an Event") { // Handle the DELETE request for removing an event deleteEvent({ variables: { deleteEventId: eventToRemove?.id, user: `${user.data?.givenName} ${user.data?.surname}`, }, }) .then((response) => { console.log(response); }) .catch((error) => { console.error("Error deleting event:", error); }); addToast("Event removed successfully", { appearance: "success" }); // Add a delay of 5 seconds before refreshing the page setTimeout(() => { window.location.reload(); }, 2000); } else if (data.action === "Update Past Event") { // Handle the Update request for updating a past event // if (slides && !(await validateUrl(slides))) { // addToast("Invalid URL for slides", { appearance: "error" }); // return; // } // if (videoUrl && !(await validateUrl(videoUrl))) { // addToast("Invalid URL for video", { appearance: "error" }); // return; // } if (!isValidUrl(slides) || !isValidUrl(videoUrl)) { addToast("Invalid URL(s) provided", { appearance: "error" }); return; } const variables = { eventId: selectedPastEvent, user: `${user.data?.givenName} ${user.data?.surname}`, slides: slides !== eventToModify?.slides ? slides : undefined, videoUrl: videoUrl !== eventToModify?.videoUrl ? videoUrl : undefined, }; const response = await modifyEvent({ variables }); if (response.data) { addToast("Event updated successfully", { appearance: "success" }); reset(initialFormValues); // Add a delay of 5 seconds before refreshing the page setTimeout(() => { window.location.reload(); }, 2000); } else { console.error("Error updating the event:", response.errors); addToast("An error occurred while updating the event", { appearance: "error", }); } } } catch (error) { console.error("Error submitting the form:", error); addToast("An error occurred while submitting the form", { appearance: "error", }); } }; const [hasGuestPresenters, setHasGuestPresenters] = useState(false); const handleCheckboxChange = () => { // Toggle the state when the checkbox is clicked setHasGuestPresenters(!hasGuestPresenters); }; const [hasEventBanner, setHasEventBanner] = useState(false); const handleBannerChange = () => { // Toggle the state when the checkbox is clicked setHasEventBanner(!hasEventBanner); }; const [hasEventTags, setHasEventTags] = useState(false); const handleTagsChange = () => { // Toggle the state when the checkbox is clicked setHasEventTags(!hasEventTags); }; const options = [ {name: "Select an Action", id: -1}, {name: "Add an Event", id: -1}, {name: "Remove an Event", id: -1}, {name: "Update Past Event", id: -1} ]; const handlePastEventChange = (event: any) => { setSelectedPastEvent(Number(event.target.value)); setPastEventSelected(true); }; const { data: tagName } = useQuery(TAG_QUERY); const { data: InitiativeData } = useQuery(ALLINITIATIVES_QUERY); const [selectedInitiativeId, setSelectedInitiativeId] = useState(); const pages = [ { name: "Update an Event", link: "/update-event", current: true }, ]; return ( {/* Hero Section */}