From 3ddcfbb1bead1f9ea9df7761fe12f8d1a1b38f47 Mon Sep 17 00:00:00 2001 From: Harini312821 Date: Sun, 11 Aug 2024 22:45:36 +0800 Subject: [PATCH] edit events page --- client/src/pages/EditEventsPage.tsx | 128 +++++++++++++++++++------- client/src/pages/ManageEventsPage.tsx | 19 ++-- server/routes/events.js | 77 +++++++++++----- 3 files changed, 161 insertions(+), 63 deletions(-) diff --git a/client/src/pages/EditEventsPage.tsx b/client/src/pages/EditEventsPage.tsx index 7382be3..0d30993 100644 --- a/client/src/pages/EditEventsPage.tsx +++ b/client/src/pages/EditEventsPage.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import { useState, useEffect } from "react"; import { Button } from "@nextui-org/react"; import { Formik, Form } from "formik"; import * as Yup from "yup"; @@ -7,8 +7,10 @@ import { useNavigate, useParams } from "react-router-dom"; import NextUIFormikInput from "../components/NextUIFormikInput"; import NextUIFormikTextarea from "../components/NextUIFormikTextarea"; import config from "../config"; +import InsertImage from "../components/InsertImage"; import { ArrowUTurnLeftIcon } from "../icons"; +// Validation schema const validationSchema = Yup.object({ title: Yup.string() .trim() @@ -32,52 +34,94 @@ const validationSchema = Yup.object({ time: Yup.string().required("Time is required"), location: Yup.string().required("Location is required"), category: Yup.string().required("Category is required"), - slotsAvailable: Yup.number().integer().required("Slots Available is required"), - imageUrl: Yup.string().url("Invalid URL format").required("Image URL is required") + slotsAvailable: Yup.number() + .integer() + .required("Slots Available is required"), + evtPicture: Yup.mixed(), // Make this optional if not required }); const EditEventsPage = () => { + const [eventData, setEventData] = useState(null); + const [imageFile, setImageFile] = useState(null); // State to handle image file + const [townCouncils, setTownCouncils] = useState([]); + const { id } = useParams(); // Get event ID from URL const navigate = useNavigate(); - const { id } = useParams<{ id: string }>(); - const [initialValues, setInitialValues] = useState({ - title: "", - description: "", - date: "", - time: "", - location: "", - category: "", - slotsAvailable: "", - imageUrl: "" - }); useEffect(() => { const fetchEvent = async () => { try { - const response = await axios.get(`${config.serverAddress}/events/${id}`); - // Convert the date to the correct format for the input field - const event = response.data; - event.date = new Date(event.date).toISOString().split('T')[0]; - setInitialValues(event); + const res = await axios.get(`${config.serverAddress}/events/${id}`); + console.log("Fetched event data:", res.data); // Log the fetched data + setEventData(res.data); + + if (res.data.evtPicture) { + // Optionally handle existing image + setImageFile(null); // You might want to set this to the existing image URL if applicable + } } catch (error) { - console.error("Failed to fetch event data:", error); + console.error("Failed to fetch event:", error); + } + }; + + const fetchTownCouncils = async () => { + try { + const res = await axios.get(`${config.serverAddress}/users/town-councils-metadata`); + setTownCouncils(JSON.parse(res.data).townCouncils); + } catch (error) { + console.error("Failed to fetch town councils:", error); } }; fetchEvent(); + fetchTownCouncils(); }, [id]); + const initialValues = { + title: eventData?.title || "", + description: eventData?.description || "", + date: eventData?.date ? new Date(eventData.date).toLocaleDateString('en-CA') : "", // Convert date to YYYY-MM-DD format + time: eventData?.time || "", + location: eventData?.location || "", + category: eventData?.category || "", + slotsAvailable: eventData?.slotsAvailable || "", + evtPicture: null, // Initialize with null or handle separately + }; + const handleSubmit = async ( values: any, { setSubmitting, resetForm, setFieldError }: any ) => { - console.log("Submitting form with values:", values); // Debug log + + console.log("From data:", values) + const formData = new FormData(); + formData.append("title", values.title); + formData.append("description", values.description); + formData.append("date", values.date); + formData.append("time", values.time); + formData.append("location", values.location); + formData.append("category", values.category); + formData.append("slotsAvailable", values.slotsAvailable); + + if (imageFile) { + formData.append("evtPicture", imageFile); // Append image file to form data + } + try { - const response = await axios.put(`${config.serverAddress}/events/${id}`, values); + const response = await axios.put( + `${config.serverAddress}/events/${id}`, + formData, + { + headers: { + "Content-Type": "multipart/form-data", + }, + } + ); console.log("Server response:", response); // Debug log if (response.status === 200 || response.status === 201) { console.log("Event updated successfully:", response.data); resetForm(); // Clear form after successful submit - navigate("/events"); + setImageFile(null); // Reset image file state + navigate("/admin/events"); } else { console.error("Error updating event:", response.statusText); } @@ -109,9 +153,9 @@ const EditEventsPage = () => { initialValues={initialValues} validationSchema={validationSchema} onSubmit={handleSubmit} - enableReinitialize + enableReinitialize={true} // Ensure form updates with new data > - {({ isValid, dirty, isSubmitting }) => ( + {({ isValid, dirty, isSubmitting, setFieldValue }) => (
{ placeholder="Enter event time" labelPlacement="inside" /> - +
+ + +
{ placeholder="Enter slots available" labelPlacement="inside" /> +
+ { + setImageFile(file); // Set image file + setFieldValue("evtPicture", file); // Set form field value + }} + // Optionally handle displaying current image + /> +
diff --git a/client/src/pages/ManageEventsPage.tsx b/client/src/pages/ManageEventsPage.tsx index 6ff16da..d7a6d9d 100644 --- a/client/src/pages/ManageEventsPage.tsx +++ b/client/src/pages/ManageEventsPage.tsx @@ -24,16 +24,16 @@ const ManageEventsPage = () => { const [selectedEventId, setSelectedEventId] = useState(null); const navigate = useNavigate(); - const fetchEvents = async () => { - try { - const res = await axios.get(config.serverAddress + "/events"); - setEvents(res.data); - } catch (error) { - console.error("Failed to fetch events:", error); - } - }; - useEffect(() => { + const fetchEvents = async () => { + try { + const res = await axios.get(config.serverAddress + "/events"); + setEvents(res.data); + } catch (error) { + console.error("Failed to fetch events:", error); + } + }; + fetchEvents(); }, []); @@ -162,6 +162,7 @@ const ManageEventsPage = () => {