From 516e472ea906530f05fe0f7953c9e76fcf025ae2 Mon Sep 17 00:00:00 2001 From: Jamari McFarlane <71823011+JamarTG@users.noreply.github.com> Date: Fri, 10 Nov 2023 19:50:43 -0500 Subject: [PATCH] Dynamic dashboard Enhancements (#979) * Dynamic Organization Dashboard * Dynamic Organization Dashboard * refined organization dashboard * Update src/utils/handleLatestFeed.ts Co-authored-by: Noble Mittal <62551163+beingnoble03@users.noreply.github.com> * fixed inconsistent casing * fixed org dashboard test * fixed org dashboard test * revert previous commit * final changes * final changes --------- Co-authored-by: Noble Mittal <62551163+beingnoble03@users.noreply.github.com> --- src/GraphQl/Queries/Queries.ts | 4 +- src/assets/svgs/date.svg | 1 + src/assets/svgs/location.svg | 1 + src/assets/svgs/user.svg | 1 + .../OrganizationDashCards/CardItem.module.css | 13 ++ .../OrganizationDashCards/CardItem.test.tsx | 9 +- .../OrganizationDashCards/CardItem.tsx | 56 ++++++- src/screens/OrgPost/OrgPost.test.tsx | 6 +- .../OrganizationDashboard.test.tsx | 11 +- .../OrganizationDashboard.tsx | 90 +++++----- .../OrganizationDashboardMocks.ts | 154 ++++++++++++------ src/screens/UserPortal/Home/Home.test.tsx | 5 +- src/utils/interfaces.ts | 1 + 13 files changed, 232 insertions(+), 120 deletions(-) create mode 100644 src/assets/svgs/date.svg create mode 100644 src/assets/svgs/location.svg create mode 100644 src/assets/svgs/user.svg diff --git a/src/GraphQl/Queries/Queries.ts b/src/GraphQl/Queries/Queries.ts index fccad7d88e..14b2cf4249 100644 --- a/src/GraphQl/Queries/Queries.ts +++ b/src/GraphQl/Queries/Queries.ts @@ -567,6 +567,7 @@ export const ORGANIZATION_POST_LIST = gql` lastName email } + createdAt } } `; @@ -594,7 +595,7 @@ export const ORGANIZATION_POST_CONNECTION_LIST = gql` lastName email } - pinned + createdAt likeCount commentCount comments { @@ -611,7 +612,6 @@ export const ORGANIZATION_POST_CONNECTION_LIST = gql` } text } - createdAt likedBy { _id firstName diff --git a/src/assets/svgs/date.svg b/src/assets/svgs/date.svg new file mode 100644 index 0000000000..9baf0768c4 --- /dev/null +++ b/src/assets/svgs/date.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/location.svg b/src/assets/svgs/location.svg new file mode 100644 index 0000000000..b75f616dd6 --- /dev/null +++ b/src/assets/svgs/location.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/user.svg b/src/assets/svgs/user.svg new file mode 100644 index 0000000000..b23b34481e --- /dev/null +++ b/src/assets/svgs/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/OrganizationDashCards/CardItem.module.css b/src/components/OrganizationDashCards/CardItem.module.css index e90a6d3655..0330411b0c 100644 --- a/src/components/OrganizationDashCards/CardItem.module.css +++ b/src/components/OrganizationDashCards/CardItem.module.css @@ -45,3 +45,16 @@ font-size: 0.9rem; color: var(--bs-secondary); } + +.cardItem .creator { + font-size: 1rem; + color: rgb(33, 208, 21); +} + +.rightCard { + display: flex; + gap: 5px; + min-width: 170px; + justify-content: center; + flex-direction: column; +} diff --git a/src/components/OrganizationDashCards/CardItem.test.tsx b/src/components/OrganizationDashCards/CardItem.test.tsx index 6841fe9659..2102e86f94 100644 --- a/src/components/OrganizationDashCards/CardItem.test.tsx +++ b/src/components/OrganizationDashCards/CardItem.test.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import CardItem from './CardItem'; import type { InterfaceCardItem } from './CardItem'; +import dayjs from 'dayjs'; describe('Testing the Organization Card', () => { test('should render props and text elements For event card', () => { @@ -14,7 +15,9 @@ describe('Testing the Organization Card', () => { render(); expect(screen.getByText(/Event Title/i)).toBeInTheDocument(); - expect(screen.getByText(/03-09-2023/i)).toBeInTheDocument(); + expect( + screen.getByText(dayjs(props.time).format('MMM D, YYYY')) + ).toBeInTheDocument(); }); test('Should render props and text elements for Post card', () => { @@ -27,7 +30,9 @@ describe('Testing the Organization Card', () => { render(); expect(screen.getByText(/Post Title/i)).toBeInTheDocument(); - expect(screen.getByText(/03-09-2023/i)).toBeInTheDocument(); + expect( + screen.getByText(dayjs(props.time).format('MMM D, YYYY')) + ).toBeInTheDocument(); }); test('Should render props and text elements for Membership Request card', () => { diff --git a/src/components/OrganizationDashCards/CardItem.tsx b/src/components/OrganizationDashCards/CardItem.tsx index 4843d421c5..bcaaea68c5 100644 --- a/src/components/OrganizationDashCards/CardItem.tsx +++ b/src/components/OrganizationDashCards/CardItem.tsx @@ -1,6 +1,9 @@ import React from 'react'; import { ReactComponent as EventsIcon } from 'assets/svgs/events.svg'; import { ReactComponent as PostsIcon } from 'assets/svgs/post.svg'; +import { ReactComponent as MarkerIcon } from 'assets/svgs/location.svg'; +import { ReactComponent as DateIcon } from 'assets/svgs/date.svg'; +import { ReactComponent as UserIcon } from 'assets/svgs/user.svg'; import dayjs from 'dayjs'; import styles from './CardItem.module.css'; import { PersonAddAlt1Rounded } from '@mui/icons-material'; @@ -9,10 +12,12 @@ export interface InterfaceCardItem { type: 'Event' | 'Post' | 'MembershipRequest'; title: string; time?: string; + creator?: any; + location?: string; } const cardItem = (props: InterfaceCardItem): JSX.Element => { - const { type, title, time } = props; + const { creator, type, title, time, location } = props; return ( <>
@@ -33,13 +38,48 @@ const cardItem = (props: InterfaceCardItem): JSX.Element => { )}
{`${title}`} - {time ? ( - - {dayjs(time).format('DD-MM-YYYY')} - - ) : ( - '' - )} + +
+ {creator && ( + + {' '} + {' '} + + {creator.firstName} {creator.lastName} + + + )} + + {location && ( + + {' '} + {location} + + )} + {time && ( + + {type === 'Event' && ( + + )}{' '} + {dayjs(time).format('MMM D, YYYY')} + + )} +
); diff --git a/src/screens/OrgPost/OrgPost.test.tsx b/src/screens/OrgPost/OrgPost.test.tsx index 93f603d446..85dfc03edc 100644 --- a/src/screens/OrgPost/OrgPost.test.tsx +++ b/src/screens/OrgPost/OrgPost.test.tsx @@ -33,7 +33,7 @@ const MOCKS = [ { _id: '6411e53835d7ba2344a78e21', title: 'postone', - text: 'THis is the frist post', + text: 'This is the first post', imageUrl: null, videoUrl: null, createdAt: '2023-08-24T09:26:56.524+00:00', @@ -52,7 +52,7 @@ const MOCKS = [ { _id: '6411e54835d7ba2344a78e29', title: 'posttwo', - text: 'THis is the post two', + text: 'Tis is the post two', imageUrl: null, videoUrl: null, createdAt: '2023-08-24T09:26:56.524+00:00', @@ -133,7 +133,7 @@ describe('Organisation Post Page', () => { expect(dataQuery1).toEqual({ _id: '6411e53835d7ba2344a78e21', title: 'postone', - text: 'THis is the frist post', + text: 'This is the first post', imageUrl: null, videoUrl: null, createdAt: '2023-08-24T09:26:56.524+00:00', diff --git a/src/screens/OrganizationDashboard/OrganizationDashboard.test.tsx b/src/screens/OrganizationDashboard/OrganizationDashboard.test.tsx index f1560ee4f0..a54a5fd421 100644 --- a/src/screens/OrganizationDashboard/OrganizationDashboard.test.tsx +++ b/src/screens/OrganizationDashboard/OrganizationDashboard.test.tsx @@ -11,7 +11,6 @@ import { StaticMockLink } from 'utils/StaticMockLink'; import OrganizationDashboard from './OrganizationDashboard'; import { EMPTY_MOCKS, ERROR_MOCKS, MOCKS } from './OrganizationDashboardMocks'; import i18nForTest from 'utils/i18nForTest'; -import dayjs from 'dayjs'; import { toast } from 'react-toastify'; import userEvent from '@testing-library/user-event'; @@ -75,17 +74,9 @@ describe('Organisation Dashboard Page', () => { expect(screen.getByText('Upcoming Events')).toBeInTheDocument(); expect(screen.getByText('Latest Posts')).toBeInTheDocument(); expect(screen.getByText('Membership requests')).toBeInTheDocument(); - expect(screen.getAllByText('View All')).toHaveLength(3); - // Checking if events are rendered - expect(screen.getByText('Event 1')).toBeInTheDocument(); - expect( - screen.getByText( - `${dayjs(new Date()).add(1, 'day').format('DD-MM-YYYY')}` - ) - ).toBeInTheDocument(); // Checking if posts are rendered - expect(screen.getByText('Post 1')).toBeInTheDocument(); + expect(screen.getByText('Post 15')).toBeInTheDocument(); // Checking if membership requests are rendered expect(screen.getByText('Jane Doe')).toBeInTheDocument(); diff --git a/src/screens/OrganizationDashboard/OrganizationDashboard.tsx b/src/screens/OrganizationDashboard/OrganizationDashboard.tsx index 27ab4a4e98..a6551fd84b 100644 --- a/src/screens/OrganizationDashboard/OrganizationDashboard.tsx +++ b/src/screens/OrganizationDashboard/OrganizationDashboard.tsx @@ -7,8 +7,8 @@ import { useTranslation } from 'react-i18next'; import { ORGANIZATIONS_LIST, - ORGANIZATION_EVENT_LIST, - ORGANIZATION_POST_LIST, + ORGANIZATION_POST_CONNECTION_LIST, + ORGANIZATION_EVENT_CONNECTION_LIST, } from 'GraphQl/Queries/Queries'; import { ReactComponent as AdminsIcon } from 'assets/svgs/admin.svg'; import { ReactComponent as BlockedUsersIcon } from 'assets/svgs/blockedUser.svg'; @@ -22,7 +22,6 @@ import CardItem from 'components/OrganizationDashCards/CardItem'; import type { ApolloError } from '@apollo/client'; import type { InterfaceQueryOrganizationEventListItem, - InterfaceQueryOrganizationPostListItem, InterfaceQueryOrganizationsListObject, } from 'utils/interfaces'; import { toast } from 'react-toastify'; @@ -57,15 +56,7 @@ function organizationDashboard(): JSX.Element { data: postData, loading: loadingPost, error: errorPost, - }: { - data: - | { - postsByOrganization: InterfaceQueryOrganizationPostListItem[]; - } - | undefined; - loading: boolean; - error?: ApolloError; - } = useQuery(ORGANIZATION_POST_LIST, { + } = useQuery(ORGANIZATION_POST_CONNECTION_LIST, { variables: { id: currentUrl }, }); @@ -74,22 +65,20 @@ function organizationDashboard(): JSX.Element { loading: loadingEvent, error: errorEvent, }: { - data: - | { - eventsByOrganization: InterfaceQueryOrganizationEventListItem[]; - } - | undefined; + data: any; loading: boolean; error?: ApolloError; - } = useQuery(ORGANIZATION_EVENT_LIST, { - variables: { id: currentUrl }, + } = useQuery(ORGANIZATION_EVENT_CONNECTION_LIST, { + variables: { + organization_id: currentUrl, + }, }); // UseEffect to update upcomingEvents array useEffect(() => { - if (eventData && eventData?.eventsByOrganization.length > 0) { + if (eventData && eventData?.eventsByOrganizationConnection.length > 0) { const tempUpcomingEvents: InterfaceQueryOrganizationEventListItem[] = []; - eventData?.eventsByOrganization.map((event) => { + eventData?.eventsByOrganizationConnection.map((event: any) => { const startDate = new Date(event.startDate); const now = new Date(); if (startDate > now) { @@ -98,11 +87,12 @@ function organizationDashboard(): JSX.Element { }); setUpcomingEvents(tempUpcomingEvents); } - }, [eventData?.eventsByOrganization]); + }, [eventData?.eventsByOrganizationConnection]); if (errorOrg || errorPost || errorEvent) { window.location.replace('/orglist'); } + return ( <> @@ -136,14 +126,16 @@ function organizationDashboard(): JSX.Element { } /> } /> @@ -192,16 +184,19 @@ function organizationDashboard(): JSX.Element {
{t('noUpcomingEvents')}
) : ( - upcomingEvents.slice(0, 5).map((event) => { - return ( - - ); - }) + upcomingEvents.map( + (event: InterfaceQueryOrganizationEventListItem) => { + return ( + + ); + } + ) )} @@ -226,20 +221,27 @@ function organizationDashboard(): JSX.Element { [...Array(4)].map((_, index) => { return ; }) - ) : postData?.postsByOrganization?.length == 0 ? ( + ) : postData?.postsByOrganizationConnection.edges.length == + 0 ? ( + /* eslint-disable */
{t('noPostsPresent')}
) : ( - postData?.postsByOrganization.slice(0, 5).map((post) => { - return ( - - ); - }) + /* eslint-enable */ + postData?.postsByOrganizationConnection.edges + .slice(0, 5) + .map((post: any) => { + return ( + + ); + }) )} diff --git a/src/screens/OrganizationDashboard/OrganizationDashboardMocks.ts b/src/screens/OrganizationDashboard/OrganizationDashboardMocks.ts index f1672c03ca..dc1f158709 100644 --- a/src/screens/OrganizationDashboard/OrganizationDashboardMocks.ts +++ b/src/screens/OrganizationDashboard/OrganizationDashboardMocks.ts @@ -1,7 +1,7 @@ import { ORGANIZATIONS_LIST, - ORGANIZATION_EVENT_LIST, - ORGANIZATION_POST_LIST, + ORGANIZATION_EVENT_CONNECTION_LIST, + ORGANIZATION_POST_CONNECTION_LIST, } from 'GraphQl/Queries/Queries'; import dayjs from 'dayjs'; @@ -26,7 +26,6 @@ export const MOCKS = [ lastName: '', email: '', }, - members: [ { _id: '123', @@ -68,59 +67,114 @@ export const MOCKS = [ }, { request: { - query: ORGANIZATION_POST_LIST, + query: ORGANIZATION_POST_CONNECTION_LIST, }, result: { data: { - postsByOrganization: [ - { - _id: 1, - title: 'Post 1', - text: 'Test Post', - imageUrl: '', - videoUrl: '', - creator: { - _id: '583', - firstName: 'John', - lastName: 'Doe', - email: 'johndoe@gmail.com', + postsByOrganizationConnection: { + edges: [ + { + _id: '6411e53835d7ba2344a78e21', + title: 'Post 15', + text: 'This is the first post that was made', + imageUrl: null, + videoUrl: null, + creator: { + _id: '640d98d9eb6a743d75341067', + firstName: 'Aditya', + lastName: 'Shelke', + email: 'adidacreator1@gmail.com', + }, + createdAt: dayjs(new Date()).add(1, 'day'), + likeCount: 0, + commentCount: 0, + comments: [], + likedBy: [], + pinned: false, }, - }, - ], + { + _id: '6411e54835d7ba2344a78e29', + title: 'Post 2', + text: 'Hey, anyone saw my watch that I left at the office?', + imageUrl: null, + videoUrl: null, + creator: { + _id: '640d98d9eb6a743d75341067', + firstName: 'Aditya', + lastName: 'Shelke', + email: 'adidacreator1@gmail.com', + }, + pinned: false, + createdAt: dayjs(new Date()).add(1, 'day'), + likeCount: 0, + commentCount: 2, + comments: [ + { + _id: '64eb13beca85de60ebe0ed0e', + creator: { + _id: '63d6064458fce20ee25c3bf7', + firstName: 'Noble', + lastName: 'Mittal', + email: 'test@gmail.com', + __typename: 'User', + }, + likeCount: 1, + likedBy: [ + { + _id: 1, + }, + ], + text: 'Yes, that is $50', + __typename: 'Comment', + }, + { + _id: '64eb483aca85de60ebe0ef99', + creator: { + _id: '63d6064458fce20ee25c3bf7', + firstName: 'Noble', + lastName: 'Mittal', + email: 'test@gmail.com', + __typename: 'User', + }, + likeCount: 0, + likedBy: [], + text: 'Great View', + __typename: 'Comment', + }, + ], + likedBy: [ + { + _id: '63d6064458fce20ee25c3bf7', + firstName: 'Comment', + lastName: 'Likkert', + }, + ], + }, + ], + }, }, }, }, { request: { - query: ORGANIZATION_EVENT_LIST, + query: ORGANIZATION_EVENT_CONNECTION_LIST, + variables: { + organization_id: '123', + }, }, result: { data: { - eventsByOrganization: [ - { - _id: 1, - title: 'Event 1', - description: 'Event Test', - startDate: dayjs(new Date()).add(1, 'day'), - endDate: dayjs(new Date()).add(3, 'day'), - location: 'New Delhi', - startTime: '', - endTime: '', - allDay: true, - recurring: false, - isPublic: true, - isRegisterable: true, - }, + eventsByOrganizationConnection: [ { - _id: 2, - title: 'Event 2', - description: 'Event Test', - startDate: dayjs(new Date()), - endDate: dayjs(new Date()).add(1, 'day'), - location: 'Jamaica', - startTime: '', - endTime: '', - allDay: true, + _id: '1', + title: 'Sample Event', + description: 'Sample Description', + startDate: '2023-10-29T00:00:00.000Z', + endDate: '2023-10-29T23:59:59.000Z', + location: 'Sample Location', + startTime: '08:00:00', + endTime: '17:00:00', + allDay: false, recurring: false, isPublic: true, isRegisterable: true, @@ -184,21 +238,23 @@ export const EMPTY_MOCKS = [ }, { request: { - query: ORGANIZATION_POST_LIST, + query: ORGANIZATION_POST_CONNECTION_LIST, }, result: { data: { - postsByOrganization: [], + postsByOrganizationConnection: { + edges: [], + }, }, }, }, { request: { - query: ORGANIZATION_EVENT_LIST, + query: ORGANIZATION_EVENT_CONNECTION_LIST, }, result: { data: { - eventsByOrganization: [], + eventsByOrganizationConnection: [], }, }, }, @@ -213,13 +269,13 @@ export const ERROR_MOCKS = [ }, { request: { - query: ORGANIZATION_POST_LIST, + query: ORGANIZATION_POST_CONNECTION_LIST, }, error: new Error('Mock Graphql ORGANIZATION_POST_LIST Error'), }, { request: { - query: ORGANIZATION_EVENT_LIST, + query: ORGANIZATION_EVENT_CONNECTION_LIST, }, error: new Error('Mock Graphql ORGANIZATION_EVENT_LIST Error'), }, diff --git a/src/screens/UserPortal/Home/Home.test.tsx b/src/screens/UserPortal/Home/Home.test.tsx index f4ca4b64ba..105714cfc8 100644 --- a/src/screens/UserPortal/Home/Home.test.tsx +++ b/src/screens/UserPortal/Home/Home.test.tsx @@ -14,6 +14,7 @@ import userEvent from '@testing-library/user-event'; import * as getOrganizationId from 'utils/getOrganizationId'; import { CREATE_POST_MUTATION } from 'GraphQl/Mutations/mutations'; import { toast } from 'react-toastify'; +import dayjs from 'dayjs'; jest.mock('react-toastify', () => ({ toast: { @@ -47,12 +48,12 @@ const MOCKS = [ lastName: 'Shelke', email: 'adidacreator1@gmail.com', }, + createdAt: dayjs(new Date()).add(1, 'day'), likeCount: 0, commentCount: 0, comments: [], likedBy: [], pinned: false, - createdAt: '2023-02-18T09:22:27.969Z', }, { _id: '6411e54835d7ba2344a78e29', @@ -66,9 +67,9 @@ const MOCKS = [ lastName: 'Shelke', email: 'adidacreator1@gmail.com', }, + createdAt: dayjs(new Date()).add(1, 'day'), likeCount: 0, commentCount: 2, - createdAt: '2023-02-18T09:22:27.969Z', comments: [ { _id: '64eb13beca85de60ebe0ed0e', diff --git a/src/utils/interfaces.ts b/src/utils/interfaces.ts index 1a41e91dfb..e90711028f 100644 --- a/src/utils/interfaces.ts +++ b/src/utils/interfaces.ts @@ -82,6 +82,7 @@ export interface InterfaceQueryOrganizationPostListItem { text: string; imageUrl: null; videoUrl: null; + createdAt: string; creator: { _id: string; firstName: string;