From b512b1980450a5fe3dce9e16799c0961bc21f2db Mon Sep 17 00:00:00 2001 From: MTG2000 Date: Thu, 1 Sep 2022 13:26:44 +0300 Subject: [PATCH] feat: event card, event modal --- api/functions/graphql/nexus-typegen.ts | 7 ++- api/functions/graphql/schema.graphql | 8 ++- api/functions/graphql/types/tournament.js | 15 ++++- .../pages/EventsPage/EventCard/EventCard.tsx | 45 +++++++++++-- .../EventsPage/EventModal/EventModal.tsx | 63 +++++++++++++++++++ .../pages/EventsPage/EventModal/index.tsx | 6 ++ .../pages/EventsPage/EventsPage.tsx | 2 +- .../Navigation/Navigation.tsx | 2 +- src/graphql/index.tsx | 10 ++- src/mocks/data/tournament.ts | 14 ++--- src/redux/features/modals.slice.ts | 10 ++- 11 files changed, 159 insertions(+), 23 deletions(-) create mode 100644 src/features/Tournaments/pages/EventsPage/EventModal/EventModal.tsx create mode 100644 src/features/Tournaments/pages/EventsPage/EventModal/index.tsx diff --git a/api/functions/graphql/nexus-typegen.ts b/api/functions/graphql/nexus-typegen.ts index b5d78da..44f453f 100644 --- a/api/functions/graphql/nexus-typegen.ts +++ b/api/functions/graphql/nexus-typegen.ts @@ -69,6 +69,7 @@ export interface NexusGenInputs { export interface NexusGenEnums { POST_TYPE: "Bounty" | "Question" | "Story" RoleLevelEnum: 3 | 0 | 1 | 2 | 4 + TournamentEventTypeEnum: 2 | 0 | 1 VOTE_ITEM_TYPE: "Bounty" | "PostComment" | "Project" | "Question" | "Story" | "User" } @@ -261,7 +262,7 @@ export interface NexusGenObjects { links: string[]; // [String!]! location: string; // String! title: string; // String! - type: string; // String! + type: NexusGenEnums['TournamentEventTypeEnum']; // TournamentEventTypeEnum! website: string; // String! } TournamentFAQ: { // root type @@ -562,7 +563,7 @@ export interface NexusGenFieldTypes { links: string[]; // [String!]! location: string; // String! title: string; // String! - type: string; // String! + type: NexusGenEnums['TournamentEventTypeEnum']; // TournamentEventTypeEnum! website: string; // String! } TournamentFAQ: { // field return type @@ -886,7 +887,7 @@ export interface NexusGenFieldTypeNames { links: 'String' location: 'String' title: 'String' - type: 'String' + type: 'TournamentEventTypeEnum' website: 'String' } TournamentFAQ: { // field return type name diff --git a/api/functions/graphql/schema.graphql b/api/functions/graphql/schema.graphql index 0a8c099..2944fcc 100644 --- a/api/functions/graphql/schema.graphql +++ b/api/functions/graphql/schema.graphql @@ -351,10 +351,16 @@ type TournamentEvent { links: [String!]! location: String! title: String! - type: String! + type: TournamentEventTypeEnum! website: String! } +enum TournamentEventTypeEnum { + IRLMeetup + TwitterSpace + Workshop +} + type TournamentFAQ { answer: String! question: String! diff --git a/api/functions/graphql/types/tournament.js b/api/functions/graphql/types/tournament.js index c60de12..6952ff8 100644 --- a/api/functions/graphql/types/tournament.js +++ b/api/functions/graphql/types/tournament.js @@ -4,6 +4,7 @@ const { stringArg, extendType, nonNull, + enumType, } = require('nexus'); const { prisma } = require('../../../prisma'); @@ -35,6 +36,18 @@ const TournamentFAQ = objectType({ } }) + + +const TournamentEventTypeEnum = enumType({ + name: 'TournamentEventTypeEnum', + members: { + TwitterSpace: 0, + Workshop: 1, + IRLMeetup: 2, + }, +}); + + const TournamentEvent = objectType({ name: 'TournamentEvent', definition(t) { @@ -45,7 +58,7 @@ const TournamentEvent = objectType({ t.nonNull.date('date'); t.nonNull.string('location'); t.nonNull.string('website'); - t.nonNull.string('type'); + t.nonNull.field('type', { type: TournamentEventTypeEnum }) t.nonNull.list.nonNull.string('links'); } }) diff --git a/src/features/Tournaments/pages/EventsPage/EventCard/EventCard.tsx b/src/features/Tournaments/pages/EventsPage/EventCard/EventCard.tsx index 54c478f..07f74de 100644 --- a/src/features/Tournaments/pages/EventsPage/EventCard/EventCard.tsx +++ b/src/features/Tournaments/pages/EventsPage/EventCard/EventCard.tsx @@ -4,8 +4,10 @@ import dayjs from "dayjs"; import advancedFormat from 'dayjs/plugin/advancedFormat' import { trimText } from "src/utils/helperFunctions"; import { Override } from "src/utils/interfaces"; -import { Tag, Tournament } from "src/graphql"; -dayjs.extend(advancedFormat) +import { Tag, Tournament, TournamentEventTypeEnum } from "src/graphql"; +import { UnionToObjectKeys } from 'src/utils/types/utils'; +import { useAppDispatch, } from "src/utils/hooks"; +import { openModal } from "src/redux/features/modals.slice"; interface Props { @@ -22,8 +24,25 @@ interface Props { } export default function EventCard({ event }: Props) { + + const dispatch = useAppDispatch() + + const openEventModal = () => { + dispatch(openModal({ + Modal: "EventModal", + isPageModal: true, + props: { + event + } + })) + } + return ( -
+
@@ -34,13 +53,31 @@ export default function EventCard({ event }: Props) { {event.date}

- {event.location} + {event.location}

{trimText(event.description, 90)}

+ + {mapTypeToBadge[event.type].text} +
) } + +export const mapTypeToBadge: UnionToObjectKeys = { + [TournamentEventTypeEnum.TwitterSpace]: { + text: "🐦 Twitter space", + color: "bg-blue-50 text-blue-500" + }, + [TournamentEventTypeEnum.Workshop]: { + text: "🛠️ Workshop", + color: "bg-green-50 text-green-500" + }, + [TournamentEventTypeEnum.IrlMeetup]: { + text: "🤝 IRL meetup", + color: "bg-red-50 text-red-500" + }, +} diff --git a/src/features/Tournaments/pages/EventsPage/EventModal/EventModal.tsx b/src/features/Tournaments/pages/EventsPage/EventModal/EventModal.tsx new file mode 100644 index 0000000..0151bf8 --- /dev/null +++ b/src/features/Tournaments/pages/EventsPage/EventModal/EventModal.tsx @@ -0,0 +1,63 @@ + +import { MdClose, } from 'react-icons/md'; +import { ModalCard } from 'src/Components/Modals/ModalsContainer/ModalsContainer'; +import { useMediaQuery } from 'src/utils/hooks'; +import { Tournament, } from 'src/graphql'; +import { MEDIA_QUERIES } from 'src/utils/theme'; +import { IoGlobe, IoLocationOutline } from 'react-icons/io5'; +import { mapTypeToBadge } from '../EventCard/EventCard'; + + +interface Props extends ModalCard { + event: Pick +} + +export default function ProjectDetailsCard({ direction, event, ...props }: Props) { + + const closeModal = () => { + props.onClose?.(); + } + + + const isMdScreen = useMediaQuery(MEDIA_QUERIES.isMedium) + + return ( +
+
+ + + + {mapTypeToBadge[event.type].text} + +
+
+

{event.title}

+

+ {event.date} +

+
+

+ {event.location} +

+

+ + {event.website} +

+
+

+ {event.description} +

+
+
+ ) +} diff --git a/src/features/Tournaments/pages/EventsPage/EventModal/index.tsx b/src/features/Tournaments/pages/EventsPage/EventModal/index.tsx new file mode 100644 index 0000000..26ef497 --- /dev/null +++ b/src/features/Tournaments/pages/EventsPage/EventModal/index.tsx @@ -0,0 +1,6 @@ + +import { lazyModal } from 'src/utils/helperFunctions'; + + + +export const { LazyComponent: EventModal, preload: projectDetailsCardPreload } = lazyModal(() => import('./EventModal')) diff --git a/src/features/Tournaments/pages/EventsPage/EventsPage.tsx b/src/features/Tournaments/pages/EventsPage/EventsPage.tsx index 8fdcb06..36b7cec 100644 --- a/src/features/Tournaments/pages/EventsPage/EventsPage.tsx +++ b/src/features/Tournaments/pages/EventsPage/EventsPage.tsx @@ -10,7 +10,7 @@ interface Props { export default function EventsPage({ data: { events, events_count } }: Props) { return ( -
+

Events 📆 ({events_count})

{ diff --git a/src/features/Tournaments/pages/TournamentDetailsPage/Navigation/Navigation.tsx b/src/features/Tournaments/pages/TournamentDetailsPage/Navigation/Navigation.tsx index a359a78..97c1757 100644 --- a/src/features/Tournaments/pages/TournamentDetailsPage/Navigation/Navigation.tsx +++ b/src/features/Tournaments/pages/TournamentDetailsPage/Navigation/Navigation.tsx @@ -42,7 +42,7 @@ export default function Navigation({ data }: Props) { ], [data.events_count, data.makers_count, data.projects_count]) return ( -
+
diff --git a/src/graphql/index.tsx b/src/graphql/index.tsx index 7a8f40c..0870f54 100644 --- a/src/graphql/index.tsx +++ b/src/graphql/index.tsx @@ -521,10 +521,16 @@ export type TournamentEvent = { links: Array; location: Scalars['String']; title: Scalars['String']; - type: Scalars['String']; + type: TournamentEventTypeEnum; website: Scalars['String']; }; +export enum TournamentEventTypeEnum { + IrlMeetup = 'IRLMeetup', + TwitterSpace = 'TwitterSpace', + Workshop = 'Workshop' +} + export type TournamentFaq = { __typename?: 'TournamentFAQ'; answer: Scalars['String']; @@ -787,7 +793,7 @@ export type GetTournamentByIdQueryVariables = Exact<{ }>; -export type GetTournamentByIdQuery = { __typename?: 'Query', getTournamentById: { __typename?: 'Tournament', id: number, title: string, description: string, thumbnail_image: string, cover_image: string, start_date: any, end_date: any, location: string, website: string, events_count: number, makers_count: number, projects_count: number, prizes: Array<{ __typename?: 'TournamentPrize', title: string, amount: string, image: string }>, judges: Array<{ __typename?: 'TournamentJudge', name: string, jobTitle: string, avatar: string }>, events: Array<{ __typename?: 'TournamentEvent', id: number, title: string, image: string, description: string, date: any, location: string, website: string, type: string, links: Array }>, faqs: Array<{ __typename?: 'TournamentFAQ', question: string, answer: string }> } }; +export type GetTournamentByIdQuery = { __typename?: 'Query', getTournamentById: { __typename?: 'Tournament', id: number, title: string, description: string, thumbnail_image: string, cover_image: string, start_date: any, end_date: any, location: string, website: string, events_count: number, makers_count: number, projects_count: number, prizes: Array<{ __typename?: 'TournamentPrize', title: string, amount: string, image: string }>, judges: Array<{ __typename?: 'TournamentJudge', name: string, jobTitle: string, avatar: string }>, events: Array<{ __typename?: 'TournamentEvent', id: number, title: string, image: string, description: string, date: any, location: string, website: string, type: TournamentEventTypeEnum, links: Array }>, faqs: Array<{ __typename?: 'TournamentFAQ', question: string, answer: string }> } }; export type VoteMutationVariables = Exact<{ itemType: Vote_Item_Type; diff --git a/src/mocks/data/tournament.ts b/src/mocks/data/tournament.ts index c735487..e96172d 100644 --- a/src/mocks/data/tournament.ts +++ b/src/mocks/data/tournament.ts @@ -1,4 +1,4 @@ -import { Tournament } from "src/graphql"; +import { Tournament, TournamentEventTypeEnum } from "src/graphql"; import { getCoverImage } from "./utils"; export const tournaments: Tournament[] = [{ @@ -50,7 +50,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Semper turpis est, ac e image: getCoverImage(), links: [], location: "Online", - type: "🐦 Twitter space", + type: TournamentEventTypeEnum.TwitterSpace, website: "https://event.name" }, { @@ -61,7 +61,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Semper turpis est, ac e image: getCoverImage(), links: [], location: "Online", - type: "🛠 Workshop", + type: TournamentEventTypeEnum.Workshop, website: "https://event.name" }, { @@ -72,7 +72,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Semper turpis est, ac e image: getCoverImage(), links: [], location: "Online", - type: "🤝 IRL meetup", + type: TournamentEventTypeEnum.IrlMeetup, website: "https://event.name" }, { @@ -83,7 +83,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Semper turpis est, ac e image: getCoverImage(), links: [], location: "Online", - type: "🛠 Workshop", + type: TournamentEventTypeEnum.Workshop, website: "https://event.name" }, @@ -95,7 +95,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Semper turpis est, ac e image: getCoverImage(), links: [], location: "Online", - type: "🛠 Workshop", + type: TournamentEventTypeEnum.Workshop, website: "https://event.name" }, @@ -107,7 +107,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Semper turpis est, ac e image: getCoverImage(), links: [], location: "Online", - type: "🛠 Workshop", + type: TournamentEventTypeEnum.Workshop, website: "https://event.name" }, ], diff --git a/src/redux/features/modals.slice.ts b/src/redux/features/modals.slice.ts index f4e547e..d3e58ed 100644 --- a/src/redux/features/modals.slice.ts +++ b/src/redux/features/modals.slice.ts @@ -14,6 +14,7 @@ import { LinkingAccountModal } from "src/features/Profiles/pages/EditProfilePage import { ComponentProps } from "react"; import { generateId } from "src/utils/helperFunctions"; import { NoWeblnModal } from "src/Components/Modals/NoWeblnModal"; +import { EventModal } from "src/features/Tournaments/pages/EventsPage/EventModal"; export enum Direction { START, @@ -38,6 +39,9 @@ export const ALL_MODALS = { Claim_SubmittedCard, Claim_FundWithdrawCard, + // Tournaments + EventModal: EventModal, + // Misc ConfirmModal, VoteCard, @@ -63,9 +67,9 @@ type NonNullableObject = { type ModalAction = U extends any ? {} extends NonNullableObject> ? - { Modal: U } + { Modal: U, isPageModal?: boolean, } : - { Modal: U, props: ModalProps } + { Modal: U, isPageModal?: boolean, props: ModalProps } : never; @@ -134,7 +138,7 @@ export const modalSlice = createSlice({ state.isOpen = true; let props: any = {}; - props.isPageModal = action.payload.Modal === 'ProjectDetailsCard'; + props.isPageModal = action.payload.isPageModal; if ('props' in action.payload) props = { ...props, ...action.payload.props }