From ed3f29af861026f4f8eebb9f8f40477b220f10af Mon Sep 17 00:00:00 2001 From: ArkadiK94 Date: Fri, 12 Apr 2024 22:32:15 +0300 Subject: [PATCH 1/3] feat: sort sub events --- src/components/CommunityEvents/ModifyTimeline.jsx | 12 ++++++++---- .../CommunityEvents/TimelineListItemDisplay.jsx | 5 ++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/components/CommunityEvents/ModifyTimeline.jsx b/src/components/CommunityEvents/ModifyTimeline.jsx index 7f6ba413..6e93f3f5 100644 --- a/src/components/CommunityEvents/ModifyTimeline.jsx +++ b/src/components/CommunityEvents/ModifyTimeline.jsx @@ -92,6 +92,7 @@ const ModifyTimeline = ({ onModify, onCloseChangeMode, modifyEvent, eventManageT } return validationError; }); + if ( new Date(modifyEvent.startTime) > new Date(valueObj.startTime) || new Date(modifyEvent.endTime) < new Date(valueObj.endTime) || @@ -102,7 +103,6 @@ const ModifyTimeline = ({ onModify, onCloseChangeMode, modifyEvent, eventManageT } return validationError; }); - if (validationError || timeValidationError) { if (validationError) return toast.error("Some of the input fields are empty, fill all the fields and try again"); @@ -111,13 +111,17 @@ const ModifyTimeline = ({ onModify, onCloseChangeMode, modifyEvent, eventManageT toast.error( `In addition, the sub-event needs to be during the event time. from: ${format( new Date(modifyEvent.startTime), - "EEEE hh:m a", - )}, to: ${format(new Date(modifyEvent.endTime), "EEEE hh:m a")}`, + "EEEE hh:mm a", + )}, to: ${format(new Date(modifyEvent.endTime), "EEEE hh:mm a")}`, ); return; } } - const timelineArray = convertFromObjToArray(timeLineListItems); + const timelineArray = convertFromObjToArray(timeLineListItems).sort((itemA, itemB) => { + const firstStart = new Date(itemA.startTime) - new Date(itemB.startTime); + if (firstStart) return firstStart; + return new Date(itemA.endTime) - new Date(itemB.endTime); + }); onModify({ ...modifyEvent, timeline: timelineArray }, eventManageTimelineId); onCloseChangeMode(); }; diff --git a/src/components/CommunityEvents/TimelineListItemDisplay.jsx b/src/components/CommunityEvents/TimelineListItemDisplay.jsx index 61f6b274..2260807b 100644 --- a/src/components/CommunityEvents/TimelineListItemDisplay.jsx +++ b/src/components/CommunityEvents/TimelineListItemDisplay.jsx @@ -45,8 +45,7 @@ const TimelineListItemDisplay = ({ timeLineListItemObj, setTimelineListItems, ra return { ...prevTimeline, [updateTimelineItem.id]: { ...updateTimelineItem } }; }); }; - const dateFieldType = - new Date(rangeDate.to).getDate() - new Date(rangeDate.from).getDate() > 0 ? "pick date" : "show date"; + const dateFieldType = rangeDate.to - rangeDate.from > 0 ? "pick date" : "show date"; const handleSelectTopic = (topic) => { setSelectedTopic(topic); @@ -68,7 +67,7 @@ const TimelineListItemDisplay = ({ timeLineListItemObj, setTimelineListItems, ra From 7b5079b26a6bb206d2656130615f7735da1973fa Mon Sep 17 00:00:00 2001 From: ArkadiK94 Date: Fri, 12 Apr 2024 22:33:04 +0300 Subject: [PATCH 2/3] fix: update eslint-plugin-no-relative-import-paths package --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index c8e60cf2..31eed4de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -61,7 +61,7 @@ "eslint-config-standard": "^17.0.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-n": "^15.3.0", - "eslint-plugin-no-relative-import-paths": "^1.5.3", + "eslint-plugin-no-relative-import-paths": "^1.5.4", "eslint-plugin-promise": "^6.1.1", "eslint-plugin-react": "^7.31.10", "gh-pages": "^4.0.0", @@ -3422,9 +3422,9 @@ } }, "node_modules/eslint-plugin-no-relative-import-paths": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-relative-import-paths/-/eslint-plugin-no-relative-import-paths-1.5.3.tgz", - "integrity": "sha512-z7c7Km1U0zdLyPziWeRKSsN2mPaGaBHDjfXn98B8XjRIhFi2bPqduRYcxWih1kI5al5tQtiChXVmspLkB0wNsQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-relative-import-paths/-/eslint-plugin-no-relative-import-paths-1.5.4.tgz", + "integrity": "sha512-2smViH7R3682NR6dwgYr8Vm7emqNP1gEjBku6DbvUy3Ef/2Fz+mhwsFjZGSixzWzazMCj4MAgIWTsHELCCDJKA==", "dev": true }, "node_modules/eslint-plugin-promise": { diff --git a/package.json b/package.json index fb8ccc3b..f870598e 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "eslint-config-standard": "^17.0.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-n": "^15.3.0", - "eslint-plugin-no-relative-import-paths": "^1.5.3", + "eslint-plugin-no-relative-import-paths": "^1.5.4", "eslint-plugin-promise": "^6.1.1", "eslint-plugin-react": "^7.31.10", "gh-pages": "^4.0.0", From 261ef9471f67d3f71b3ebb48af90d3cbb5e88bbc Mon Sep 17 00:00:00 2001 From: ArkadiK94 Date: Sun, 14 Apr 2024 20:12:49 +0300 Subject: [PATCH 3/3] feat: add filter to events "All,Join,Joined,Full" why: so users could navigate to relavant events how: make SidebarFilterButtons common component --- src/components/Blogs/Blogs.jsx | 2 +- .../SocialSidebar/Sidebar.jsx | 0 .../Common/SocialSidebar/SidebarElements.jsx | 39 ++++++++++ .../SocialSidebar/SidebarFilterButton.jsx | 11 +++ .../SocialSidebar/SidebarFilterButtons.jsx | 25 ++++++ src/components/Common/SocialSidebar/index.js | 5 ++ .../CommunityEvents/CommunityEvents.jsx | 77 ++++++++++++++++++- .../CommunityEventsElement.jsx | 12 +++ .../CommunityEvents/EventItemList.jsx | 6 +- src/components/Explore/Explore.jsx | 2 +- src/components/Feeds/Feeds.jsx | 2 +- .../Feeds/SocialSidebar/SidebarElements.jsx | 18 ----- 12 files changed, 174 insertions(+), 25 deletions(-) rename src/components/{Feeds => Common}/SocialSidebar/Sidebar.jsx (100%) create mode 100644 src/components/Common/SocialSidebar/SidebarElements.jsx create mode 100644 src/components/Common/SocialSidebar/SidebarFilterButton.jsx create mode 100644 src/components/Common/SocialSidebar/SidebarFilterButtons.jsx create mode 100644 src/components/Common/SocialSidebar/index.js delete mode 100644 src/components/Feeds/SocialSidebar/SidebarElements.jsx diff --git a/src/components/Blogs/Blogs.jsx b/src/components/Blogs/Blogs.jsx index c6232e3b..08f8705c 100644 --- a/src/components/Blogs/Blogs.jsx +++ b/src/components/Blogs/Blogs.jsx @@ -9,7 +9,7 @@ import apiStatus from "src/features/apiStatus"; import BlogCards from "src/components/Blogs/BlogCard/BlogCards"; import { getAllUserDetails, userDetailReset } from "src/features/userDetail/userDetailSlice"; import { getFollowData, reset } from "src/features/follow/followSlice"; -import Sidebar from "src/components/Feeds/SocialSidebar/Sidebar"; +import Sidebar from "src/components/Common/SocialSidebar/Sidebar"; const Blogs = () => { const dispatch = useDispatch(); diff --git a/src/components/Feeds/SocialSidebar/Sidebar.jsx b/src/components/Common/SocialSidebar/Sidebar.jsx similarity index 100% rename from src/components/Feeds/SocialSidebar/Sidebar.jsx rename to src/components/Common/SocialSidebar/Sidebar.jsx diff --git a/src/components/Common/SocialSidebar/SidebarElements.jsx b/src/components/Common/SocialSidebar/SidebarElements.jsx new file mode 100644 index 00000000..e2b555a9 --- /dev/null +++ b/src/components/Common/SocialSidebar/SidebarElements.jsx @@ -0,0 +1,39 @@ +import styled from "styled-components"; + +export const SidebarContainer = styled.div` + position: sticky; + display: flex; + flex-direction: column; + justify-content: flex-start; + gap: 10px; + top: 100px; + + width: 100%; + max-width: 400px; + min-width: ${(props) => (props.sidebarType === "explore" ? "300px" : "400px")}; + + color: #ffffff; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + border-radius: 10px; +`; + +export const FilterButton = styled.button` + font-size: 15px; + width: 100%; + gap: 10px; + font-weight: 600; + padding: 5px 10px; + background-color: ${({ activeButton }) => (activeButton ? "#ff6b08" : "")}; + color: ${({ activeButton }) => (activeButton ? "#0a0a0a" : "")}; + height: 6vh; + padding: 0 20px; + &:first-child { + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + } + + &:last-child { + border-top-right-radius: 7px; + border-bottom-right-radius: 7px; + } +`; diff --git a/src/components/Common/SocialSidebar/SidebarFilterButton.jsx b/src/components/Common/SocialSidebar/SidebarFilterButton.jsx new file mode 100644 index 00000000..254f4e80 --- /dev/null +++ b/src/components/Common/SocialSidebar/SidebarFilterButton.jsx @@ -0,0 +1,11 @@ +import React from "react"; +import { FilterButton } from "./SidebarElements"; + +const SidebarFilterButton = ({ filterLabel, onClick, activeButton, id }) => { + return ( + onClick(id)}> + {filterLabel} + + ); +}; +export default SidebarFilterButton; diff --git a/src/components/Common/SocialSidebar/SidebarFilterButtons.jsx b/src/components/Common/SocialSidebar/SidebarFilterButtons.jsx new file mode 100644 index 00000000..e43230c5 --- /dev/null +++ b/src/components/Common/SocialSidebar/SidebarFilterButtons.jsx @@ -0,0 +1,25 @@ +import React, { useState } from "react"; +import SidebarFilterButton from "./SidebarFilterButton"; + +const SidebarFilterButtons = ({ filterButtonsData, defaultButtonId = "" }) => { + const [activeButton, setActiveButton] = useState(defaultButtonId); + + const renderButtons = filterButtonsData.map(({ filterLabel, onClick, id }) => { + const handleClick = (filterId) => { + setActiveButton(filterId); + onClick(filterLabel); + }; + + return ( + + ); + }); + return
{renderButtons}
; +}; +export default SidebarFilterButtons; diff --git a/src/components/Common/SocialSidebar/index.js b/src/components/Common/SocialSidebar/index.js new file mode 100644 index 00000000..df7d4843 --- /dev/null +++ b/src/components/Common/SocialSidebar/index.js @@ -0,0 +1,5 @@ +import Sidebar from "./Sidebar"; +import SidebarFilterButton from "./SidebarFilterButton"; +import SidebarFilterButtons from "./SidebarFilterButtons"; + +export { Sidebar, SidebarFilterButton, SidebarFilterButtons }; diff --git a/src/components/CommunityEvents/CommunityEvents.jsx b/src/components/CommunityEvents/CommunityEvents.jsx index 67de35fe..4e70ba33 100644 --- a/src/components/CommunityEvents/CommunityEvents.jsx +++ b/src/components/CommunityEvents/CommunityEvents.jsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useMemo, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { toast } from "react-toastify"; @@ -13,6 +13,7 @@ import { EventList, EventNote, CommunityEventHeaderContainer, + FilterContainer, } from "./CommunityEventsElement"; import NoDataFound from "src/assets/images/no_data_found.svg"; import { EventItemList } from "./EventItemList"; @@ -20,6 +21,7 @@ import { RouterNavCreateButton } from "src/components/Header/Navbar/NavbarElemen import ModifyCommunityEvent from "./ModifyCommunityEvent"; import LoadingSpinner from "src/components/Other/MixComponents/Spinner/LoadingSpinner"; import ModifyTimeline from "./ModifyTimeline"; +import { SidebarFilterButtons } from "src/components/Common/SocialSidebar"; const CommunityEvents = ({ pageHeader, @@ -39,6 +41,7 @@ const CommunityEvents = ({ const { events, isEventLoading, isEventError, eventMessage } = useSelector((state) => state.events); const [isActiveTab, setActiveTab] = useState(0); const [openCreatingNewEvent, setOpenCreatingNewEvent] = useState(false); + const [filterValue, setFilterValue] = useState(""); const tabNames = [ { id: 0, status: "upcoming" }, @@ -64,7 +67,37 @@ const CommunityEvents = ({ return () => dispatch(eventsReset()); }, [dispatch]); - const filteredEvents = events + const handleFilterUpdate = (filterLabel) => { + setFilterValue(filterLabel); + }; + + const filterButtonsData = useMemo( + () => [ + { + filterLabel: "All", + onClick: handleFilterUpdate, + id: "All" + Math.random() * 100, + }, + { + filterLabel: "Join", + onClick: handleFilterUpdate, + id: "Join" + Math.random() * 100, + }, + { + filterLabel: "Joined", + onClick: handleFilterUpdate, + id: "Joined" + Math.random() * 100, + }, + { + filterLabel: "Full", + onClick: handleFilterUpdate, + id: "Full" + Math.random() * 100, + }, + ], + [], + ); + + let filteredEvents = events ? events .filter((event) => { let eventFit = false; @@ -94,6 +127,38 @@ const CommunityEvents = ({ return a.date < b.date || (a.date === b.date && a.startTime < b.startTime); }) : []; + + if (filterValue) { + filteredEvents = filteredEvents.filter((event) => { + let suitable = false; + switch (filterValue) { + case "Full": + if ( + event.maxParticipantsNumber - event.participants.length === 0 && + !eventsJoinedId.includes(event._id) + ) { + suitable = true; + } + break; + case "Joined": + if (eventsJoinedId.includes(event._id)) { + suitable = true; + } + break; + case "Join": + if ( + event.maxParticipantsNumber - event.participants.length !== 0 && + !eventsJoinedId.includes(event._id) + ) { + suitable = true; + } + break; + default: + suitable = true; + } + return suitable; // } + }); + } const handleModifyEvent = (newEvent, eventId = "") => { if (!eventId) return dispatch(createEvent(newEvent)); dispatch(updateEvent({ id: newEvent._id, eventData: newEvent })); @@ -143,6 +208,14 @@ const CommunityEvents = ({ Create Event )} + {!modify && ( + + + + )} {modify && openCreatingNewEvent && ( diff --git a/src/components/CommunityEvents/CommunityEventsElement.jsx b/src/components/CommunityEvents/CommunityEventsElement.jsx index 3ccd5bf2..5d2ec9be 100644 --- a/src/components/CommunityEvents/CommunityEventsElement.jsx +++ b/src/components/CommunityEvents/CommunityEventsElement.jsx @@ -27,6 +27,18 @@ export const SubHeader = styled.p` color: gray; `; +export const FilterContainer = styled.div` + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + gap: 10px; + background: #131313; + border-radius: 7px; + height: 6vh; + align-self: center; + margin-bottom: 2.5rem; +`; export const Tabs = styled.div` display: flex; gap: 1rem; diff --git a/src/components/CommunityEvents/EventItemList.jsx b/src/components/CommunityEvents/EventItemList.jsx index 579b65e3..2a7085d2 100644 --- a/src/components/CommunityEvents/EventItemList.jsx +++ b/src/components/CommunityEvents/EventItemList.jsx @@ -90,7 +90,7 @@ export const EventItemList = ({ event, actions, index, modify, eventsJoinedId, u
-

{leftPlacesToJoin === 0 ? "Full" : actionDisplay}

+

+ {leftPlacesToJoin === 0 && actionDisplay !== "Joined" ? "Full" : actionDisplay} +

diff --git a/src/components/Explore/Explore.jsx b/src/components/Explore/Explore.jsx index 91ad2bb2..8699e913 100644 --- a/src/components/Explore/Explore.jsx +++ b/src/components/Explore/Explore.jsx @@ -18,7 +18,7 @@ import UnderMaintenance from "src/components/Other/UnderMaintenance/UnderMainten import LoadingSpinner from "src/components/Other/MixComponents/Spinner/LoadingSpinner"; import { getFollowData } from "src/features/follow/followSlice"; import { getConnections } from "src/features/connections/connectionSlice"; -import Sidebar from "src/components/Feeds/SocialSidebar/Sidebar"; +import Sidebar from "src/components/Common/SocialSidebar/Sidebar"; import { FilterButton } from "src/components/Feeds/FeedsElements"; import { HintIcon } from "src/components/WebSecurity/Common/HintElements"; import { FaAngleDown, FaAngleUp } from "react-icons/fa"; diff --git a/src/components/Feeds/Feeds.jsx b/src/components/Feeds/Feeds.jsx index cbabf527..d7c5cfb4 100644 --- a/src/components/Feeds/Feeds.jsx +++ b/src/components/Feeds/Feeds.jsx @@ -11,7 +11,7 @@ import UnderMaintenance from "src/components/Other/UnderMaintenance/UnderMainten import apiStatus from "src/features/apiStatus"; import { LeftContainer } from "src/components/Explore/ExploreElements"; import { getFollowData, reset } from "src/features/follow/followSlice"; -import Sidebar from "./SocialSidebar/Sidebar"; +import Sidebar from "src/components/Common/SocialSidebar/Sidebar"; const Feeds = () => { const dispatch = useDispatch(); diff --git a/src/components/Feeds/SocialSidebar/SidebarElements.jsx b/src/components/Feeds/SocialSidebar/SidebarElements.jsx deleted file mode 100644 index 64cfdf56..00000000 --- a/src/components/Feeds/SocialSidebar/SidebarElements.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import styled from "styled-components"; - -export const SidebarContainer = styled.div` - position: sticky; - display: flex; - flex-direction: column; - justify-content: flex-start; - gap: 10px; - top: 100px; - - width: 100%; - max-width: 400px; - min-width: ${(props) => (props.sidebarType === "explore" ? "300px" : "400px")}; - - color: #ffffff; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - border-radius: 10px; -`;