Advertisement
mohammed-ahad

updated event

Jan 2nd, 2024
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React, { useEffect, useState } from "react";
  2. import { useForm } from "react-hook-form";
  3. import { zodResolver } from "@hookform/resolvers/zod";
  4. import * as z from "zod";
  5. import Page from "../../../components/Page";
  6. import DayPicker from "../../../components/DayPicker";
  7. import { useMutation, useQuery } from "@apollo/client";
  8. import {
  9.   EVENT_MUTATION,
  10.   DELETE_EVENT_MUTATION,
  11.   MODIFY_EVENT_MUTATION,
  12. } from "../../../gql/eventMutation";
  13. import Upload from "../../../components/upload/UploadAntDesign";
  14. import { useToasts } from "react-toast-notifications";
  15. import SelectField from "../../../components/SelectField";
  16. import Modal from "../../../components/Modal";
  17. import { TAG_QUERY, TagName } from "../../../gql/tagsQuery";
  18. import { Dialog, Transition } from "@headlessui/react";
  19. import { UserI } from "../../../types";
  20. import { getUser } from "../../../utils/getUser";
  21. import { UseQueryResult, useQuery as reactUseQuery } from "react-query";
  22. import {
  23.   ALLINITIATIVES_QUERY,
  24.   InitiativeData,
  25. } from "../../../gql/allInitiativesQuery";
  26. import { IMAGE_MUTATION } from "../../../gql/imageMutation";
  27. import StaffDropdown from "../../../components/StaffDropdown";
  28. import "./styles.css";
  29. import TimePicker from "../../../components/TimePicker";
  30. import Button from "../../../components/Button";
  31. import Breadcrumb from "../../../components/Breadcrumb";
  32. import { EVENTS_QUERY, EventsData } from "../../../gql/eventsQuery";
  33. import { HiOutlineExclamation, HiX } from "react-icons/hi";
  34.  
  35. const initialFormValues = {
  36.   action: "",
  37.   title: "",
  38.   description: "",
  39.   eventdate: null,
  40.   eventtime: "",
  41.   location: "",
  42.   initiative: "",
  43.   staffPresenter: [],
  44.   guestPresenter: "",
  45.   tags: [],
  46. };
  47.  
  48. export interface selectedStaffI {
  49.   id: number;
  50.   name: string;
  51. }
  52.  
  53. // const urlSchema = z.string().url({ message: "Please enter a valid URL" }).optional();
  54.  
  55. // const validateUrl = async (url: any) => {
  56. //   try {
  57. //     await urlSchema.parse(url);
  58. //     return true;
  59. //   } catch (error) {
  60. //     return false;
  61. //   }
  62. // };
  63.  
  64. export default function UpdateEventForm() {
  65.   const [selectedDepartment, setSelectedDepartment] = useState("");
  66.   const [filenames, setFileNames] = useState<string[]>([]);
  67.   const [action, setAction] = useState("");
  68.   const [isActionSelected, setIsActionSelected] = useState(false);
  69.   const [staffPresenters, setStaffPresenters] = useState<selectedStaffI[]>([]);
  70.   const [time, setTime] = useState("12:00");
  71.   const user: UseQueryResult<UserI, any> = reactUseQuery("user", getUser);
  72.  
  73.   const { addToast } = useToasts();
  74.   const [isModalOpen, setIsModalOpen] = useState(false);
  75.   const [isRemoveModalOpen, setIsRemoveModalOpen] = useState(false);
  76.   const openModal = () => {
  77.     setIsModalOpen(true);
  78.   };
  79.  
  80.   const closeModal = () => {
  81.     setIsModalOpen(false);
  82.   };
  83.  
  84.   const openRemoveModal = () => {
  85.     setIsRemoveModalOpen(true);
  86.   };
  87.  
  88.   const closeRemoveModal = () => {
  89.     setIsRemoveModalOpen(false);
  90.   };
  91.  
  92.   const handlePurposeChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
  93.     setAction(event.target.value);
  94.     setIsActionSelected(event.target.value !== "Select an Action");
  95.   };
  96.  
  97.   const { data: pastEvents } = useQuery<EventsData>(EVENTS_QUERY, {
  98.     variables: { pastEvents: true, futureEvents: null },
  99.   });
  100.  
  101.   const { data: allEvents } = useQuery<EventsData>(EVENTS_QUERY, {
  102.     variables: { pastEvents: null, futureEvents: null },
  103.   });
  104.  
  105.   const [eventSelected, setEventSelected] = useState(false);
  106.   const [selectedEvent, setSelectedEvent] = useState("");
  107.  
  108.   const [pastEventSelected, setPastEventSelected] = useState(false);
  109.   const [selectedPastEvent, setSelectedPastEvent] = useState(-1);
  110.  
  111.   const handleEventChange = (event: any) => {
  112.     setEventSelected(true);
  113.     setSelectedEvent(event.target.value);
  114.   };
  115.  
  116.   const eventToRemove = allEvents?.allEvents.find(
  117.     (Event) => Event.title === selectedEvent
  118.   );
  119.  
  120.   const eventToModify = allEvents?.allEvents.find(
  121.     (Event) => Event.id === selectedPastEvent
  122.   );
  123.  
  124.   const isValidUrl = (url: string) => {
  125.     return !url || /^https?:\/\/.*/i.test(url);
  126.   };
  127.  
  128.   const [validationErrors, setValidationErrors] = useState({ slides: '', videoUrl: '' });
  129.  
  130.   const handleSlideChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
  131.     setSlides(event.target.value);
  132.     if (!isValidUrl(event.target.value)) {
  133.       setValidationErrors(prev => ({ ...prev, slides: 'Please enter a valid URL for slides' }));
  134.     } else {
  135.       setValidationErrors(prev => ({ ...prev, slides: '' }));
  136.     }
  137.   };
  138.  
  139.   const handleVideoUrlChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
  140.     setVideoUrl(event.target.value);
  141.     if (!isValidUrl(event.target.value)) {
  142.       setValidationErrors(prev => ({ ...prev, videoUrl: 'Please enter a valid URL for video' }));
  143.     } else {
  144.       setValidationErrors(prev => ({ ...prev, videoUrl: '' }));
  145.     }
  146.   };
  147.  
  148.  
  149.   const urlValidation = (url: string) => /^https?:\/\/.*/i.test(url);
  150.  
  151.   const [slides, setSlides] = useState(eventToModify?.slides || "");
  152.   const [videoUrl, setVideoUrl] = useState(eventToModify?.videoUrl || "");
  153.  
  154.   // const handleSlideChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
  155.   //   setSlides(event.target.value);
  156.   // };
  157.  
  158.   // const handleVideoUrlChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
  159.   //   setVideoUrl(event.target.value);
  160.   // };
  161.  
  162.   const [eventDate, setEventDate] = useState("");
  163.   const originalDateString = eventToRemove?.date;
  164.   useEffect(() => {
  165.     if (originalDateString) {
  166.       const date = new Date(originalDateString);
  167.  
  168.       const weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
  169.       const months = [
  170.         "Jan",
  171.         "Feb",
  172.         "Mar",
  173.         "Apr",
  174.         "May",
  175.         "Jun",
  176.         "Jul",
  177.         "Aug",
  178.         "Sep",
  179.         "Oct",
  180.         "Nov",
  181.         "Dec",
  182.       ];
  183.  
  184.       let hours = date.getUTCHours();
  185.       const amOrPm = hours >= 12 ? "PM" : "AM";
  186.       hours = hours % 12 || 12;
  187.  
  188.       const formattedDate = `${
  189.         weekdays[date.getUTCDay()]
  190.       }, ${date.getUTCDate()} ${months[date.getUTCMonth()]} ${date
  191.         .getUTCFullYear()
  192.         .toString()
  193.         .slice(-2)} at ${hours}:${date
  194.         .getUTCMinutes()
  195.         .toString()
  196.         .padStart(2, "0")} ${amOrPm}`;
  197.       setEventDate(formattedDate);
  198.     } else {
  199.       console.log("Date is undefined.");
  200.     }
  201.   }, [originalDateString]);
  202.  
  203.   const getZodSchema = (action: string) => {
  204.     switch (action) {
  205.       case "Add an Event":
  206.         return z.object({
  207.           action: z
  208.             .string()
  209.             .nonempty("Select an action from the dropdown")
  210.             .refine((value) => value !== "", {
  211.               message: "Select an action from the dropdown",
  212.             }),
  213.           title: z.string().nonempty("Please enter an event name"),
  214.           description: z.string().nonempty("Please enter an event description"),
  215.           eventdate: z
  216.             .date()
  217.             .nullable()
  218.             .refine((date: Date | null) => date !== null, {
  219.               message: "Select an event date",
  220.             }),
  221.           location: z.string().nonempty("Please enter location of event"),
  222.           initiative: z.string().nonempty("An initiative must be selected"),
  223.           staffPresenter: z.array(z.number()),
  224.           guestPresenter: z.string(),
  225.           tags: z.string().array(),
  226.         });
  227.       case "Update Past Event":
  228.         return z.object({
  229.           action: z.string(),
  230.           slides: z.string().refine(urlValidation, { message: "Please enter a valid URL for slides" }).optional(),
  231.           videoUrl: z.string().refine(urlValidation, { message: "Please enter a valid URL for video" }).optional(),
  232.         });
  233.       default:
  234.         return z.object({
  235.           action: z.string(),
  236.         });
  237.     }
  238.   };
  239.  
  240.   useEffect(() => {
  241.     if (eventToModify) {
  242.       setSlides(eventToModify.slides || "");
  243.       setVideoUrl(eventToModify.videoUrl || "");
  244.     }
  245.   }, [eventToModify]);
  246.  
  247.   const formSchema = getZodSchema(action);
  248.  
  249.   const {
  250.     register,
  251.     handleSubmit,
  252.     formState: { errors },
  253.     control,
  254.     reset,
  255.   } = useForm({
  256.     resolver: zodResolver(formSchema),
  257.     defaultValues: {
  258.       ...initialFormValues,
  259.       department: selectedDepartment,
  260.       // slides: eventToModify?.slides || "",
  261.       // videoUrl: eventToModify?.videoUrl || "",
  262.     },
  263.   });
  264.   const [newEvent] = useMutation(EVENT_MUTATION);
  265.   const [moveImageFromTemp] = useMutation(IMAGE_MUTATION);
  266.   const [deleteEvent] = useMutation(DELETE_EVENT_MUTATION);
  267.   const [modifyEvent] = useMutation(MODIFY_EVENT_MUTATION);
  268.   const onSubmit = async (data: any) => {
  269.     try {
  270.       if (data.action === "Add an Event") {
  271.         var imageResponse;
  272.         if (filenames.length) {
  273.           imageResponse = await moveImageFromTemp({
  274.             variables: {
  275.               filenames: filenames,
  276.               paths: filenames.map(
  277.                 (filename) => `events/${data.title}/${filename}`
  278.               ),
  279.             },
  280.           });
  281.         }
  282.         const response = await newEvent({
  283.           variables: {
  284.             title: data.title,
  285.             description: data.description,
  286.             date: data.eventdate.toLocaleDateString("en-GB", {
  287.               month: "2-digit",
  288.               day: "2-digit",
  289.               year: "numeric",
  290.             }),
  291.             eventTime: time,
  292.             location: data.location,
  293.             initiativeId: selectedInitiativeId,
  294.             guestPresenters: data.guestPresenter,
  295.             staffPresenters: staffPresenters.map((presenter) => presenter.id),
  296.             tags: [...data.tags],
  297.             banner: encodeURIComponent(
  298.               imageResponse?.data?.uploadImageFile.filenames[0]
  299.             ),
  300.             user: `${user.data?.givenName} ${user.data?.surname}`,
  301.           },
  302.         });
  303.         if (response.data) {
  304.           addToast("Form submitted successfully", { appearance: "success" });
  305.           reset(initialFormValues);
  306.           setStaffPresenters([]);
  307.  
  308.           // Add a delay of 5 seconds before refreshing the page
  309.           setTimeout(() => {
  310.             window.location.reload();
  311.           }, 2000);
  312.         } else {
  313.           console.error("Error submitting the form:", response.errors);
  314.           addToast("An error occurred while submitting the form", {
  315.             appearance: "error",
  316.           });
  317.         }
  318.       } else if (data.action === "Remove an Event") {
  319.         // Handle the DELETE request for removing an event
  320.         deleteEvent({
  321.           variables: {
  322.             deleteEventId: eventToRemove?.id,
  323.             user: `${user.data?.givenName} ${user.data?.surname}`,
  324.           },
  325.         })
  326.           .then((response) => {
  327.             console.log(response);
  328.           })
  329.           .catch((error) => {
  330.             console.error("Error deleting event:", error);
  331.           });
  332.  
  333.         addToast("Event removed successfully", { appearance: "success" });
  334.  
  335.         // Add a delay of 5 seconds before refreshing the page
  336.         setTimeout(() => {
  337.           window.location.reload();
  338.         }, 2000);
  339.       } else if (data.action === "Update Past Event") {
  340.         // Handle the Update request for updating a past event
  341.  
  342.         // if (slides && !(await validateUrl(slides))) {
  343.         //   addToast("Invalid URL for slides", { appearance: "error" });
  344.         //   return;
  345.         // }
  346.    
  347.         // if (videoUrl && !(await validateUrl(videoUrl))) {
  348.         //   addToast("Invalid URL for video", { appearance: "error" });
  349.         //   return;
  350.         // }
  351.  
  352.         if (!isValidUrl(slides) || !isValidUrl(videoUrl)) {
  353.           addToast("Invalid URL(s) provided", { appearance: "error" });
  354.           return;
  355.         }
  356.         const variables = {
  357.           eventId: selectedPastEvent,
  358.           user: `${user.data?.givenName} ${user.data?.surname}`,
  359.           slides: slides !== eventToModify?.slides ? slides : undefined,
  360.           videoUrl: videoUrl !== eventToModify?.videoUrl ? videoUrl : undefined,
  361.         };
  362.      
  363.         const response = await modifyEvent({ variables });
  364.         if (response.data) {
  365.           addToast("Event updated successfully", { appearance: "success" });
  366.           reset(initialFormValues);
  367.           // Add a delay of 5 seconds before refreshing the page
  368.           setTimeout(() => {
  369.             window.location.reload();
  370.           }, 2000);
  371.         } else {
  372.           console.error("Error updating the event:", response.errors);
  373.           addToast("An error occurred while updating the event", {
  374.             appearance: "error",
  375.           });
  376.         }
  377.       }
  378.     } catch (error) {
  379.       console.error("Error submitting the form:", error);
  380.       addToast("An error occurred while submitting the form", {
  381.         appearance: "error",
  382.       });
  383.     }
  384.   };
  385.  
  386.   const [hasGuestPresenters, setHasGuestPresenters] = useState(false);
  387.   const handleCheckboxChange = () => {
  388.     // Toggle the state when the checkbox is clicked
  389.     setHasGuestPresenters(!hasGuestPresenters);
  390.   };
  391.  
  392.   const [hasEventBanner, setHasEventBanner] = useState(false);
  393.   const handleBannerChange = () => {
  394.     // Toggle the state when the checkbox is clicked
  395.     setHasEventBanner(!hasEventBanner);
  396.   };
  397.  
  398.   const [hasEventTags, setHasEventTags] = useState(false);
  399.   const handleTagsChange = () => {
  400.     // Toggle the state when the checkbox is clicked
  401.     setHasEventTags(!hasEventTags);
  402.   };
  403.  
  404.   const options = [
  405.     {name: "Select an Action", id: -1},
  406.     {name: "Add an Event", id: -1},
  407.     {name: "Remove an Event", id: -1},
  408.     {name: "Update Past Event", id: -1}
  409.   ];
  410.  
  411.   const handlePastEventChange = (event: any) => {
  412.     setSelectedPastEvent(Number(event.target.value));
  413.     setPastEventSelected(true);
  414.   };
  415.  
  416.   const { data: tagName } = useQuery<TagName>(TAG_QUERY);
  417.   const { data: InitiativeData } =
  418.     useQuery<InitiativeData>(ALLINITIATIVES_QUERY);
  419.   const [selectedInitiativeId, setSelectedInitiativeId] = useState<number>();
  420.  
  421.   const pages = [
  422.     { name: "Update an Event", link: "/update-event", current: true },
  423.   ];
  424.  
  425.  
  426.   return (
  427.     <Page>
  428.       {/* Hero Section */}
  429.       <Breadcrumb data={pages} />
  430.       <div className="grid place-items-center py-12">
  431.         <div
  432.           className="absolute inset-x-0 -top-40 -z-20 transform-gpu overflow-hidden blur-3xl sm:-top-80"
  433.           aria-hidden="true"
  434.         >
  435.           <div
  436.             className="relative left-[calc(50%-11rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 rotate-[30deg] bg-gradient-to-tr from-[#bfdbfe] to-[#2563eb] opacity-30 sm:left-[calc(50%-30rem)] sm:w-[72.1875rem]"
  437.             style={{
  438.               clipPath:
  439.                 "polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)",
  440.             }}
  441.           />
  442.         </div>
  443.         {!action && (
  444.           <>
  445.             <div className="mx-auto max-w-2xl">
  446.               <h1 className="text-4xl font-semibold tracking-tight text-text-primary sm:text-6xl animate__animated animate__slideInDown flex pl-4 justify-center">
  447.                 Manage Events
  448.               </h1>
  449.               <p className="mt-6 text-lg text-center leading-8 text-text-secondary">
  450.                 This page serves as a dedicated platform to efficiently manage
  451.                 events within the department. Seamlessly add, remove, or update
  452.                 and event. Please select an action to get started.
  453.               </p>
  454.             </div>
  455.           </>
  456.         )}
  457.         {action === "Add an Event" && (
  458.           <>
  459.             <div className="mx-auto max-w-2xl">
  460.               <h1 className="text-4xl font-semibold tracking-tight text-text-primary sm:text-6xl animate__animated animate__slideInDown flex pl-4 justify-center">
  461.                 Adding an Event
  462.               </h1>
  463.               <p className="mt-6 text-lg text-center leading-8 text-text-secondary">
  464.                 This page is designed to help you easily manage the process of
  465.                 adding new events to the site. You can effortlessly add events
  466.                 to the events page and ensure a smooth experience for your
  467.                 users.
  468.               </p>
  469.             </div>
  470.           </>
  471.         )}
  472.         {action === "Remove an Event" && (
  473.           <>
  474.             <div className="mx-auto max-w-2xl">
  475.               <h1 className="text-4xl font-semibold tracking-tight text-text-primary sm:text-6xl animate__animated animate__slideInDown flex pl-4 justify-center">
  476.                 Remove an Event
  477.               </h1>
  478.               <p className="mt-6 text-lg text-center leading-8 text-text-secondary">
  479.                 This page is designed to help you easily manage the process of
  480.                 removing events from the site.
  481.               </p>
  482.             </div>
  483.           </>
  484.         )}
  485.         {action === "Update Past Event" && (
  486.           <>
  487.             <div className="mx-auto max-w-2xl">
  488.               <h1 className="text-4xl font-semibold tracking-tight text-text-primary sm:text-6xl animate__animated animate__slideInDown flex pl-4 justify-center">
  489.                 Update Past Event
  490.               </h1>
  491.               <p className="mt-6 text-lg text-center leading-8 text-text-secondary">
  492.                 This page is designed to help you easily manage the process of
  493.                 adding updating past events within the site. You can
  494.                 effortlessly update past events; ensuring a smooth experience
  495.                 for your users.
  496.               </p>
  497.             </div>
  498.           </>
  499.         )}
  500.         {action === "Select an Action" && (
  501.           <>
  502.             <div className="mx-auto max-w-2xl">
  503.               <h1 className="text-4xl font-semibold tracking-tight text-text-primary sm:text-6xl animate__animated animate__slideInDown flex pl-4 justify-center">
  504.                 Manage Events
  505.               </h1>
  506.               <p className="mt-6 text-lg text-center leading-8 text-text-secondary">
  507.                 This page serves as a dedicated platform to efficiently manage
  508.                 events within the department. Seamlessly add, remove, or update
  509.                 and event. Please select an action to get started.
  510.               </p>
  511.             </div>
  512.           </>
  513.         )}
  514.  
  515.         <div className="py-12 w-9/12">
  516.           <form
  517.             className="bg-neutral shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl"
  518.             onSubmit={handleSubmit(onSubmit)}
  519.           >
  520.             <div className="px-4 py-8 sm:p-8">
  521.               <div>
  522.                 <SelectField
  523.                   type="select"
  524.                   label="Action"
  525.                   name="action"
  526.                   autoComplete="action-name"
  527.                   options={options}
  528.                   onChange={handlePurposeChange}
  529.                   formSchema={{ control, errors }}
  530.                 />
  531.                 {/* Conditional rendering based on the selected purpose */}
  532.                 {action === "Add an Event" && (
  533.                   <>
  534.                     <div>
  535.                       <SelectField
  536.                         label="Name of Event"
  537.                         name="title"
  538.                         autoComplete="given-name"
  539.                         type="text"
  540.                         placeholder="Enter The Event Name"
  541.                         formSchema={{ control, errors }}
  542.                         options={[]}
  543.                         onChange={onchange}
  544.                         className="text-text-primary placeholder-text-primary"
  545.                       />
  546.                     </div>
  547.                     <div className="grid grid-cols-2 gap-x-6 gap-y-8 py-8 border-t border-gray-900/10">
  548.                       <label className="block text-sm font-medium leading-6 text-text-primary">
  549.                         Description of Event{" "}
  550.                         <span className="text-helpers-error-button">*</span>
  551.                       </label>
  552.                       <div className="w-full">
  553.                         <textarea
  554.                           id="description"
  555.                           {...register("description")}
  556.                           placeholder="Description of The Event"
  557.                           rows={3}
  558.                           className="block w-full rounded-md bg-neutral-dimmed border-0 py-1.5 text-text-primary placeholder-text-primary shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:max-w-md sm:text-sm sm:leading-6"
  559.                           defaultValue={""}
  560.                         />
  561.                         {errors.description && (
  562.                           <p className="error text-helpers-error-button mt-2">
  563.                             {errors.description?.message}
  564.                           </p>
  565.                         )}
  566.                       </div>
  567.                     </div>
  568.  
  569.                     <div className="grid grid-cols-2 gap-x-6 gap-y-8 border-t border-gray-900/10 py-8">
  570.                       <label className="block text-sm font-medium leading-6 text-text-primary">
  571.                         Select Date of Event
  572.                         <span className="text-helpers-error-button">*</span>
  573.                       </label>
  574.                       <DayPicker
  575.                         register={register}
  576.                         errors={errors}
  577.                         formSchema={formSchema}
  578.                         control={control}
  579.                         name="eventdate"
  580.                       />
  581.                     </div>
  582.  
  583.                     <div className="grid grid-cols-2 gap-x-6 gap-y-8 py-8 border-t border-gray-900/10">
  584.                       <label className="block text-sm font-medium leading-6 text-text-primary">
  585.                         Time of Event{" "}
  586.                         <span className="text-helpers-error-button">*</span>
  587.                       </label>
  588.                       <TimePicker
  589.                         time={time}
  590.                         changeTime={setTime}
  591.                         register={register}
  592.                         errors={errors}
  593.                         formSchema={formSchema}
  594.                         control={control}
  595.                       />
  596.                     </div>
  597.  
  598.                     <div className="border-t border-gray-900/10">
  599.                       <SelectField
  600.                         label="Location of Event"
  601.                         name="location"
  602.                         autoComplete="given-name"
  603.                         type="text"
  604.                         placeholder="Enter Location of The Event"
  605.                         formSchema={{ control, errors }}
  606.                         options={[]}
  607.                         onChange={onchange}
  608.                         className="text-text-primary placeholder-text-primary"
  609.                       />
  610.                     </div>
  611.  
  612.                     <div className="grid grid-cols-2 gap-x-6 gap-y-8 py-8 border-t border-gray-900/10">
  613.                       <label className="block text-sm font-medium leading-6 text-text-primary">
  614.                         Hosting Initiative{" "}
  615.                         <span className="text-helpers-error-button">*</span>
  616.                       </label>
  617.                       <div className="w-full">
  618.                         <select
  619.                           id="initiative"
  620.                           {...register("initiative")}
  621.                           autoComplete="Hosting initiative"
  622.                           className="block w-full rounded-md bg-neutral-dimmed border-0 py-1.5 text-text-primary placeholder-text-primary shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:max-w-md sm:text-sm sm:leading-6"
  623.                           onChange={(e) => {
  624.                             const selectedId =
  625.                               InitiativeData?.allInitiatives.find(
  626.                                 (initiative) =>
  627.                                   initiative.name === e.target.value
  628.                               )?.id;
  629.                             setSelectedInitiativeId(selectedId);
  630.                           }}
  631.                         >
  632.                           <option disabled selected value="">
  633.                             Select an Initiative
  634.                           </option>
  635.                           {InitiativeData?.allInitiatives.map(
  636.                             (initiative: any) => (
  637.                               <option
  638.                                 key={initiative.id}
  639.                                 value={initiative.name}
  640.                               >
  641.                                 {initiative.name}
  642.                               </option>
  643.                             )
  644.                           )}
  645.                         </select>
  646.                         {errors.initiative && (
  647.                           <p className="error text-helpers-error-button mt-2">
  648.                             {errors.initiative?.message}
  649.                           </p>
  650.                         )}
  651.                       </div>
  652.                     </div>
  653.  
  654.                     <div className="py-8 border-t border-gray-900/10">
  655.                       <StaffDropdown
  656.                         selectedStaff={staffPresenters}
  657.                         setSelectedStaff={setStaffPresenters}
  658.                         register={register}
  659.                         errors={errors}
  660.                         formSchema={formSchema}
  661.                         control={control}
  662.                       />
  663.                     </div>
  664.                     <div className="border-t border-gray-900/10 mb-8">
  665.                       <div className="mt-8">
  666.                         <label className="block text-sm font-medium leading-6 text-text-primary">
  667.                           Are There Any Guest Presenters?
  668.                           <input
  669.                             type="checkbox"
  670.                             className="ml-2 mb-1 rounded-md bg-neutral-dimmed border-1 shadow-sm ring-inset ring-gray-300 focus:ring-inset focus:ring-elements-secondary-dimmed"
  671.                             onChange={handleCheckboxChange}
  672.                             checked={hasGuestPresenters}
  673.                           />
  674.                         </label>
  675.                       </div>
  676.  
  677.                       {hasGuestPresenters && (
  678.                         <div>
  679.                           <SelectField
  680.                             label="Guest Presenters of Event"
  681.                             name="guestPresenter"
  682.                             autoComplete="given-name"
  683.                             type="text"
  684.                             placeholder="Enter The Guest Presenter Name"
  685.                             formSchema={{ control, errors }}
  686.                             options={[]}
  687.                             onChange={onchange}
  688.                             className="text-text-primary placeholder-text-primary block w-full rounded-md bg-neutral-dimmed border-0 py-1.5 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:max-w-md sm:text-sm sm:leading-6"
  689.                             required={false}
  690.                           />
  691.                         </div>
  692.                       )}
  693.  
  694.                       {!hasGuestPresenters && (
  695.                         <div className="mt-8">
  696.                           <p className="text-sm text-text-tertiary">
  697.                             If the checkbox is left unselected, no guest
  698.                             presenters will be submitted.
  699.                           </p>
  700.                         </div>
  701.                       )}
  702.                     </div>
  703.  
  704.                     <div className="border-t border-gray-900/10 mb-8">
  705.                       <div className="mt-8">
  706.                         <label className="block text-sm font-medium leading-6 text-text-primary">
  707.                           Are There Any Event Tags?
  708.                           <input
  709.                             type="checkbox"
  710.                             className="ml-2 mb-1 rounded-md bg-neutral-dimmed border-1 shadow-sm ring-inset ring-gray-300 focus:ring-inset focus:ring-elements-secondary-dimmed"
  711.                             onChange={handleTagsChange}
  712.                             checked={hasEventTags}
  713.                           />
  714.                         </label>
  715.                       </div>
  716.  
  717.                       {hasEventTags && (
  718.                         <div className="grid grid-cols-2 gap-x-6 gap-y-8 py-8 ">
  719.                           <div>
  720.                             <label className="block text-sm font-medium leading-6 text-text-primary whitespace-nowrap">
  721.                               Event Tag{" "}
  722.                             </label>
  723.                           </div>
  724.                           <div className="w-full">
  725.                             <select
  726.                               id="eventTags"
  727.                               multiple={true}
  728.                               autoComplete="event-tags"
  729.                               className="block w-full overflow-hidden rounded-md bg-neutral-dimmed border-0 py-1.5 text-text-primary placeholder-text-primary shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:max-w-md sm:text-sm sm:leading-6"
  730.                               {...register("tags")}
  731.                             >
  732.                               <option disabled selected value="">
  733.                                 Select Tag Related to the Event
  734.                               </option>
  735.                               {tagName?.allTags.map((tag: any) => (
  736.                                 <option key={tag.id} value={tag.name}>
  737.                                   {tag.name}
  738.                                 </option>
  739.                               ))}
  740.                             </select>
  741.                             {errors.tags && (
  742.                               <p className="error text-helpers-error-button mt-2">
  743.                                 {errors.tags?.message}
  744.                               </p>
  745.                             )}
  746.                           </div>
  747.                         </div>
  748.                       )}
  749.  
  750.                       {!hasEventTags && (
  751.                         <div className="mt-8">
  752.                           <p className="text-sm text-text-tertiary">
  753.                             If the checkbox is left unselected, no event tags
  754.                             will be submitted.
  755.                           </p>
  756.                         </div>
  757.                       )}
  758.                     </div>
  759.  
  760.                     <div className="border-t border-gray-900/10">
  761.                       <div className="mt-8">
  762.                         <label className="block text-sm font-medium leading-6 text-text-primary">
  763.                           Would You Like To Upload An Event Banner?
  764.                           <input
  765.                             type="checkbox"
  766.                             className="ml-2 mb-1 rounded-md bg-neutral-dimmed border-1 shadow-sm ring-inset ring-gray-300 focus:ring-inset focus:ring-elements-secondary-dimmed"
  767.                             onChange={handleBannerChange}
  768.                             checked={hasEventBanner}
  769.                           />
  770.                         </label>
  771.                       </div>
  772.  
  773.                       {hasEventBanner && (
  774.                         <div>
  775.                           <label className="mt-8 block text-sm font-medium leading-6 text-text-primary">
  776.                             Event Banner{" "}
  777.                           </label>
  778.                           <div className="mt-2">
  779.                             <Upload
  780.                               imageType="photo"
  781.                               filenames={filenames}
  782.                               setFileNames={setFileNames}
  783.                               control={control}
  784.                               register={register}
  785.                               errors={errors}
  786.                               formSchema={formSchema}
  787.                               name="file"
  788.                               multiple={false}
  789.                               component_choice="single"
  790.                               showUploadList={false}
  791.                             />
  792.                           </div>
  793.                         </div>
  794.                       )}
  795.  
  796.                       {!hasEventBanner && (
  797.                         <div className="mt-8">
  798.                           <p className="text-sm text-text-tertiary">
  799.                             If no event banner is uploaded, a default image will
  800.                             be used.
  801.                           </p>
  802.                         </div>
  803.                       )}
  804.                     </div>
  805.                   </>
  806.                 )}
  807.  
  808.                 {action === "Remove an Event" && (
  809.                   <>
  810.                     <div className="grid grid-cols-2 gap-x-6 gap-y-8 py-8">
  811.                       <div>
  812.                         <label className="block text-sm font-medium leading-6 text-text-primary whitespace-nowrap">
  813.                           Name of Past Event{" "}
  814.                           <span className="text-helpers-error-button">*</span>
  815.                         </label>
  816.                       </div>
  817.                       <div className="w-full">
  818.                         <select
  819.                           id="name"
  820.                           name="name"
  821.                           autoComplete="event"
  822.                           className="block w-full rounded-md bg-neutral-dimmed border-0 py-1.5 text-text-primary placeholder-text-primary shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:max-w-md sm:text-sm sm:leading-6"
  823.                           onChange={handleEventChange}
  824.                         >
  825.                           <option disabled selected value="">
  826.                             Select Name of Event
  827.                           </option>
  828.                           {allEvents?.allEvents.map((event: any) => (
  829.                             <option>{event.title}</option>
  830.                           ))}
  831.                         </select>
  832.                       </div>
  833.                     </div>
  834.  
  835.                     {eventSelected && (
  836.                       <>
  837.                         <div className="grid grid-cols-2 gap-x-6 gap-y-8 py-8 border-t border-gray-900/10">
  838.                           <label className="block text-sm font-medium leading-6 text-text-primary">
  839.                             Description of Event{" "}
  840.                             <span className="text-helpers-error-button">*</span>
  841.                           </label>
  842.                           <div className="w-full">
  843.                             <textarea
  844.                               id="description"
  845.                               placeholder=""
  846.                               rows={4}
  847.                               className="cursor-not-allowed block w-full rounded-md bg-neutral border-0 py-1.5 text-text-primary sm:max-w-md sm:text-sm sm:leading-6"
  848.                               value={
  849.                                 eventToRemove ? eventToRemove.description : ""
  850.                               }
  851.                               disabled={true}
  852.                             />
  853.                           </div>
  854.                         </div>
  855.                         <div className="grid grid-cols-2 gap-x-6 gap-y-8 border-t border-gray-900/10 py-8">
  856.                           <label className="block text-sm font-medium leading-6 text-text-primary">
  857.                             Date of Event
  858.                             <span className="text-helpers-error-button">*</span>
  859.                           </label>
  860.                           <div className="">
  861.                             <input
  862.                               id="description"
  863.                               placeholder=""
  864.                               className="cursor-not-allowed block w-full rounded-md bg-neutral border-0 py-1.5 text-text-primary sm:max-w-md sm:text-sm sm:leading-6"
  865.                               value={eventDate}
  866.                               disabled={true}
  867.                             />
  868.                           </div>
  869.                         </div>
  870.                       </>
  871.                     )}
  872.                   </>
  873.                 )}
  874.  
  875.                 {action === "Update Past Event" && (
  876.                   <>
  877.                     <div className="grid grid-cols-2 gap-x-6 gap-y-8 py-8">
  878.                       <div>
  879.                         <label className="block text-sm font-medium leading-6 text-text-primary whitespace-nowrap">
  880.                           Name of Past Event{" "}
  881.                           <span className="text-helpers-error-button">*</span>
  882.                         </label>
  883.                       </div>
  884.                       <div className="w-full">
  885.                         <select
  886.                           id="name"
  887.                           {...register("title")}
  888.                           autoComplete="pastEvent"
  889.                           className="block w-full rounded-md bg-neutral-dimmed border-0 py-1.5 text-text-primary placeholder-text-primary shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:max-w-md sm:text-sm sm:leading-6"
  890.                           onChange={handlePastEventChange}
  891.                         >
  892.                           <option disabled selected value="">
  893.                             Select Name of Event
  894.                           </option>
  895.                           {pastEvents?.allEvents.map((event: any) => (
  896.                             <option value={event.id}>{event.title}</option>
  897.                           ))}
  898.                         </select>
  899.                         {errors.title && (
  900.                           <p className="error text-helpers-error-button mt-2">
  901.                             {errors.title?.message}
  902.                           </p>
  903.                         )}
  904.                       </div>
  905.                     </div>
  906.  
  907.                     {/* Conditionally render the Event Video Link and Event Presentation Slides fields */}
  908.                     {pastEventSelected && (
  909.                       <>
  910.                         <div className="py-8 border-t border-gray-900/10">
  911.                           <SelectField
  912.                             label="Video Link"
  913.                             name="videoUrl"
  914.                             autoComplete="given-name"
  915.                             type="text"
  916.                             value={videoUrl}
  917.                             placeholder="Enter The Event MS Stream Link "
  918.                             formSchema={{ control, errors }}
  919.                             options={[]}
  920.                             onChange={handleVideoUrlChange}
  921.                             errorMessage={validationErrors.slides}
  922.                             className="text-text-primary placeholder-text-primary"
  923.                             required={false}
  924.                           />
  925.                         </div>
  926.  
  927.                         <div className="col-span-full border-t border-gray-900/10 pt-8">
  928.                           <SelectField
  929.                             label="Event Presentation Slides"
  930.                             name="slides"
  931.                             autoComplete="given-name"
  932.                             type="text"
  933.                             value={slides}
  934.                             placeholder="Enter The Link For The Presentation Slides"
  935.                             formSchema={{ control, errors }}
  936.                             options={[]}
  937.                             onChange={handleSlideChange}
  938.                             errorMessage={validationErrors.videoUrl}
  939.                             className="text-text-primary placeholder-text-primary"
  940.                             required={false}
  941.                           />
  942.                         </div>
  943.                       </>
  944.                     )}
  945.                   </>
  946.                 )}
  947.               </div>
  948.             </div>
  949.             <div className="flex items-center justify-end gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8">
  950.               <Button
  951.                 type="text"
  952.                 label="Cancel"
  953.                 size="lg"
  954.                 className="text-text-primary"
  955.                 onClick={openModal}
  956.                 disabled={!isActionSelected}
  957.               />
  958.               {isModalOpen && (
  959.                 <Modal
  960.                   closeModal={() => {
  961.                     reset(initialFormValues);
  962.                     window.location.reload();
  963.                     closeModal();
  964.                   }}
  965.                   title="Warning"
  966.                   description="Are you sure you want to cancel your changes?"
  967.                   appearance="warning"
  968.                   action="Continue"
  969.                 />
  970.               )}
  971.  
  972.               {action === "Remove an Event" ? (
  973.                 <>
  974.                   <Button
  975.                     type="text"
  976.                     label="Remove"
  977.                     size="lg"
  978.                     className="bg-elements-secondary-shadow hover:bg-elements-secondary-dimmed px-4 py-2 text-white"
  979.                     onClick={openRemoveModal}
  980.                     disabled={!isActionSelected}
  981.                   />
  982.                   {isRemoveModalOpen && (
  983.                     <Transition.Root
  984.                       show={isRemoveModalOpen}
  985.                       as={React.Fragment}
  986.                     >
  987.                       {/* <Dialog
  988.                           as="div"
  989.                           className="fixed inset-0 z-10 overflow-y-auto"
  990.                           onClose={closeRemoveModal}
  991.                         > */}
  992.                       <div className="fixed inset-0 z-10 overflow-y-auto flex items-center justify-center">
  993.                         <Transition.Child
  994.                           as={React.Fragment}
  995.                           enter="ease-out duration-300"
  996.                           enterFrom="opacity-0"
  997.                           enterTo="opacity-100"
  998.                           leave="ease-in duration-200"
  999.                           leaveFrom="opacity-100"
  1000.                           leaveTo="opacity-0"
  1001.                         >
  1002.                           <div className="fixed inset-0 transition-opacity">
  1003.                             <div className="absolute inset-0 bg-gray-500 opacity-75" />
  1004.                           </div>
  1005.                         </Transition.Child>
  1006.  
  1007.                         <Transition.Child
  1008.                           as={React.Fragment}
  1009.                           enter="ease-out duration-300"
  1010.                           enterFrom="opacity-0 scale-95"
  1011.                           enterTo="opacity-100 scale-100"
  1012.                           leave="ease-in duration-200"
  1013.                           leaveFrom="opacity-100 scale-100"
  1014.                           leaveTo="opacity-0 scale-95"
  1015.                         >
  1016.                           <div className="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transition-all transform rounded-lg shadow-xl bg-neutral-dimmed-heavy sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6">
  1017.                             <div className="absolute top-0 right-0 hidden pt-4 pr-4 sm:block">
  1018.                               <button
  1019.                                 type="button"
  1020.                                 className="rounded-md bg-neutral text-text-dimmed hover:text-text-tertiary focus:outline-none focus:ring-2 focus:ring-offset-2 focus:elements-primary-main"
  1021.                                 onClick={closeRemoveModal}
  1022.                               >
  1023.                                 <span className="sr-only">Close</span>
  1024.                                 <HiX className="w-6 h-6" aria-hidden="true" />
  1025.                               </button>
  1026.                             </div>
  1027.                             <div className="sm:flex sm:items-start">
  1028.                               <div className="bg-helpers-warning-dimmed mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full sm:mx-0 sm:h-10 sm:w-10">
  1029.                                 <HiOutlineExclamation
  1030.                                   className="text-helpers-warning-main w-6 h-6"
  1031.                                   aria-hidden="true"
  1032.                                 />
  1033.                               </div>
  1034.  
  1035.                               <div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
  1036.                                 <h3 className="text-lg font-medium leading-6 text-text-primary">
  1037.                                   Warning
  1038.                                 </h3>
  1039.                                 <div className="mt-2">
  1040.                                   <p className="text-sm text-text-tertiary">
  1041.                                     Are you sure you want to remove an event?
  1042.                                   </p>
  1043.                                 </div>
  1044.                               </div>
  1045.                             </div>
  1046.                             <div className="mt-5 sm:mt-4 flex sm:flex-row-reverse space-x-4">
  1047.                               <Button
  1048.                                 type="primary"
  1049.                                 size="md"
  1050.                                 label="Remove"
  1051.                                 className="ml-3 bg-helpers-warning-button hover:bg-helpers-warning-button-hover focus:ring-helpers-warning-button"
  1052.                                 disabled={!isActionSelected}
  1053.                                 buttonType="submit"
  1054.                               />
  1055.                               <button
  1056.                                 type="button"
  1057.                                 className="inline-flex justify-center w-full px-4 py-2 mt-3 text-base font-medium border rounded-md shadow-sm border-divider-main bg-neutral-dimmed-heavy hover:bg-neutral-dimmed text-text-secondary hover:text-text-tertiary focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-elements-primary-main sm:mt-0 sm:w-auto sm:text-sm"
  1058.                                 onClick={closeRemoveModal}
  1059.                               >
  1060.                                 Cancel
  1061.                               </button>
  1062.                             </div>
  1063.                           </div>
  1064.                         </Transition.Child>
  1065.                       </div>
  1066.                       {/* </Dialog> */}
  1067.                     </Transition.Root>
  1068.                   )}
  1069.                 </>
  1070.               ) : (
  1071.                 <Button
  1072.                   type="primary"
  1073.                   size="md"
  1074.                   label="Save"
  1075.                   className="bg-elements-secondary-shadow hover:bg-elements-secondary-dimmed"
  1076.                   disabled={!isActionSelected}
  1077.                   buttonType="submit"
  1078.                 />
  1079.               )}
  1080.             </div>
  1081.           </form>
  1082.         </div>
  1083.         <div
  1084.           className="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]"
  1085.           aria-hidden="true"
  1086.         >
  1087.           <div
  1088.             className="relative left-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#bfdbfe] to-[#2563eb] opacity-30 sm:left-[calc(50%+36rem)] sm:w-[72.1875rem]"
  1089.             style={{
  1090.               clipPath:
  1091.                 "polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)",
  1092.             }}
  1093.           />
  1094.         </div>
  1095.       </div>
  1096.     </Page>
  1097.   );
  1098. }
  1099.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement