From fb155c993496b42ce9a5ea8d051e3367497328c7 Mon Sep 17 00:00:00 2001 From: jennymar Date: Sun, 30 Jun 2024 15:53:13 -0700 Subject: [PATCH] timestamp records complete --- backend/src/controllers/eventDetails.ts | 2 + backend/src/controllers/records.ts | 11 ++++ frontend/src/app/admin/dashboard/page.tsx | 36 +++++++++-- .../src/app/admin/newsletter-creator/page.tsx | 9 +++ frontend/src/app/admin/page-editor/page.tsx | 6 +- frontend/src/components/ContactForm.tsx | 11 ++-- frontend/src/components/EventSidebar.tsx | 9 ++- frontend/src/components/Footer.tsx | 2 + frontend/src/components/NewsletterForm.tsx | 3 + .../components/NewsletterSidebar.module.css | 1 + frontend/src/components/NewsletterSidebar.tsx | 63 ++++++++++++++----- 11 files changed, 119 insertions(+), 34 deletions(-) diff --git a/backend/src/controllers/eventDetails.ts b/backend/src/controllers/eventDetails.ts index f21e57b6..7280b995 100644 --- a/backend/src/controllers/eventDetails.ts +++ b/backend/src/controllers/eventDetails.ts @@ -47,6 +47,8 @@ export const createEventDetails: RequestHandler = async (req, res, next) => { description_short, } = req.body; + console.log("events date: ", date); + try { validationErrorParser(errors); diff --git a/backend/src/controllers/records.ts b/backend/src/controllers/records.ts index 84b2b837..ebca8695 100644 --- a/backend/src/controllers/records.ts +++ b/backend/src/controllers/records.ts @@ -19,6 +19,7 @@ export const updateRecord: RequestHandler = async (req, res, next) => { const { card } = req.params; try { + console.log("req.body: ", req.body); const record = await RecordModel.findOneAndUpdate({ card: card }, req.body); if (record === null) { @@ -29,6 +30,16 @@ export const updateRecord: RequestHandler = async (req, res, next) => { res.status(404); } + if (card === "home" || card === "about" || card === "involved" || card === "impact") { + const pageRecord = await RecordModel.findOneAndUpdate( + { card: "page-editor" }, + { date: req.body.date }, + ); + if (pageRecord === null) { + res.status(404); + } + } + res.status(200).json(updatedRecord); } catch (error) { next(error); diff --git a/frontend/src/app/admin/dashboard/page.tsx b/frontend/src/app/admin/dashboard/page.tsx index dd2be1cd..7f887f2f 100644 --- a/frontend/src/app/admin/dashboard/page.tsx +++ b/frontend/src/app/admin/dashboard/page.tsx @@ -1,10 +1,38 @@ "use client"; +import { useEffect, useState } from "react"; import styles from "./page.module.css"; import DashboardCard from "@/components/DashboardCard"; +import { getRecord } from "@/api/records"; export default function Dashboard() { + const [lastUpdated, setLastUpdated] = useState>({}); + + useEffect(() => { + const cards = ["event-creator", "page-editor", "mailing-list", "newsletter-creator"]; + for (const card of cards) { + try { + getRecord(card) + .then((record) => { + if (record.success) { + setLastUpdated((prevLastUpdated) => ({ + ...prevLastUpdated, + [card]: record.data.date, + })); + } else { + alert(record.error); + } + }) + .catch((error) => { + alert(error); + }); + } catch (error) { + console.error(`Error fetching last updated date for ${card}:`, error); + } + } + }, []); + return (
@@ -12,25 +40,25 @@ export default function Dashboard() { imageURI="/dashboard_eventcreator.png" url="/event-creator" title="Event Creator" - last_updated="Month XX, XXXX, XX:XX" + last_updated={lastUpdated["event-creator"] ?? ""} />
diff --git a/frontend/src/app/admin/newsletter-creator/page.tsx b/frontend/src/app/admin/newsletter-creator/page.tsx index 8207df18..a50e10c7 100644 --- a/frontend/src/app/admin/newsletter-creator/page.tsx +++ b/frontend/src/app/admin/newsletter-creator/page.tsx @@ -58,6 +58,15 @@ export default function NewsletterCreator() { cellClassName: `${styles.cellEntry} ${styles.cellBorderStyle}`, disableColumnMenu: true, renderHeader: () =>
Date
, + renderCell: (params) => { + const { date } = params.row; + const formattedDate = new Date(date).toLocaleDateString("en-US", { + year: "numeric", + month: "long", + day: "numeric", + }); + return formattedDate; + }, }, ]; diff --git a/frontend/src/app/admin/page-editor/page.tsx b/frontend/src/app/admin/page-editor/page.tsx index 900ae016..dd7891fc 100644 --- a/frontend/src/app/admin/page-editor/page.tsx +++ b/frontend/src/app/admin/page-editor/page.tsx @@ -11,9 +11,7 @@ export default function PageEditorDashboard() { const [lastUpdated, setLastUpdated] = useState>({}); useEffect(() => { - // Function to fetch last updated date for each card - - const cards = ["home", "about", "involved", "impact"]; // Assuming these are the card names + const cards = ["home", "about", "involved", "impact"]; for (const card of cards) { try { getRecord(card) @@ -21,7 +19,7 @@ export default function PageEditorDashboard() { if (record.success) { setLastUpdated((prevLastUpdated) => ({ ...prevLastUpdated, - [card]: record.data.date, // Assuming the date is stored in the 'date' field + [card]: record.data.date, })); } else { alert(record.error); diff --git a/frontend/src/components/ContactForm.tsx b/frontend/src/components/ContactForm.tsx index 1386b3db..2dffea44 100644 --- a/frontend/src/components/ContactForm.tsx +++ b/frontend/src/components/ContactForm.tsx @@ -99,13 +99,10 @@ const ContactForm: React.FC = () => { subject, message, question: questionType, - }).then( - () => {}, - (error) => { - // If the .then() request fails, show the error message - alert(error); - }, - ); + }).then((error) => { + // If the .then() request fails, show the error message + alert(error); + }); }; return ( diff --git a/frontend/src/components/EventSidebar.tsx b/frontend/src/components/EventSidebar.tsx index e1030e88..915ad3f9 100644 --- a/frontend/src/components/EventSidebar.tsx +++ b/frontend/src/components/EventSidebar.tsx @@ -10,12 +10,13 @@ import styles from "./EventSidebar.module.css"; import { TextArea } from "./TextArea"; import { TextAreaCharLimit } from "./TextAreaCharLimit"; import { TextFieldCharLimit } from "./TextFieldCharLimit"; +import SimpleImageDropzone from "./admin/storage/SimpleImageDropzone"; +import { deleteFile } from "@/app/admin/util/pageeditUtil"; import AlertBanner from "@/components/AlertBanner"; import { TextField } from "@/components/TextField"; import { WarningModule } from "@/components/WarningModule"; -import SimpleImageDropzone from "./admin/storage/SimpleImageDropzone"; -import { deleteFile } from "@/app/admin/util/pageeditUtil"; +import { updateRecord } from "@/api/records"; const EVENT_TITLE_CHAR_LIMIT = 35; const EVENT_DESCRIPTION_SHORT_CHAR_LIMIT = 200; @@ -143,6 +144,7 @@ const EventSidebar = ({ }); } + updateRecord("event-creator").catch(console.error); setIsEditing(false); setErrors({}); setShowAlert(true); @@ -159,6 +161,7 @@ const EventSidebar = ({ ...eventDetails, imageURI: "", }); + updateRecord("event-creator").catch(console.error); } }; @@ -170,6 +173,7 @@ const EventSidebar = ({ ...eventDetails, imageURI: url, }); + updateRecord("event-creator").catch(console.error); } }; @@ -181,6 +185,7 @@ const EventSidebar = ({ deleteEventDetails(eventDetails._id) .then((result) => { if (result.success) { + updateRecord("event-creator").catch(console.error); } else { console.error("ERROR:", result.error); } diff --git a/frontend/src/components/Footer.tsx b/frontend/src/components/Footer.tsx index a8d748ab..650395af 100644 --- a/frontend/src/components/Footer.tsx +++ b/frontend/src/components/Footer.tsx @@ -7,6 +7,7 @@ import React, { useState } from "react"; import { createSubscriber } from "../api/subscriber"; import styles from "./Footer.module.css"; +import { updateRecord } from "@/api/records"; const Footer = () => { const [email, setEmail] = useState(""); @@ -48,6 +49,7 @@ const Footer = () => { createSubscriber({ email }).then( (result) => { if (result.success) { + updateRecord("mailing-list").catch(console.error); setSubmitted(true); // show the success message setPlaceholder("Thanks for subscribing!"); setEmail(""); // clear the email input diff --git a/frontend/src/components/NewsletterForm.tsx b/frontend/src/components/NewsletterForm.tsx index 0adf6ed2..1ada6320 100644 --- a/frontend/src/components/NewsletterForm.tsx +++ b/frontend/src/components/NewsletterForm.tsx @@ -5,6 +5,7 @@ import { sendEmail } from "../api/email"; import { createSubscriber } from "../api/subscriber"; import styles from "./NewsletterForm.module.css"; +import { updateRecord } from "@/api/records"; type NewsLetterFormProps = { setSuccess: (success: boolean) => void; @@ -87,6 +88,8 @@ const NewsletterForm: React.FC = ({ alert(error); }, ); + + updateRecord("mailing-list").catch(console.error); setSuccess(true); } else { setSuccess(false); diff --git a/frontend/src/components/NewsletterSidebar.module.css b/frontend/src/components/NewsletterSidebar.module.css index fcce8f7d..277d44b4 100644 --- a/frontend/src/components/NewsletterSidebar.module.css +++ b/frontend/src/components/NewsletterSidebar.module.css @@ -132,6 +132,7 @@ gap: 24px; justify-content: flex-end; width: 33vw; + margin-bottom: 77px; } .deleteButtonWrapper { diff --git a/frontend/src/components/NewsletterSidebar.tsx b/frontend/src/components/NewsletterSidebar.tsx index 847d97da..8d6dda56 100644 --- a/frontend/src/components/NewsletterSidebar.tsx +++ b/frontend/src/components/NewsletterSidebar.tsx @@ -1,19 +1,22 @@ "use client"; import Image from "next/image"; import React, { useState } from "react"; +import DatePicker from "react-datepicker"; +import "react-datepicker/dist/react-datepicker.css"; import { CreateNewsletterRequest, Newsletter, deleteNewsletter } from "../api/newsletter"; import AlertBanner from "./AlertBanner"; import styles from "./NewsletterSidebar.module.css"; import { TextArea } from "./TextArea"; +import { TextAreaCharLimit } from "./TextAreaCharLimit"; import { TextField } from "./TextField"; +import { TextFieldCharLimit } from "./TextFieldCharLimit"; import { WarningModule } from "./WarningModule"; import SimpleImageDropzone from "./admin/storage/SimpleImageDropzone"; import { deleteFile } from "@/app/admin/util/pageeditUtil"; -import { TextFieldCharLimit } from "./TextFieldCharLimit"; -import { TextAreaCharLimit } from "./TextAreaCharLimit"; +import { updateRecord } from "@/api/records"; const NEWSLETTER_TITLE_CHAR_LIMIT = 35; const NEWSLETTER_DESCRIPTION_CHAR_LIMIT = 200; @@ -41,7 +44,7 @@ const NewsletterSidebar = ({ }: newsletterSidebarProps) => { const [title, setTitle] = useState(newsletter ? newsletter.title : ""); const [description, setDescription] = useState(newsletter ? newsletter.description : ""); - const [date, setDate] = useState(newsletter ? newsletter.date : ""); + const [date, setDate] = useState(newsletter ? new Date(newsletter.date) : new Date()); const [image, setImage] = useState(newsletter ? newsletter.image : ""); const [content, setContent] = useState(newsletter ? newsletter.content : ""); const [isEditing, setIsEditing] = useState(!newsletter); @@ -52,7 +55,7 @@ const NewsletterSidebar = ({ const confirmCancel = () => { setTitle(newsletter ? newsletter.title : ""); setDescription(newsletter ? newsletter.description : ""); - setDate(newsletter ? newsletter.date : ""); + setDate(newsletter ? new Date(newsletter.date) : new Date()); setImage(newsletter ? newsletter.image : ""); setContent(newsletter ? newsletter.content : ""); setIsEditing(false); @@ -84,7 +87,7 @@ const NewsletterSidebar = ({ _id: newsletter._id, title, description, - date, + date: date.toISOString(), image, content, }); @@ -92,11 +95,13 @@ const NewsletterSidebar = ({ await createNewsletter({ title, description, - date, + date: date.toISOString(), image, content, }); } + + updateRecord("newsletter-creator").catch(console.error); setIsEditing(false); setErrors({}); setShowAlert(true); @@ -113,6 +118,7 @@ const NewsletterSidebar = ({ ...newsletter, image: "", }); + updateRecord("newsletter-creator").catch(console.error); } }; @@ -124,6 +130,7 @@ const NewsletterSidebar = ({ ...newsletter, image: url, }); + updateRecord("newsletter-creator").catch(console.error); } }; @@ -135,6 +142,7 @@ const NewsletterSidebar = ({ deleteNewsletter(newsletter._id) .then((result) => { if (result.success) { + updateRecord("newsletter-creator").catch(console.error); } else { console.error("ERROR:", result.error); } @@ -190,7 +198,9 @@ const NewsletterSidebar = ({

Newsletter Description

{description}

Date & Time

-

{date}

+

+ {date.toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" })} +

Newsletter Cover

- ) => { - setDate(event.target.value); - }} - error={errors.date} - /> +
+ { + setDate(dateObj); + }} + dateFormat="MMMM d, yyyy" + customInput={ + + } + /> + {errors.date &&

Date is required

} +

Newsletter Cover

Newsletter Description

{description}

Date & Time

-

{date}

+

+ {date.toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" })} +

Newsletter Cover