From ad3dbc05355803ed7e994772bf225958a97d9008 Mon Sep 17 00:00:00 2001 From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com> Date: Wed, 4 Oct 2023 15:58:44 +0530 Subject: [PATCH 1/7] Create left drawer for event dashboard --- .../LeftDrawerEvent.module.css | 290 ++++++++++++++++++ .../LeftDrawerEvent/LeftDrawerEvent.tsx | 168 ++++++++++ 2 files changed, 458 insertions(+) create mode 100644 src/components/LeftDrawerEvent/LeftDrawerEvent.module.css create mode 100644 src/components/LeftDrawerEvent/LeftDrawerEvent.tsx diff --git a/src/components/LeftDrawerEvent/LeftDrawerEvent.module.css b/src/components/LeftDrawerEvent/LeftDrawerEvent.module.css new file mode 100644 index 0000000000..399a7cb4ef --- /dev/null +++ b/src/components/LeftDrawerEvent/LeftDrawerEvent.module.css @@ -0,0 +1,290 @@ +.leftDrawer { + width: calc(300px + 2rem); + position: fixed; + top: 0; + bottom: 0; + z-index: 100; + display: flex; + flex-direction: column; + padding: 0.8rem 1rem 0 1rem; + background-color: var(--bs-white); + transition: 0.5s; + overflow-y: scroll; +} + +.leftDrawer::-webkit-scrollbar { + width: 6px; +} + +.leftDrawer::-webkit-scrollbar-track { + background: #f1f1f1; +} + +.leftDrawer::-webkit-scrollbar-thumb { + background: var(--bs-gray-500); +} + +.leftDrawer::-webkit-scrollbar-thumb:hover { + background: var(--bs-gray-600); +} + +.activeDrawer { + width: calc(300px + 2rem); + position: fixed; + top: 0; + left: 0; + bottom: 0; + animation: comeToRightBigScreen 0.5s ease-in-out; +} + +.inactiveDrawer { + position: fixed; + top: 0; + left: calc(-300px - 2rem); + bottom: 0; + animation: goToLeftBigScreen 0.5s ease-in-out; +} + +.leftDrawer .closeModalBtn { + display: none; +} + +.leftDrawer .brandingContainer { + display: flex; + justify-content: flex-start; + align-items: center; +} + +.leftDrawer .organizationContainer button { + position: relative; + margin: 1.25rem 0; + padding: 2.5rem 0.1rem; + border-radius: 0.5rem; + border: 1px solid var(--bs-gray-300); + background-color: var(--bs-gray-100); +} + +.leftDrawer .talawaLogo { + width: 42px; + height: 42px; + margin-right: 0.5rem; +} + +.leftDrawer .talawaText { + font-size: 1.1rem; +} + +.leftDrawer .titleHeader { + margin-bottom: 1rem; + font-weight: 600; +} + +.leftDrawer .optionList button { + display: flex; + align-items: center; + width: 100%; + text-align: start; + margin-bottom: 0.8rem; + border: 1px solid var(--bs-gray-200); + border-radius: 8px; +} + +.leftDrawer button .iconWrapper { + width: 36px; +} + +.leftDrawer .optionList .collapseBtn { + height: 48px; +} + +.leftDrawer button .iconWrapperSm { + width: 36px; + display: flex; + justify-content: center; + align-items: center; +} + +.leftDrawer .profileContainer { + border: none; + width: 100%; + margin-top: 5rem; + height: 52px; + border-radius: 8px; + background-color: var(--bs-white); + display: flex; + align-items: center; +} + +.leftDrawer .profileContainer:focus { + outline: none; + background-color: var(--bs-gray-100); +} + +.leftDrawer .imageContainer { + width: 68px; +} + +.leftDrawer .profileContainer img { + height: 52px; + width: 52px; + border-radius: 50%; +} + +.leftDrawer .profileContainer .profileText { + flex: 1; + text-align: start; +} + +.leftDrawer .profileContainer .profileText .primaryText { + font-size: 1.1rem; + font-weight: 600; +} + +.leftDrawer .profileContainer .profileText .secondaryText { + font-size: 0.8rem; + font-weight: 400; + color: var(--bs-secondary); + display: block; + text-transform: capitalize; +} + +@media (max-width: 1120px) { + .leftDrawer { + width: calc(250px + 2rem); + padding: 1rem 1rem 0 1rem; + } +} + +/* For tablets */ +@media (max-width: 820px) { + .hideElemByDefault { + display: none; + } + + .leftDrawer { + width: 100%; + left: 0; + right: 0; + } + + .leftDrawer .closeModalBtn { + display: block; + position: absolute; + top: 1rem; + right: 1rem; + z-index: 10; + } + + /* For smaller devices .activeDrawer in real behaves like inactive */ + .activeDrawer { + opacity: 0; + left: 0; + z-index: -1; + animation: closeDrawer 0.4s ease-in-out; + } + + /* For smaller devices .inactiveDrawer in real behaves like active */ + .inactiveDrawer { + display: flex; + z-index: 100; + animation: openDrawer 0.6s ease-in-out; + } +} + +@keyframes goToLeftBigScreen { + from { + left: 0; + } + + to { + opacity: 0.1; + left: calc(-300px - 2rem); + } +} + +/* Webkit prefix for older browser compatibility */ +@-webkit-keyframes goToLeftBigScreen { + from { + left: 0; + } + + to { + opacity: 0.1; + left: calc(-300px - 2rem); + } +} + +@keyframes comeToRightBigScreen { + from { + opacity: 0.4; + left: calc(-300px - 2rem); + } + + to { + opacity: 1; + left: 0; + } +} + +/* Webkit prefix for older browser compatibility */ +@-webkit-keyframes comeToRightBigScreen { + from { + opacity: 0.4; + left: calc(-300px - 2rem); + } + + to { + opacity: 1; + left: 0; + } +} + +@keyframes closeDrawer { + from { + left: 0; + opacity: 1; + } + + to { + left: -1000px; + opacity: 0; + } +} + +/* Webkit prefix for older browser compatibility */ +@-webkit-keyframes closeDrawer { + from { + left: 0; + opacity: 1; + } + + to { + left: -1000px; + opacity: 0; + } +} + +@keyframes openDrawer { + from { + opacity: 0; + left: -1000px; + } + + to { + left: 0; + opacity: 1; + } +} + +/* Webkit prefix for older browser compatibility */ +@-webkit-keyframes openDrawer { + from { + opacity: 0; + left: -1000px; + } + + to { + left: 0; + opacity: 1; + } +} diff --git a/src/components/LeftDrawerEvent/LeftDrawerEvent.tsx b/src/components/LeftDrawerEvent/LeftDrawerEvent.tsx new file mode 100644 index 0000000000..c80b55187e --- /dev/null +++ b/src/components/LeftDrawerEvent/LeftDrawerEvent.tsx @@ -0,0 +1,168 @@ +import React from 'react'; +import Button from 'react-bootstrap/Button'; +import { useHistory } from 'react-router-dom'; +import { toast } from 'react-toastify'; +import { ReactComponent as AngleRightIcon } from 'assets/svgs/angleRight.svg'; +import { ReactComponent as LogoutIcon } from 'assets/svgs/logout.svg'; +import { ReactComponent as TalawaLogo } from 'assets/svgs/talawa.svg'; +import styles from './LeftDrawerOrg.module.css'; +import IconComponent from 'components/IconComponent/IconComponent'; + +export interface InterfaceLeftDrawerProps { + event: { + _id: string; + title: string; + description: string; + }; + hideDrawer: boolean; + setHideDrawer: React.Dispatch>; +} + +const leftDrawerEvent = ({ + event, + hideDrawer, + setHideDrawer, +}: InterfaceLeftDrawerProps): JSX.Element => { + const userType = localStorage.getItem('UserType'); + const firstName = localStorage.getItem('FirstName'); + const lastName = localStorage.getItem('LastName'); + const userImage = localStorage.getItem('UserImage'); + + const history = useHistory(); + const logout = (): void => { + localStorage.clear(); + history.push('/'); + }; + + return ( + <> +
+ {/* Close Drawer Button for small devices */} + + + {/* Branding Section */} +
+ + Talawa Admin Portal +
+ + {/* Event Detail Section */} +
+ +
+ + {/* Options List */} + {/*
+
{t('menu')}
+ {targets.map(({ name, url }, index) => { + return url ? ( + + ) : ( + + ); + })} +
*/} + + {/* Profile Section & Logout Btn */} +
+ + +
+
+ + ); +}; + +export default leftDrawerEvent; From 038d32ac9033f5f36c28447e0869afc702a6d9e7 Mon Sep 17 00:00:00 2001 From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com> Date: Wed, 4 Oct 2023 16:45:20 +0530 Subject: [PATCH 2/7] Add basic styles to the event dashboard --- src/assets/svgs/addEventProject.svg | 1 + src/assets/svgs/checkInRegistrants.svg | 1 + src/assets/svgs/listEventRegistrants.svg | 1 + .../IconComponent/IconComponent.tsx | 5 ++ .../LeftDrawerEvent/LeftDrawerEvent.tsx | 58 +++++++----------- .../LeftDrawerEventWrapper.module.css | 60 +++++++++++++++++++ .../LeftDrawerEventWrapper.tsx | 57 ++++++++++++++++++ src/screens/EventDashboard/EventDashboard.tsx | 8 ++- 8 files changed, 153 insertions(+), 38 deletions(-) create mode 100644 src/assets/svgs/addEventProject.svg create mode 100644 src/assets/svgs/checkInRegistrants.svg create mode 100644 src/assets/svgs/listEventRegistrants.svg create mode 100644 src/components/LeftDrawerEvent/LeftDrawerEventWrapper.module.css create mode 100644 src/components/LeftDrawerEvent/LeftDrawerEventWrapper.tsx diff --git a/src/assets/svgs/addEventProject.svg b/src/assets/svgs/addEventProject.svg new file mode 100644 index 0000000000..3c561d5ee8 --- /dev/null +++ b/src/assets/svgs/addEventProject.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/checkInRegistrants.svg b/src/assets/svgs/checkInRegistrants.svg new file mode 100644 index 0000000000..b7fed08a8b --- /dev/null +++ b/src/assets/svgs/checkInRegistrants.svg @@ -0,0 +1 @@ +check_inCreated with Sketch.Created by Manivasakanfrom the Noun Project \ No newline at end of file diff --git a/src/assets/svgs/listEventRegistrants.svg b/src/assets/svgs/listEventRegistrants.svg new file mode 100644 index 0000000000..bf0475684a --- /dev/null +++ b/src/assets/svgs/listEventRegistrants.svg @@ -0,0 +1 @@ +Created by Sma Flofrom the Noun Project \ No newline at end of file diff --git a/src/components/IconComponent/IconComponent.tsx b/src/components/IconComponent/IconComponent.tsx index a4648a6e03..a338fd9f59 100644 --- a/src/components/IconComponent/IconComponent.tsx +++ b/src/components/IconComponent/IconComponent.tsx @@ -8,6 +8,7 @@ import { ReactComponent as PeopleIcon } from 'assets/svgs/people.svg'; import { ReactComponent as PluginsIcon } from 'assets/svgs/plugins.svg'; import { ReactComponent as PostsIcon } from 'assets/svgs/posts.svg'; import { ReactComponent as SettingsIcon } from 'assets/svgs/settings.svg'; +import { ReactComponent as AddEventProjectIcon } from 'assets/svgs/addEventProject.svg'; export interface InterfaceIconComponent { name: string; @@ -56,6 +57,10 @@ const iconComponent = (props: InterfaceIconComponent): JSX.Element => { data-testid="Icon-Component-AllOrganizationsIcon" /> ); + case 'Add Event Project': + return ( + + ); default: return ( >; + setShowAddEventProjectModal: React.Dispatch>; } const leftDrawerEvent = ({ event, hideDrawer, setHideDrawer, + setShowAddEventProjectModal, }: InterfaceLeftDrawerProps): JSX.Element => { const userType = localStorage.getItem('UserType'); const firstName = localStorage.getItem('FirstName'); @@ -83,41 +85,25 @@ const leftDrawerEvent = ({ {/* Options List */} - {/*
-
{t('menu')}
- {targets.map(({ name, url }, index) => { - return url ? ( - - ) : ( - +
Event Options
+
+ Add an Event Project + + {/* Profile Section & Logout Btn */}
diff --git a/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.module.css b/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.module.css new file mode 100644 index 0000000000..681ac8823d --- /dev/null +++ b/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.module.css @@ -0,0 +1,60 @@ +.pageContainer { + display: flex; + flex-direction: column; + min-height: 100vh; + padding: 1rem 1.5rem 0 calc(300px + 2rem + 1.5rem); +} + +.expand { + padding-left: 1.5rem; + animation: moveLeft 0.5s ease-in-out; +} + +.contract { + padding-left: calc(300px + 2rem + 1.5rem); + animation: moveRight 0.5s ease-in-out; +} + +@media (max-width: 1120px) { + .contract { + padding-left: calc(250px + 2rem + 1.5rem); + } +} + +/* For tablets */ +@media (max-width: 820px) { + .pageContainer { + padding-left: 1.5rem; + } + + .contract, + .expand { + animation: none; + } +} + +@media (max-width: 820px) { + .pageContainer { + padding: 1rem; + } +} + +@keyframes moveLeft { + from { + padding-left: calc(300px + 2rem + 1.5rem); + } + + to { + padding-left: 1.5rem; + } +} + +@keyframes moveRight { + from { + padding-left: 1.5rem; + } + + to { + padding-left: calc(300px + 2rem + 1.5rem); + } +} diff --git a/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.tsx b/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.tsx new file mode 100644 index 0000000000..05acf1e177 --- /dev/null +++ b/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.tsx @@ -0,0 +1,57 @@ +import MenuIcon from '@mui/icons-material/Menu'; +import LeftDrawerEvent from './LeftDrawerEvent'; +import React, { useState } from 'react'; +import Button from 'react-bootstrap/Button'; +import styles from './LeftDrawerEventWrapper.module.css'; + +export interface InterfacePropType { + event: { + _id: string; + title: string; + description: string; + }; + setShowAddEventProjectModal: React.Dispatch>; + children: React.ReactNode; +} + +export const LeftDrawerEventWrapper = ( + props: InterfacePropType +): JSX.Element => { + const [hideDrawer, setHideDrawer] = useState(null); + + return ( + <> + +
+
+
+

Event Dashboard

+
+ +
+ {props.children} +
+ + ); +}; diff --git a/src/screens/EventDashboard/EventDashboard.tsx b/src/screens/EventDashboard/EventDashboard.tsx index 0c48f30f12..fa18eccd64 100644 --- a/src/screens/EventDashboard/EventDashboard.tsx +++ b/src/screens/EventDashboard/EventDashboard.tsx @@ -15,6 +15,7 @@ import { EventRegistrantsWrapper } from 'components/EventRegistrantsModal/EventR import { TaskListItem } from 'components/TaskListItem/TaskListItem'; import { CheckInWrapper } from 'components/CheckIn/CheckInWrapper'; import Loader from 'components/Loader/Loader'; +import { LeftDrawerEventWrapper } from 'components/LeftDrawerEvent/LeftDrawerEventWrapper'; interface InterfaceEventTask { _id: string; @@ -70,7 +71,10 @@ const EventDashboard = (): JSX.Element => { } return ( - <> +
@@ -256,7 +260,7 @@ const EventDashboard = (): JSX.Element => { refetchData={refetchEventData} projectId={currentProject._id} /> - + ); }; From 344977fd419479201e8f9bb4f2d628aff721446d Mon Sep 17 00:00:00 2001 From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com> Date: Wed, 4 Oct 2023 17:40:58 +0530 Subject: [PATCH 3/7] Fix button styling --- src/assets/svgs/checkInRegistrants.svg | 2 +- src/assets/svgs/listEventRegistrants.svg | 2 +- .../CheckIn/CheckInWrapper.module.css | 13 +++++++++++ src/components/CheckIn/CheckInWrapper.tsx | 15 ++++++++---- .../EventRegistrantsWrapper.module.css | 13 +++++++++++ .../EventRegistrantsWrapper.tsx | 18 +++++++++++---- .../IconComponent/IconComponent.tsx | 21 ++++++++++++++++- src/components/LeftDrawer/LeftDrawer.tsx | 2 +- .../LeftDrawerEvent/LeftDrawerEvent.tsx | 12 +++++++++- .../LeftDrawerEventWrapper.tsx | 3 +++ .../LeftDrawerOrg/LeftDrawerOrg.tsx | 2 +- src/screens/EventDashboard/EventDashboard.tsx | 23 +------------------ 12 files changed, 89 insertions(+), 37 deletions(-) create mode 100644 src/components/CheckIn/CheckInWrapper.module.css create mode 100644 src/components/EventRegistrantsModal/EventRegistrantsWrapper.module.css diff --git a/src/assets/svgs/checkInRegistrants.svg b/src/assets/svgs/checkInRegistrants.svg index b7fed08a8b..0a663e3876 100644 --- a/src/assets/svgs/checkInRegistrants.svg +++ b/src/assets/svgs/checkInRegistrants.svg @@ -1 +1 @@ -check_inCreated with Sketch.Created by Manivasakanfrom the Noun Project \ No newline at end of file +check_inCreated with Sketch. \ No newline at end of file diff --git a/src/assets/svgs/listEventRegistrants.svg b/src/assets/svgs/listEventRegistrants.svg index bf0475684a..4d2874d641 100644 --- a/src/assets/svgs/listEventRegistrants.svg +++ b/src/assets/svgs/listEventRegistrants.svg @@ -1 +1 @@ -Created by Sma Flofrom the Noun Project \ No newline at end of file + \ No newline at end of file diff --git a/src/components/CheckIn/CheckInWrapper.module.css b/src/components/CheckIn/CheckInWrapper.module.css new file mode 100644 index 0000000000..f5f42546c3 --- /dev/null +++ b/src/components/CheckIn/CheckInWrapper.module.css @@ -0,0 +1,13 @@ +button .iconWrapper { + width: 32px; + padding-right: 4px; + margin-right: 4px; + transform: translateY(4px); +} + +button .iconWrapperSm { + width: 32px; + display: flex; + justify-content: center; + align-items: center; +} diff --git a/src/components/CheckIn/CheckInWrapper.tsx b/src/components/CheckIn/CheckInWrapper.tsx index a1dae1da42..9a87a12ed3 100644 --- a/src/components/CheckIn/CheckInWrapper.tsx +++ b/src/components/CheckIn/CheckInWrapper.tsx @@ -1,6 +1,8 @@ import React, { useState } from 'react'; import { CheckInModal } from './CheckInModal'; import { Button } from 'react-bootstrap'; +import IconComponent from 'components/IconComponent/IconComponent'; +import styles from './CheckInWrapper.module.css'; type PropType = { eventId: string; @@ -12,14 +14,19 @@ export const CheckInWrapper = (props: PropType): JSX.Element => { return ( <> {showModal && ( diff --git a/src/components/EventRegistrantsModal/EventRegistrantsWrapper.module.css b/src/components/EventRegistrantsModal/EventRegistrantsWrapper.module.css new file mode 100644 index 0000000000..59b31333af --- /dev/null +++ b/src/components/EventRegistrantsModal/EventRegistrantsWrapper.module.css @@ -0,0 +1,13 @@ +button .iconWrapper { + width: 36px; + padding-right: 4px; + margin-right: 4px; + transform: translateY(4px); +} + +button .iconWrapperSm { + width: 36px; + display: flex; + justify-content: center; + align-items: center; +} diff --git a/src/components/EventRegistrantsModal/EventRegistrantsWrapper.tsx b/src/components/EventRegistrantsModal/EventRegistrantsWrapper.tsx index a45a428bfc..b621f8673a 100644 --- a/src/components/EventRegistrantsModal/EventRegistrantsWrapper.tsx +++ b/src/components/EventRegistrantsModal/EventRegistrantsWrapper.tsx @@ -1,6 +1,8 @@ import React, { useState } from 'react'; import { EventRegistrantsModal } from './EventRegistrantsModal'; import { Button } from 'react-bootstrap'; +import IconComponent from 'components/IconComponent/IconComponent'; +import styles from './EventRegistrantsWrapper.module.css'; type PropType = { eventId: string; @@ -13,17 +15,23 @@ export const EventRegistrantsWrapper = (props: PropType): JSX.Element => { return ( <> - {showModal ? ( + + {showModal && ( { @@ -32,7 +40,7 @@ export const EventRegistrantsWrapper = (props: PropType): JSX.Element => { eventId={props.eventId} orgId={props.orgId} /> - ) : null} + )} ); }; diff --git a/src/components/IconComponent/IconComponent.tsx b/src/components/IconComponent/IconComponent.tsx index a338fd9f59..4be98448be 100644 --- a/src/components/IconComponent/IconComponent.tsx +++ b/src/components/IconComponent/IconComponent.tsx @@ -9,6 +9,8 @@ import { ReactComponent as PluginsIcon } from 'assets/svgs/plugins.svg'; import { ReactComponent as PostsIcon } from 'assets/svgs/posts.svg'; import { ReactComponent as SettingsIcon } from 'assets/svgs/settings.svg'; import { ReactComponent as AddEventProjectIcon } from 'assets/svgs/addEventProject.svg'; +import { ReactComponent as ListEventRegistrantsIcon } from 'assets/svgs/listEventRegistrants.svg'; +import { ReactComponent as CheckInRegistrants } from 'assets/svgs/checkInRegistrants.svg'; export interface InterfaceIconComponent { name: string; @@ -59,7 +61,24 @@ const iconComponent = (props: InterfaceIconComponent): JSX.Element => { ); case 'Add Event Project': return ( - + + ); + case 'List Event Registrants': + return ( + + ); + case 'Check In Registrants': + return ( + ); default: return ( diff --git a/src/components/LeftDrawer/LeftDrawer.tsx b/src/components/LeftDrawer/LeftDrawer.tsx index e28f40d31a..b5244b2df7 100644 --- a/src/components/LeftDrawer/LeftDrawer.tsx +++ b/src/components/LeftDrawer/LeftDrawer.tsx @@ -143,7 +143,7 @@ const leftDrawer = ({ {`profile ) : ( {`dummy )} diff --git a/src/components/LeftDrawerEvent/LeftDrawerEvent.tsx b/src/components/LeftDrawerEvent/LeftDrawerEvent.tsx index 4bccaafa4c..8b63291435 100644 --- a/src/components/LeftDrawerEvent/LeftDrawerEvent.tsx +++ b/src/components/LeftDrawerEvent/LeftDrawerEvent.tsx @@ -7,12 +7,17 @@ import { ReactComponent as LogoutIcon } from 'assets/svgs/logout.svg'; import { ReactComponent as TalawaLogo } from 'assets/svgs/talawa.svg'; import styles from './LeftDrawerEvent.module.css'; import IconComponent from 'components/IconComponent/IconComponent'; +import { EventRegistrantsWrapper } from 'components/EventRegistrantsModal/EventRegistrantsWrapper'; +import { CheckInWrapper } from 'components/CheckIn/CheckInWrapper'; export interface InterfaceLeftDrawerProps { event: { _id: string; title: string; description: string; + organization: { + _id: string; + }; }; hideDrawer: boolean | null; setHideDrawer: React.Dispatch>; @@ -74,7 +79,7 @@ const leftDrawerEvent = ({ src={`https://api.dicebear.com/5.x/initials/svg?seed=${event.title .split(' ') .join('%20')}`} - alt={`Dummy Event Picture`} + alt="Dummy Event Picture" />
@@ -103,6 +108,11 @@ const leftDrawerEvent = ({
Add an Event Project + +
{/* Profile Section & Logout Btn */} diff --git a/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.tsx b/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.tsx index 05acf1e177..9c5e8418db 100644 --- a/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.tsx +++ b/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.tsx @@ -9,6 +9,9 @@ export interface InterfacePropType { _id: string; title: string; description: string; + organization: { + _id: string; + }; }; setShowAddEventProjectModal: React.Dispatch>; children: React.ReactNode; diff --git a/src/components/LeftDrawerOrg/LeftDrawerOrg.tsx b/src/components/LeftDrawerOrg/LeftDrawerOrg.tsx index 119a90f0eb..beb7f07206 100644 --- a/src/components/LeftDrawerOrg/LeftDrawerOrg.tsx +++ b/src/components/LeftDrawerOrg/LeftDrawerOrg.tsx @@ -192,7 +192,7 @@ const leftDrawerOrg = ({ {`profile ) : ( {`dummy )} diff --git a/src/screens/EventDashboard/EventDashboard.tsx b/src/screens/EventDashboard/EventDashboard.tsx index fa18eccd64..18b885a131 100644 --- a/src/screens/EventDashboard/EventDashboard.tsx +++ b/src/screens/EventDashboard/EventDashboard.tsx @@ -11,9 +11,7 @@ import { AddTaskModal } from 'components/TaskModals/AddTaskModal'; import { EVENT_DETAILS } from 'GraphQl/Queries/Queries'; import Button from 'react-bootstrap/Button'; import List from '@mui/material/List'; -import { EventRegistrantsWrapper } from 'components/EventRegistrantsModal/EventRegistrantsWrapper'; import { TaskListItem } from 'components/TaskListItem/TaskListItem'; -import { CheckInWrapper } from 'components/CheckIn/CheckInWrapper'; import Loader from 'components/Loader/Loader'; import { LeftDrawerEventWrapper } from 'components/LeftDrawerEvent/LeftDrawerEventWrapper'; @@ -100,28 +98,9 @@ const EventDashboard = (): JSX.Element => { : ``}

- Registrantss: {eventData.event.attendees.length} + Registrants: {eventData.event.attendees.length}


- {/* Buttons to trigger different modals */} -

- - - -

From 83ec339d3e5773ed57584db775e22d68770d3a33 Mon Sep 17 00:00:00 2001 From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com> Date: Thu, 5 Oct 2023 10:04:48 +0530 Subject: [PATCH 4/7] Add testing --- src/assets/svgs/eventStats.svg | 1 + .../EventStats/EventStatsWrapper.module.css | 13 +++ .../EventStats/EventStatsWrapper.tsx | 24 +++--- .../IconComponent/IconComponent.test.tsx | 80 ++++++------------- .../IconComponent/IconComponent.tsx | 12 ++- .../LeftDrawerEvent.module.css | 1 + .../LeftDrawerEvent/LeftDrawerEvent.tsx | 2 + src/screens/EventDashboard/EventDashboard.tsx | 10 ++- 8 files changed, 73 insertions(+), 70 deletions(-) create mode 100644 src/assets/svgs/eventStats.svg create mode 100644 src/components/EventStats/EventStatsWrapper.module.css diff --git a/src/assets/svgs/eventStats.svg b/src/assets/svgs/eventStats.svg new file mode 100644 index 0000000000..9503758f39 --- /dev/null +++ b/src/assets/svgs/eventStats.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/EventStats/EventStatsWrapper.module.css b/src/components/EventStats/EventStatsWrapper.module.css new file mode 100644 index 0000000000..f5f42546c3 --- /dev/null +++ b/src/components/EventStats/EventStatsWrapper.module.css @@ -0,0 +1,13 @@ +button .iconWrapper { + width: 32px; + padding-right: 4px; + margin-right: 4px; + transform: translateY(4px); +} + +button .iconWrapperSm { + width: 32px; + display: flex; + justify-content: center; + align-items: center; +} diff --git a/src/components/EventStats/EventStatsWrapper.tsx b/src/components/EventStats/EventStatsWrapper.tsx index 953a21a06b..eef529342b 100644 --- a/src/components/EventStats/EventStatsWrapper.tsx +++ b/src/components/EventStats/EventStatsWrapper.tsx @@ -1,6 +1,8 @@ import React, { useState } from 'react'; import { EventStats } from './EventStats'; import { Button } from 'react-bootstrap'; +import IconComponent from 'components/IconComponent/IconComponent'; +import styles from './EventStatsWrapper.module.css'; type PropType = { eventId: string; @@ -12,23 +14,23 @@ export const EventStatsWrapper = (props: PropType): JSX.Element => { return ( <> - {showModal && ( - setShowModal(false)} - eventId={props.eventId} - /> - )} + setShowModal(false)} + eventId={props.eventId} + /> ); }; diff --git a/src/components/IconComponent/IconComponent.test.tsx b/src/components/IconComponent/IconComponent.test.tsx index 766a6576b8..ff83ebe57c 100644 --- a/src/components/IconComponent/IconComponent.test.tsx +++ b/src/components/IconComponent/IconComponent.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import IconComponent from './IconComponent'; -const screenTestIdMap = { +const screenTestIdMap: Record> = { Dashboard: { name: 'Dashboard', testId: 'Icon-Component-DashboardIcon', @@ -35,65 +35,35 @@ const screenTestIdMap = { name: 'All Organizations', testId: 'Icon-Component-AllOrganizationsIcon', }, + EventProject: { + name: 'Add Event Project', + testId: 'Icon-Component-Add-Event-Project', + }, + ListEventRegistrant: { + name: 'List Event Registrants', + testId: 'Icon-Component-List-Event-Registrants', + }, + CheckInRegistrants: { + name: 'Check In Registrants', + testId: 'Icon-Component-Check-In-Registrants', + }, + EventStats: { + name: 'Event Stats', + testId: 'Icon-Component-Event-Stats', + }, default: { name: 'default', testId: 'Icon-Component-DefaultIcon', }, }; -describe('Testing CollapsibleDropdown component', () => { - it('renders the Dashboard icon', () => { - render(); - expect( - screen.getByTestId(`${screenTestIdMap.Dashboard.testId}`) - ).toBeInTheDocument(); - }); - it('renders the People icon', () => { - render(); - expect( - screen.getByTestId(`${screenTestIdMap.People.testId}`) - ).toBeInTheDocument(); - }); - it('renders the Events icon', () => { - render(); - expect( - screen.getByTestId(`${screenTestIdMap.Events.testId}`) - ).toBeInTheDocument(); - }); - it('renders the Posts icon', () => { - render(); - expect( - screen.getByTestId(`${screenTestIdMap.Posts.testId}`) - ).toBeInTheDocument(); - }); - it('renders the Block/Unblock icon', () => { - render(); - expect( - screen.getByTestId(`${screenTestIdMap.BlockUnblock.testId}`) - ).toBeInTheDocument(); - }); - it('renders the Plugins icon', () => { - render(); - expect( - screen.getByTestId(`${screenTestIdMap.Plugins.testId}`) - ).toBeInTheDocument(); - }); - it('renders the Settings icon', () => { - render(); - expect( - screen.getByTestId(`${screenTestIdMap.Settings.testId}`) - ).toBeInTheDocument(); - }); - it('renders the All Organizations icon', () => { - render(); - expect( - screen.getByTestId(`${screenTestIdMap.AllOrganizations.testId}`) - ).toBeInTheDocument(); - }); - it('renders the default icon', () => { - render(); - expect( - screen.getByTestId(`${screenTestIdMap.default.testId}`) - ).toBeInTheDocument(); +describe('Testing Collapsible Dropdown component', () => { + it('Renders the correct icon according to the component', () => { + for (const component in screenTestIdMap) { + render(); + expect( + screen.getByTestId(screenTestIdMap[component].testId) + ).toBeInTheDocument(); + } }); }); diff --git a/src/components/IconComponent/IconComponent.tsx b/src/components/IconComponent/IconComponent.tsx index 4be98448be..8504b13d2a 100644 --- a/src/components/IconComponent/IconComponent.tsx +++ b/src/components/IconComponent/IconComponent.tsx @@ -10,7 +10,8 @@ import { ReactComponent as PostsIcon } from 'assets/svgs/posts.svg'; import { ReactComponent as SettingsIcon } from 'assets/svgs/settings.svg'; import { ReactComponent as AddEventProjectIcon } from 'assets/svgs/addEventProject.svg'; import { ReactComponent as ListEventRegistrantsIcon } from 'assets/svgs/listEventRegistrants.svg'; -import { ReactComponent as CheckInRegistrants } from 'assets/svgs/checkInRegistrants.svg'; +import { ReactComponent as CheckInRegistrantsIcon } from 'assets/svgs/checkInRegistrants.svg'; +import { ReactComponent as EventStatsIcon } from 'assets/svgs/eventStats.svg'; export interface InterfaceIconComponent { name: string; @@ -75,11 +76,18 @@ const iconComponent = (props: InterfaceIconComponent): JSX.Element => { ); case 'Check In Registrants': return ( - ); + case 'Event Stats': + return ( + + ); default: return ( + {/* Profile Section & Logout Btn */} diff --git a/src/screens/EventDashboard/EventDashboard.tsx b/src/screens/EventDashboard/EventDashboard.tsx index 18b885a131..4089cd23a4 100644 --- a/src/screens/EventDashboard/EventDashboard.tsx +++ b/src/screens/EventDashboard/EventDashboard.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import Row from 'react-bootstrap/Row'; import Col from 'react-bootstrap/Col'; import { useQuery } from '@apollo/client'; @@ -37,7 +37,13 @@ interface InterfaceEventProject { const EventDashboard = (): JSX.Element => { // Get the Event ID from the URL document.title = 'Event Dashboard'; - const eventId = window.location.href.split('/')[4]; + + const [eventId, setEventId] = useState(''); + + useEffect(() => { + console.log(window.location.href); + setEventId(window.location.href.split('/')[4]); + }, [window.location.href]); // Data fetching const { From 9904d967550c134ffe94adf8e97d0b94f63406ab Mon Sep 17 00:00:00 2001 From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com> Date: Thu, 5 Oct 2023 11:26:54 +0530 Subject: [PATCH 5/7] Add testing for the left event drawer --- src/GraphQl/Queries/Queries.ts | 1 + .../EventStats/EventStatsWrapper.tsx | 1 + .../LeftDrawerEvent/LeftDrawerEvent.test.tsx | 187 ++++++++++++++++++ .../LeftDrawerEvent/LeftDrawerEvent.tsx | 13 +- .../LeftDrawerEventWrapper.test.tsx | 94 +++++++++ .../LeftDrawerEventWrapper.tsx | 6 +- src/screens/EventDashboard/EventDashboard.tsx | 2 +- 7 files changed, 298 insertions(+), 6 deletions(-) create mode 100644 src/components/LeftDrawerEvent/LeftDrawerEvent.test.tsx create mode 100644 src/components/LeftDrawerEvent/LeftDrawerEventWrapper.test.tsx diff --git a/src/GraphQl/Queries/Queries.ts b/src/GraphQl/Queries/Queries.ts index 02dec2a6f6..0cea409b99 100644 --- a/src/GraphQl/Queries/Queries.ts +++ b/src/GraphQl/Queries/Queries.ts @@ -95,6 +95,7 @@ export const USER_LIST = gql` export const EVENT_DETAILS = gql` query Event($id: ID!) { event(id: $id) { + _id title description startDate diff --git a/src/components/EventStats/EventStatsWrapper.tsx b/src/components/EventStats/EventStatsWrapper.tsx index eef529342b..b501e77430 100644 --- a/src/components/EventStats/EventStatsWrapper.tsx +++ b/src/components/EventStats/EventStatsWrapper.tsx @@ -29,6 +29,7 @@ export const EventStatsWrapper = (props: PropType): JSX.Element => { setShowModal(false)} + key={props.eventId || 'eventStatsDetails'} eventId={props.eventId} /> diff --git a/src/components/LeftDrawerEvent/LeftDrawerEvent.test.tsx b/src/components/LeftDrawerEvent/LeftDrawerEvent.test.tsx new file mode 100644 index 0000000000..f6187ce9c6 --- /dev/null +++ b/src/components/LeftDrawerEvent/LeftDrawerEvent.test.tsx @@ -0,0 +1,187 @@ +import React from 'react'; +import { render, screen, waitFor, fireEvent } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import 'jest-localstorage-mock'; +import { I18nextProvider } from 'react-i18next'; +import { BrowserRouter } from 'react-router-dom'; +import { toast } from 'react-toastify'; +import i18nForTest from 'utils/i18nForTest'; +import LeftDrawerEvent, { + type InterfaceLeftDrawerProps, +} from './LeftDrawerEvent'; +import { MockedProvider } from '@apollo/react-testing'; +import { EVENT_FEEDBACKS } from 'GraphQl/Queries/Queries'; + +const props: InterfaceLeftDrawerProps = { + event: { + _id: 'testEvent', + title: 'Test Event', + description: 'Test Description', + organization: { + _id: 'Test Organization', + }, + }, + hideDrawer: false, + setHideDrawer: jest.fn(), + setShowAddEventProjectModal: jest.fn(), +}; + +const mocks = [ + { + request: { + query: EVENT_FEEDBACKS, + variables: { + id: 'testEvent', + }, + }, + result: { + data: { + event: { + _id: 'testEvent', + feedback: [], + averageFeedbackScore: 5, + }, + }, + }, + }, +]; + +jest.mock('react-toastify', () => ({ + toast: { + success: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + }, +})); + +// Mock the modules for PieChart rendering as they require a trasformer being used (which is not done by Jest) +// They are required by the feedback statistics component +jest.mock('@mui/x-charts/PieChart', () => ({ + pieArcLabelClasses: jest.fn(), + PieChart: jest.fn().mockImplementation(() => <>Test), + pieArcClasses: jest.fn(), +})); + +beforeEach(() => { + localStorage.setItem('FirstName', 'John'); + localStorage.setItem('LastName', 'Doe'); + localStorage.setItem( + 'UserImage', + 'https://api.dicebear.com/5.x/initials/svg?seed=John%20Doe' + ); +}); + +afterEach(() => { + jest.clearAllMocks(); + localStorage.clear(); +}); + +describe('Testing Left Drawer component for the Event Dashboard', () => { + test('Component should be rendered properly', async () => { + localStorage.setItem('UserImage', ''); + localStorage.setItem('UserType', 'SUPERADMIN'); + + const { queryByText } = render( + + + + + + + + ); + + await waitFor(() => + expect(queryByText('Talawa Admin Portal')).toBeInTheDocument() + ); + await waitFor(() => expect(queryByText('Test Event')).toBeInTheDocument()); + await waitFor(() => + expect(queryByText('Test Description')).toBeInTheDocument() + ); + await waitFor(() => + expect(queryByText('Event Options')).toBeInTheDocument() + ); + }); + + test('Add Event Project button and profile page button should work properly', async () => { + localStorage.setItem('UserType', 'SUPERADMIN'); + + const { queryByText, queryByTestId } = render( + + + + + + + + ); + + await waitFor(() => + expect(queryByText('Talawa Admin Portal')).toBeInTheDocument() + ); + + fireEvent.click(queryByText('Add an Event Project') as HTMLElement); + expect(props.setShowAddEventProjectModal).toHaveBeenCalled(); + + fireEvent.click(queryByTestId(/profileBtn/i) as HTMLElement); + expect(toast.success).toHaveBeenCalledWith('Profile page coming soon!'); + }); + + test('Testing Drawer when hideDrawer is null', () => { + localStorage.setItem('UserType', 'SUPERADMIN'); + render( + + + + + + + + ); + }); + + test('Testing Drawer when hideDrawer is true', () => { + localStorage.setItem('UserType', 'SUPERADMIN'); + render( + + + + + + + + ); + }); + + test('Testing Drawer open close functionality', () => { + localStorage.setItem('UserType', 'SUPERADMIN'); + render( + + + + + + + + ); + const closeModalBtn = screen.getByTestId(/closeModalBtn/i); + userEvent.click(closeModalBtn); + }); + + test('Testing logout functionality', async () => { + localStorage.setItem('UserType', 'SUPERADMIN'); + render( + + + + + + + + ); + + userEvent.click(screen.getByTestId('logoutBtn')); + expect(localStorage.clear).toHaveBeenCalled(); + expect(global.window.location.pathname).toBe('/'); + }); +}); diff --git a/src/components/LeftDrawerEvent/LeftDrawerEvent.tsx b/src/components/LeftDrawerEvent/LeftDrawerEvent.tsx index eb4785498f..1981eb12f0 100644 --- a/src/components/LeftDrawerEvent/LeftDrawerEvent.tsx +++ b/src/components/LeftDrawerEvent/LeftDrawerEvent.tsx @@ -110,11 +110,18 @@ const leftDrawerEvent = ({ Add an Event Project - - + + {/* Profile Section & Logout Btn */} @@ -123,7 +130,7 @@ const leftDrawerEvent = ({ className={styles.profileContainer} data-testid="profileBtn" onClick={(): void => { - toast.success('Profile Page coming soon!'); + toast.success('Profile page coming soon!'); }} >
diff --git a/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.test.tsx b/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.test.tsx new file mode 100644 index 0000000000..72093aaf06 --- /dev/null +++ b/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.test.tsx @@ -0,0 +1,94 @@ +import React from 'react'; +import 'jest-localstorage-mock'; +import { render, waitFor, fireEvent } from '@testing-library/react'; +import { I18nextProvider } from 'react-i18next'; +import { BrowserRouter } from 'react-router-dom'; +import i18nForTest from 'utils/i18nForTest'; +import { + type InterfacePropType, + LeftDrawerEventWrapper, +} from './LeftDrawerEventWrapper'; +import { MockedProvider } from '@apollo/react-testing'; +import { EVENT_FEEDBACKS } from 'GraphQl/Queries/Queries'; + +const props: InterfacePropType = { + event: { + _id: 'testEvent', + title: 'Test Event', + description: 'Test Description', + organization: { + _id: 'Test Organization', + }, + }, + setShowAddEventProjectModal: jest.fn(), + children: null, +}; + +const mocks = [ + { + request: { + query: EVENT_FEEDBACKS, + variables: { + id: 'testEvent', + }, + }, + result: { + data: { + event: { + _id: 'testEvent', + feedback: [], + averageFeedbackScore: 5, + }, + }, + }, + }, +]; + +jest.mock('react-toastify', () => ({ + toast: { + success: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + }, +})); + +// Mock the modules for PieChart rendering as they require a trasformer being used (which is not done by Jest) +// They are required by the feedback statistics component +jest.mock('@mui/x-charts/PieChart', () => ({ + pieArcLabelClasses: jest.fn(), + PieChart: jest.fn().mockImplementation(() => <>Test), + pieArcClasses: jest.fn(), +})); + +beforeEach(() => { + localStorage.setItem('FirstName', 'John'); + localStorage.setItem('LastName', 'Doe'); + localStorage.setItem( + 'UserImage', + 'https://api.dicebear.com/5.x/initials/svg?seed=John%20Doe' + ); +}); + +afterEach(() => { + jest.clearAllMocks(); + localStorage.clear(); +}); + +describe('Testing Left Drawer Wrapper component for the Event Dashboard', () => { + test('Component should be rendered properly and the close menu button should function', async () => { + const { queryByText, queryByTestId } = render( + + + + + + + + ); + + await waitFor(() => + expect(queryByText('Event Management')).toBeInTheDocument() + ); + fireEvent.click(queryByTestId('closeLeftDrawerBtn') as HTMLElement); + }); +}); diff --git a/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.tsx b/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.tsx index 9c5e8418db..1b1157385c 100644 --- a/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.tsx +++ b/src/components/LeftDrawerEvent/LeftDrawerEventWrapper.tsx @@ -25,10 +25,12 @@ export const LeftDrawerEventWrapper = ( return ( <> +
-

Event Dashboard

+

Event Management

diff --git a/src/screens/EventDashboard/EventDashboard.tsx b/src/screens/EventDashboard/EventDashboard.tsx index 4089cd23a4..810e8335c6 100644 --- a/src/screens/EventDashboard/EventDashboard.tsx +++ b/src/screens/EventDashboard/EventDashboard.tsx @@ -41,7 +41,6 @@ const EventDashboard = (): JSX.Element => { const [eventId, setEventId] = useState(''); useEffect(() => { - console.log(window.location.href); setEventId(window.location.href.split('/')[4]); }, [window.location.href]); @@ -77,6 +76,7 @@ const EventDashboard = (): JSX.Element => { return ( From 8d574811ed974350dd98941ada3fffbff13681b8 Mon Sep 17 00:00:00 2001 From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com> Date: Thu, 5 Oct 2023 13:25:45 +0530 Subject: [PATCH 6/7] Add 100% line coverage for all components --- .../UserPortal/Register/Register.test.tsx | 1 - .../EventDashboard/EventDashboard.mocks.ts | 75 ++++++++++++ .../EventDashboard/EventDashboard.test.tsx | 111 +++++++++++------- 3 files changed, 146 insertions(+), 41 deletions(-) diff --git a/src/components/UserPortal/Register/Register.test.tsx b/src/components/UserPortal/Register/Register.test.tsx index f730baca73..8020ac03fa 100644 --- a/src/components/UserPortal/Register/Register.test.tsx +++ b/src/components/UserPortal/Register/Register.test.tsx @@ -4,7 +4,6 @@ import { act, render, screen } from '@testing-library/react'; import { MockedProvider } from '@apollo/react-testing'; import userEvent from '@testing-library/user-event'; import { I18nextProvider } from 'react-i18next'; - import { SIGNUP_MUTATION } from 'GraphQl/Mutations/mutations'; import { BrowserRouter } from 'react-router-dom'; import { Provider } from 'react-redux'; diff --git a/src/screens/EventDashboard/EventDashboard.mocks.ts b/src/screens/EventDashboard/EventDashboard.mocks.ts index c9b1109e5d..fe5b66a959 100644 --- a/src/screens/EventDashboard/EventDashboard.mocks.ts +++ b/src/screens/EventDashboard/EventDashboard.mocks.ts @@ -1,4 +1,71 @@ import { EVENT_DETAILS } from 'GraphQl/Queries/Queries'; +import { EVENT_FEEDBACKS } from 'GraphQl/Queries/Queries'; + +const constantMocks = [ + { + request: { + query: EVENT_FEEDBACKS, + variables: { + id: 'event123', + }, + }, + result: { + data: { + event: { + _id: 'event123', + feedback: [], + averageFeedbackScore: 0, + }, + }, + }, + }, + { + request: { + query: EVENT_FEEDBACKS, + variables: { + id: '', + }, + }, + result: { + data: { + event: { + _id: '', + feedback: [], + averageFeedbackScore: 0, + }, + }, + }, + }, + { + request: { + query: EVENT_DETAILS, + variables: { + id: '', + }, + }, + result: { + data: { + event: { + _id: '', + title: 'Event Title', + description: 'Event Description', + startDate: '1/1/23', + endDate: '2/2/23', + startTime: '08:00:00', + endTime: '09:00:00', + allDay: false, + location: 'India', + organization: { + _id: '', + members: [], + }, + attendees: [], + projects: [], + }, + }, + }, + }, +]; // Mock 1 export const queryMockWithTime = [ @@ -12,6 +79,7 @@ export const queryMockWithTime = [ result: { data: { event: { + _id: 'event123', title: 'Event Title', description: 'Event Description', startDate: '1/1/23', @@ -30,6 +98,7 @@ export const queryMockWithTime = [ }, }, }, + ...constantMocks, ]; // Mock 2 @@ -44,6 +113,7 @@ export const queryMockWithoutTime = [ result: { data: { event: { + _id: 'event123', title: 'Event Title', description: 'Event Description', startDate: '1/1/23', @@ -62,6 +132,7 @@ export const queryMockWithoutTime = [ }, }, }, + ...constantMocks, ]; // Mock 3 @@ -76,6 +147,7 @@ export const queryMockWithProject = [ result: { data: { event: { + _id: 'event123', title: 'Event Title', description: 'Event Description', startDate: '1/1/23', @@ -101,6 +173,7 @@ export const queryMockWithProject = [ }, }, }, + ...constantMocks, ]; // Mock 4 @@ -115,6 +188,7 @@ export const queryMockWithProjectAndTask = [ result: { data: { event: { + _id: 'event123', title: 'Event Title', description: 'Event Description', startDate: '1/1/23', @@ -149,4 +223,5 @@ export const queryMockWithProjectAndTask = [ }, }, }, + ...constantMocks, ]; diff --git a/src/screens/EventDashboard/EventDashboard.test.tsx b/src/screens/EventDashboard/EventDashboard.test.tsx index 2a3340be10..b595f893eb 100644 --- a/src/screens/EventDashboard/EventDashboard.test.tsx +++ b/src/screens/EventDashboard/EventDashboard.test.tsx @@ -1,15 +1,14 @@ import React from 'react'; -import { fireEvent, render, waitFor } from '@testing-library/react'; +import { fireEvent, render, waitFor, act } from '@testing-library/react'; import EventDashboard from './EventDashboard'; import { BrowserRouter } from 'react-router-dom'; -import { Provider } from 'react-redux'; -import { store } from 'state/store'; import { I18nextProvider } from 'react-i18next'; import i18nForTest from 'utils/i18nForTest'; import { ToastContainer } from 'react-toastify'; import { MockedProvider } from '@apollo/react-testing'; import { LocalizationProvider } from '@mui/x-date-pickers'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { type DefaultOptions } from '@apollo/client'; import { queryMockWithProject, queryMockWithTime, @@ -17,6 +16,18 @@ import { queryMockWithProjectAndTask, } from './EventDashboard.mocks'; +// We want to disable all forms of caching so that we do not need to define a custom merge function in testing for the network requests +const defaultOptions: DefaultOptions = { + watchQuery: { + fetchPolicy: 'no-cache', + errorPolicy: 'ignore', + }, + query: { + fetchPolicy: 'no-cache', + errorPolicy: 'all', + }, +}; + // Mock the modules for PieChart rendering as they require a trasformer being used (which is not done by Jest) // These modules are used by the Feedback components jest.mock('@mui/x-charts/PieChart', () => ({ @@ -25,6 +36,16 @@ jest.mock('@mui/x-charts/PieChart', () => ({ pieArcClasses: jest.fn(), })); +// We will wait for 500 ms after each test to ensure that the queries and rendering of the nested components such as `Feedback` and `Statistics` is complete before moving on to the next test suite +// This is important to mitigate the cleanup errors due to nesting of components +async function wait(ms = 500): Promise { + await act(() => { + return new Promise((resolve) => { + setTimeout(resolve, ms); + }); + }); +} + describe('Testing Event Dashboard Screen', () => { beforeEach(() => { global.window = Object.create(window); @@ -37,25 +58,25 @@ describe('Testing Event Dashboard Screen', () => { }); test('The page should display event details correctly and also show the time if provided', async () => { - const { queryByText } = render( + const { queryByText, queryAllByText } = render( - + - - - - - - + + ); - await waitFor(() => expect(queryByText('Event Title')).toBeInTheDocument()); + await waitFor(() => expect(queryAllByText('Event Title').length).toBe(2)); await waitFor(() => - expect(queryByText('Event Description')).toBeInTheDocument() + expect(queryAllByText('Event Description').length).toBe(2) ); await waitFor(() => expect(queryByText('India')).toBeInTheDocument()); @@ -66,38 +87,44 @@ describe('Testing Event Dashboard Screen', () => { queryByText('There are no active projects for this event!') ).toBeInTheDocument() ); + + await wait(); }); test('The page should display event details correctly and should not show the time if it is null', async () => { - const { queryByText } = render( + const { queryAllByText } = render( - + - - - - - - + + ); - await waitFor(() => expect(queryByText('Event Title')).toBeInTheDocument()); + await waitFor(() => expect(queryAllByText('Event Title').length).toBe(2)); + + await wait(); }); test('The page should display event project details correctly when provided', async () => { const { queryByText } = render( - + - - - - - - + + + + @@ -108,34 +135,36 @@ describe('Testing Event Dashboard Screen', () => { await waitFor(() => expect(queryByText('Project Description 1')).toBeInTheDocument() ); + + await wait(); }); test('The modals from the page should work properly', async () => { - const { queryByRole, queryByText, getByRole } = render( + const { queryByRole, getByRole, queryAllByText } = render( - + - - - - - - + + ); - await waitFor(() => expect(queryByText('Event Title')).toBeInTheDocument()); + await waitFor(() => expect(queryAllByText('Event Title').length).toBe(2)); - // Edit Event Project Modal + // Add Event Project Modal await waitFor(() => fireEvent.click( getByRole('button', { name: 'addEventProject' }) as HTMLElement ) ); - fireEvent.click(queryByRole('button', { name: /close/i }) as HTMLElement); + fireEvent.click(queryByRole('button', { name: /close/i }) as HTMLElement); // Edit Event Project Modal await waitFor(() => fireEvent.click( @@ -157,5 +186,7 @@ describe('Testing Event Dashboard Screen', () => { fireEvent.click(getByRole('button', { name: 'addTask' }) as HTMLElement) ); fireEvent.click(queryByRole('button', { name: /close/i }) as HTMLElement); + + await wait(); }); }); From a5039503b5053e2316b158e639520cb1c3497ea0 Mon Sep 17 00:00:00 2001 From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com> Date: Thu, 5 Oct 2023 14:11:35 +0530 Subject: [PATCH 7/7] Increase timeout for tests --- src/setupTests.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/setupTests.ts b/src/setupTests.ts index feb8764f8b..392ad3e99b 100644 --- a/src/setupTests.ts +++ b/src/setupTests.ts @@ -32,3 +32,5 @@ jestPreviewConfigure({ // Opt-in to automatic mode to preview failed test case automatically. autoPreview: true, }); + +jest.setTimeout(15000);