diff --git a/src/components/Events/ArchiveEventsModal.jsx b/src/components/Events/ArchiveEventsModal.jsx deleted file mode 100644 index c1e91a3..0000000 --- a/src/components/Events/ArchiveEventsModal.jsx +++ /dev/null @@ -1,50 +0,0 @@ -import { - Button, - ListItem, - Modal, - ModalBody, - ModalCloseButton, - ModalContent, - ModalFooter, - ModalHeader, - ModalOverlay, - UnorderedList, -} from '@chakra-ui/react'; -import PropTypes from 'prop-types'; - -const ArchiveEventsModal = ({ isOpen, onClose, events, confirmArchive }) => { - return ( - <> - - - - Confirm event archive - - - Are you sure you want to archive these events? This action cannot be undone. - - {events.map(event => { - return {event.name}; - })} - - - - - - - - - - ); -}; - -ArchiveEventsModal.propTypes = { - isOpen: PropTypes.bool.isRequired, - onClose: PropTypes.func.isRequired, - confirmArchive: PropTypes.func.isRequired, - events: PropTypes.array.isRequired, -}; - -export default ArchiveEventsModal; diff --git a/src/components/Events/DeleteEventsModal.jsx b/src/components/Events/DeleteEventsModal.jsx new file mode 100644 index 0000000..9337e9a --- /dev/null +++ b/src/components/Events/DeleteEventsModal.jsx @@ -0,0 +1,54 @@ +import { + Button, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalOverlay, +} from '@chakra-ui/react'; +import PropTypes from 'prop-types'; + +const DeleteEventsModal = ({ isOpen, onClose, events, confirmDelete }) => { + // Function to format event names separated by commas, except the last one + const formattedEventNames = events.map(event => event.name).join(', '); + + // Determine the correct event label based on the number of events + const eventLabel = events.length > 1 ? 'Events' : 'Event'; + + return ( + + + + + + Are you sure you want to delete: {formattedEventNames} {eventLabel}? + + + + + + + + + ); +}; + +DeleteEventsModal.propTypes = { + isOpen: PropTypes.bool.isRequired, + onClose: PropTypes.func.isRequired, + confirmDelete: PropTypes.func.isRequired, + events: PropTypes.array.isRequired, +}; + +export default DeleteEventsModal; diff --git a/src/components/Navbar/Navbar.jsx b/src/components/Navbar/Navbar.jsx index c5ae416..125e88c 100644 --- a/src/components/Navbar/Navbar.jsx +++ b/src/components/Navbar/Navbar.jsx @@ -39,6 +39,7 @@ const NavbarButton = ({ buttonText, path, navigate, UnfocusedIcon, FocusedIcon } marginBottom="6px" backgroundColor={location.pathname === path ? '#D4E4F9' : 'transparent'} borderRadius="4px" + cursor="pointer" onClick={e => { e.preventDefault(); navigate(path); @@ -110,7 +111,7 @@ const Navbar = () => { alignItems="start" > {/* Box containing everything above "support" */} - + {/* Box containing the logo and role title at the top */} { + const toast = useToast(); + const { onNavbarDrawerOpen } = useContext(NavbarContext); const [events, setEvents] = useState([]); const [displayEvents, setDisplayEvents] = useState([]); - + const [showSelect, setShowSelect] = useState(false); + const [isSelectButton, setIsSelectButton] = useState(true); + const [isCreateButton, setIsCreateButton] = useState(true); // toggle between create event button and deselect button const [selectedEvents, setSelectedEvents] = useState([]); const [name, setName] = useState(''); const [dates, setDates] = useState([]); @@ -34,7 +47,7 @@ const Events = () => { const getEvents = async () => { try { - const eventsData = await Backend.get('/events'); + const eventsData = await Backend.get('/events/currentEvents'); setEvents(eventsData.data); console.log(eventsData.data); // setDates(); @@ -47,24 +60,32 @@ const Events = () => { } }; - const getLocation = data => { - let location = []; - for (let i in data) { - location.push(data[i].location); - } - console.log(location.length); - return location; - }; + const { + isOpen: isDeleteEventModalOpen, + onOpen: onDeleteEventModalOpen, + onClose: onDeleteEventModalClose, + } = useDisclosure(); - const getDate = data => { - let date = []; - for (let i in data) { - date.push(data[i].date.substring(0, 10)); + const confirmDelete = async () => { + for (const id of selectedEvents) { + try { + await Backend.delete(`/events/${id}`); + getEvents(); + } catch (error) { + console.log(`Error archiving event: ${id}`, error.message); + } } - console.log(date.length); - return date; + onDeleteEventModalClose(); + handleGoBackButton(); + toast({ + title: `Successfully deleted ${selectedEvents.length} event(s)`, + status: 'success', + duration: 3000, + isClosable: true, + }); }; + const handleCheckboxChange = id => { const newCheckedItems = [...selectedEvents]; const index = newCheckedItems.indexOf(id); @@ -79,12 +100,30 @@ const Events = () => { console.log(selectedEvents); }; + const getLocation = data => { + let location = []; + for (let i in data) { + location.push(data[i].location); + } + console.log(location.length); + return location; + }; + + const getDate = data => { + let date = []; + for (let i in data) { + date.push(data[i].date.substring(0, 10)); + } + console.log(date.length); + return date; + }; + const eventCards = displayEvents.map(element => ( @@ -125,6 +164,74 @@ const Events = () => { )); }; + const deleteEvents = () => { + if (selectedEvents.length > 0) { + onDeleteEventModalOpen(); + } + }; + + const handleSelectButton = () => { + setShowSelect(true); + setIsSelectButton(false); + setIsCreateButton(false); + }; + + const handleGoBackButton = () => { + setShowSelect(false); + setIsCreateButton(true); + setIsSelectButton(true); + setSelectedEvents([]); + }; + + const SelectButton = () => { + return ( + <> + + + ); + }; + + const DeleteButton = ({ id }) => { + return ( + <> + + + ); + }; + + DeleteButton.propTypes = { + id: PropTypes.number, + }; + + const CancelButton = () => { + return ( + <> + + + ); + }; + useEffect(() => { if (!fuse) { return; @@ -161,12 +268,10 @@ const Events = () => { width="95%" height="237px" padding="32px" - flex-direction="column" - align-items="center" + flexDirection="column" + alignItems="center" gap="24px" - flex-shrink="0" borderRadius={'xl'} - flexDir={'column'} > { - - + + @@ -193,7 +298,7 @@ const Events = () => { placeholder='Search Event Name (e.g. "Festival of Whales")' /> - + @@ -202,7 +307,6 @@ const Events = () => { icon={} onChange={handleDateChange} placeholder="Select Date" - gap={'5px'} w="20%" > {getDateOptions()} @@ -212,19 +316,91 @@ const Events = () => { - - - - - - - {eventCards} - + + + + Upcoming Events + + {isCreateButton } + + + + + + { + setName(event.target.value); + }} + placeholder='Search Event Name (e.g. "Festival of Whales")' + /> + + + + + + { + setLocation(event.target.value); + }} + placeholder="Search Location" + /> + + + + + + { + setDate(event.target.value); + }} + /> + + + - - + + + + {isSelectButton ? : } + + +{!isSelectButton && ( + + + + +)} + selectedEvents.includes(event.id))} +/> + + + + + + + {eventCards} + + + + + + ); + }; export default Events; diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx index 07572d5..6ca9b5f 100644 --- a/src/pages/HomePage.jsx +++ b/src/pages/HomePage.jsx @@ -1,12 +1,9 @@ import { Box, - Button, Grid, GridItem, Spacer, HStack, - useDisclosure, - useToast, Input, InputGroup, InputLeftElement, @@ -16,8 +13,6 @@ import { import { useEffect, useState, useContext } from 'react'; import { SearchIcon, HamburgerIcon } from '@chakra-ui/icons'; -import PropTypes from 'prop-types'; -import ArchiveEventsModal from '../components/Events/ArchiveEventsModal'; import EventCard from '../components/Events/EventCard'; import ImpactSummary from '../components/Events/ImpactSummary'; import Backend from '../utils/utils'; @@ -25,12 +20,9 @@ import Fuse from 'fuse.js'; import NavbarContext from '../utils/NavbarContext'; const Home = () => { - const toast = useToast(); const [events, setEvents] = useState([]); const [displayEvents, setDisplayEvents] = useState([]); - const [showSelect, setShowSelect] = useState(false); - const [isSelectButton, setIsSelectButton] = useState(true); - const [isCreateButton, setIsCreateButton] = useState(true); // toggle between create event button and deselect button + const [showSelect] = useState(false); const [selectedEvents, setSelectedEvents] = useState([]); const [name, setName] = useState(''); const [date, setDate] = useState(''); @@ -50,36 +42,6 @@ const Home = () => { } }; - const { - isOpen: isArchiveEventModalOpen, - onOpen: onArchiveEventModalOpen, - onClose: onArchiveEventModalClose, - } = useDisclosure(); - - const confirmArchive = async () => { - for (const id of selectedEvents) { - try { - await Backend.put(`/events/archive/${id}`); - getEvents(); - } catch (error) { - console.log(`Error archiving event: ${id}`, error.message); - } - } - onArchiveEventModalClose(); - handleGoBackButton(); - toast({ - title: `Successfully archived ${selectedEvents.length} event(s)`, - status: 'success', - duration: 3000, - isClosable: true, - }); - }; - - const archiveEvents = () => { - if (selectedEvents.length === 0) handleGoBackButton(); - else onArchiveEventModalOpen(); - }; - const handleCheckboxChange = id => { const newCheckedItems = [...selectedEvents]; const index = newCheckedItems.indexOf(id); @@ -112,67 +74,9 @@ const Home = () => { // getEventId(eventId); }, []); - const handleSelectButton = () => { - setShowSelect(true); - setIsSelectButton(false); - setIsCreateButton(false); - }; - const handleGoBackButton = () => { - setShowSelect(false); - setIsCreateButton(true); - setIsSelectButton(true); - setSelectedEvents([]); - }; - const SelectButton = () => { - return ( - <> - - - ); - }; - - const ArchiveButton = ({ id }) => { - return ( - <> - - - ); - }; - ArchiveButton.propTypes = { - id: PropTypes.number, - }; - - const DeselectButton = () => { - return ( - <> - - - ); - }; useEffect(() => { if (!fuse) { @@ -225,7 +129,7 @@ const Home = () => { Upcoming Events - {isCreateButton ? <> : } + @@ -268,13 +172,7 @@ const Home = () => { - {isSelectButton ? : } - selectedEvents.includes(event.id))} - /> +