From 08222b9935ef4509e9cfc9b928faff28c74d7beb Mon Sep 17 00:00:00 2001 From: MTG2000 Date: Sun, 22 May 2022 13:23:37 +0300 Subject: [PATCH] feat: Hackathons page, hackathons filter, hackathons mocks api --- functions/graphql/nexus-typegen.ts | 38 ++++++ functions/graphql/schema.graphql | 13 ++ functions/graphql/types/hackathon.js | 42 +++++-- functions/graphql/types/index.js | 4 +- src/App.tsx | 2 + src/Components/Navbar/Navbar.tsx | 8 ++ .../HackathonCard/HackathonCard.tsx | 12 +- .../Components/SortByFilter/SortByFilter.tsx | 18 ++- .../Components/TopicsFilter/TopicsFilter.tsx | 73 +++++------ .../Components/TopicsFilter/allTopics.graphql | 7 ++ .../HackathonsPage/HackathonsPage.stories.tsx | 20 +++ .../pages/HackathonsPage/HackathonsPage.tsx | 30 +++-- .../HackathonsPage/allHackathons.graphql | 17 +++ .../pages/HackathonsPage/styles.module.scss | 7 +- .../Hackathons/types/hackathons.interface.ts | 16 +-- .../PopularTopicsFilter.tsx | 27 +--- .../Posts/pages/FeedPage/SortBy/SortBy.tsx | 6 +- src/graphql/index.tsx | 117 ++++++++++++++++++ src/mocks/data/hackathon.ts | 33 +++-- src/mocks/handlers.ts | 26 +++- src/mocks/resolvers.ts | 5 + src/redux/features/wallet.slice.ts | 3 +- src/utils/helperFunctions.tsx | 2 - src/utils/hooks/useInfiniteQuery.ts | 1 - 24 files changed, 392 insertions(+), 135 deletions(-) create mode 100644 src/features/Hackathons/Components/TopicsFilter/allTopics.graphql create mode 100644 src/features/Hackathons/pages/HackathonsPage/HackathonsPage.stories.tsx create mode 100644 src/features/Hackathons/pages/HackathonsPage/allHackathons.graphql diff --git a/functions/graphql/nexus-typegen.ts b/functions/graphql/nexus-typegen.ts index fe39635..f97c0c8 100644 --- a/functions/graphql/nexus-typegen.ts +++ b/functions/graphql/nexus-typegen.ts @@ -76,6 +76,16 @@ export interface NexusGenObjects { id: number; // Int! title: string; // String! } + Hackathon: { // root type + cover_image: string; // String! + description: string; // String! + end_date: NexusGenScalars['Date']; // Date! + id: number; // Int! + location: string; // String! + start_date: NexusGenScalars['Date']; // Date! + title: string; // String! + website: string; // String! + } LnurlDetails: { // root type commentAllowed?: number | null; // Int maxSendable?: number | null; // Int @@ -198,6 +208,17 @@ export interface NexusGenFieldTypes { title: string; // String! votes_sum: number; // Int! } + Hackathon: { // field return type + cover_image: string; // String! + description: string; // String! + end_date: NexusGenScalars['Date']; // Date! + id: number; // Int! + location: string; // String! + start_date: NexusGenScalars['Date']; // Date! + title: string; // String! + topics: NexusGenRootTypes['Topic'][]; // [Topic!]! + website: string; // String! + } LnurlDetails: { // field return type commentAllowed: number | null; // Int maxSendable: number | null; // Int @@ -235,6 +256,7 @@ export interface NexusGenFieldTypes { allCategories: NexusGenRootTypes['Category'][]; // [Category!]! allProjects: NexusGenRootTypes['Project'][]; // [Project!]! allTopics: NexusGenRootTypes['Topic'][]; // [Topic!]! + getAllHackathons: NexusGenRootTypes['Hackathon'][]; // [Hackathon!]! getCategory: NexusGenRootTypes['Category']; // Category! getFeed: NexusGenRootTypes['Post'][]; // [Post!]! getLnurlDetailsForProject: NexusGenRootTypes['LnurlDetails']; // LnurlDetails! @@ -347,6 +369,17 @@ export interface NexusGenFieldTypeNames { title: 'String' votes_sum: 'Int' } + Hackathon: { // field return type name + cover_image: 'String' + description: 'String' + end_date: 'Date' + id: 'Int' + location: 'String' + start_date: 'Date' + title: 'String' + topics: 'Topic' + website: 'String' + } LnurlDetails: { // field return type name commentAllowed: 'Int' maxSendable: 'Int' @@ -384,6 +417,7 @@ export interface NexusGenFieldTypeNames { allCategories: 'Category' allProjects: 'Project' allTopics: 'Topic' + getAllHackathons: 'Hackathon' getCategory: 'Category' getFeed: 'Post' getLnurlDetailsForProject: 'LnurlDetails' @@ -474,6 +508,10 @@ export interface NexusGenArgTypes { skip?: number | null; // Int take: number | null; // Int } + getAllHackathons: { // args + sortBy?: string | null; // String + topic?: number | null; // Int + } getCategory: { // args id: number; // Int! } diff --git a/functions/graphql/schema.graphql b/functions/graphql/schema.graphql index 9a4a7d3..b834674 100644 --- a/functions/graphql/schema.graphql +++ b/functions/graphql/schema.graphql @@ -47,6 +47,18 @@ type Category { """Date custom scalar type""" scalar Date +type Hackathon { + cover_image: String! + description: String! + end_date: Date! + id: Int! + location: String! + start_date: Date! + title: String! + topics: [Topic!]! + website: String! +} + type LnurlDetails { commentAllowed: Int maxSendable: Int @@ -105,6 +117,7 @@ type Query { allCategories: [Category!]! allProjects(skip: Int = 0, take: Int = 50): [Project!]! allTopics: [Topic!]! + getAllHackathons(sortBy: String, topic: Int): [Hackathon!]! getCategory(id: Int!): Category! getFeed(skip: Int = 0, sortBy: String = "all", take: Int = 10, topic: Int = 0): [Post!]! getLnurlDetailsForProject(project_id: Int!): LnurlDetails! diff --git a/functions/graphql/types/hackathon.js b/functions/graphql/types/hackathon.js index ffc0f1b..74aa633 100644 --- a/functions/graphql/types/hackathon.js +++ b/functions/graphql/types/hackathon.js @@ -5,6 +5,7 @@ const { extendType, nonNull, } = require('nexus'); +const { prisma } = require('../prisma') @@ -15,13 +16,14 @@ const Hackathon = objectType({ t.nonNull.string('title'); t.nonNull.string('description'); t.nonNull.string('cover_image'); - t.nonNull.string('date'); + t.nonNull.date('start_date'); + t.nonNull.date('end_date'); t.nonNull.string('location'); t.nonNull.string('website'); t.nonNull.list.nonNull.field('topics', { type: "Topic", resolve: (parent) => { - return [] + return prisma.hackathon.findUnique({ where: { id: parent.id } }).topics(); } }); } @@ -29,15 +31,41 @@ const Hackathon = objectType({ const getAllHackathons = extendType({ type: "Query", - args: { - sortBy: stringArg(), - topic: stringArg(), - }, definition(t) { t.nonNull.list.nonNull.field('getAllHackathons', { type: "Hackathon", + args: { + sortBy: stringArg(), + topic: intArg(), + }, resolve(_, args) { - return []; + const { sortBy, topic } = args; + return prisma.hackathon.findMany({ + where: { + ...(sortBy === 'Upcoming' && { + start_date: { + gte: new Date(), + } + }), + ...(sortBy === 'Live' && { + start_date: { lte: new Date() }, + end_date: { gte: new Date() } + }), + ...(sortBy === 'Finished' && { + end_date: { + lt: new Date() + } + }), + + ...(topic && { + topics: { + some: { + id: topic + } + } + }) + } + }) } }) } diff --git a/functions/graphql/types/index.js b/functions/graphql/types/index.js index 3b97a9d..51268f1 100644 --- a/functions/graphql/types/index.js +++ b/functions/graphql/types/index.js @@ -4,6 +4,7 @@ const project = require('./project') const vote = require('./vote') const post = require('./post') const users = require('./users') +const hackathon = require('./hackathon') module.exports = { ...scalars, @@ -11,5 +12,6 @@ module.exports = { ...project, ...vote, ...post, - ...users + ...users, + ...hackathon } \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 5df2256..7b79706 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,6 +9,7 @@ import LoadingPage from "./Components/LoadingPage/LoadingPage"; // Pages const FeedPage = React.lazy(() => import("./features/Posts/pages/FeedPage/FeedPage")) +const HackathonsPage = React.lazy(() => import("./features/Hackathons/pages/HackathonsPage/HackathonsPage")) const HottestPage = React.lazy(() => import("src/features/Projects/pages/HottestPage/HottestPage")) const PostDetailsPage = React.lazy(() => import("./features/Posts/pages/PostDetailsPage/PostDetailsPage")) const CategoryPage = React.lazy(() => import("src/features/Projects/pages/CategoryPage/CategoryPage")) @@ -47,6 +48,7 @@ function App() { } /> } /> } /> + } /> } /> diff --git a/src/Components/Navbar/Navbar.tsx b/src/Components/Navbar/Navbar.tsx index df31f44..8d31332 100644 --- a/src/Components/Navbar/Navbar.tsx +++ b/src/Components/Navbar/Navbar.tsx @@ -8,6 +8,7 @@ import { setNavHeight } from "src/redux/features/ui.slice"; import NavDesktop from "./NavDesktop"; import { useMediaQuery } from "@react-hookz/web"; import { MEDIA_QUERIES } from "src/utils/theme/media_queries"; +import { IoMdTrophy } from "react-icons/io"; export const navLinks = [ @@ -18,6 +19,12 @@ export const navLinks = [ icon: MdComment, color: "text-primary-600", }, + { + text: "Hackathons", + url: "/hackathons", + icon: IoMdTrophy, + color: "text-primary-600", + }, { text: "Hottest", url: "/hottest", @@ -41,6 +48,7 @@ export default function Navbar() { })); const isLargeScreen = useMediaQuery(MEDIA_QUERIES.isLarge) + console.log(isLargeScreen, MEDIA_QUERIES.isLarge); const onConnectWallet = () => { diff --git a/src/features/Hackathons/Components/HackathonCard/HackathonCard.tsx b/src/features/Hackathons/Components/HackathonCard/HackathonCard.tsx index fc5f545..0d29b45 100644 --- a/src/features/Hackathons/Components/HackathonCard/HackathonCard.tsx +++ b/src/features/Hackathons/Components/HackathonCard/HackathonCard.tsx @@ -1,6 +1,10 @@ import { Hackathon } from "src/features/Hackathons/types" import { IoLocationOutline } from 'react-icons/io5' import Button from "src/Components/Button/Button" +import dayjs from "dayjs"; +import advancedFormat from 'dayjs/plugin/advancedFormat' +import { trimText } from "src/utils/helperFunctions"; +dayjs.extend(advancedFormat) export type HackathonCardType = Hackathon; @@ -18,20 +22,20 @@ export default function HackathonCard({ hackathon }: Props) { {hackathon.title}

- {hackathon.date} + {`${dayjs(hackathon.start_date).format('Do')} - ${dayjs(hackathon.end_date).format('Do MMMM, YYYY')}`}

{hackathon.location}

- {hackathon.description} + {trimText(hackathon.description, 110)}

- {hackathon.topics.map(topic =>
{topic.title}
)} + {hackathon.topics.map(topic =>
{topic.icon} {topic.title}
)}
- diff --git a/src/features/Hackathons/Components/SortByFilter/SortByFilter.tsx b/src/features/Hackathons/Components/SortByFilter/SortByFilter.tsx index 66ae958..f68cfcb 100644 --- a/src/features/Hackathons/Components/SortByFilter/SortByFilter.tsx +++ b/src/features/Hackathons/Components/SortByFilter/SortByFilter.tsx @@ -6,35 +6,33 @@ const filters = [ value: 'Upcoming' }, { text: "Live", - value: 'live' + value: 'Live' }, { - text: "Complete", - value: 'complete' + text: "Finished", + value: 'Finished' }, ] interface Props { - filterChanged?: (newFilter: string) => void + filterChanged?: (newFilter: string | null) => void } export default function SortByFilter({ filterChanged }: Props) { - const [selected, setSelected] = useState(filters[0].value); + const [selected, setSelected] = useState(null); - const filterClicked = (newValue: string) => { - if (selected === newValue) - return + const filterClicked = (_newValue: string) => { + const newValue = selected !== _newValue ? _newValue : null; setSelected(newValue); filterChanged?.(newValue); } - return (

Sort By

    {filters.map((f, idx) =>
  • filterClicked(f.value)} > {f.text} diff --git a/src/features/Hackathons/Components/TopicsFilter/TopicsFilter.tsx b/src/features/Hackathons/Components/TopicsFilter/TopicsFilter.tsx index 79e7155..372d2cb 100644 --- a/src/features/Hackathons/Components/TopicsFilter/TopicsFilter.tsx +++ b/src/features/Hackathons/Components/TopicsFilter/TopicsFilter.tsx @@ -1,39 +1,22 @@ -import { useState } from 'react' +import React, { useState } from 'react' +import Skeleton from 'react-loading-skeleton'; +import { useAllTopicsQuery, usePopularTopicsQuery } from 'src/graphql'; + -const filters = [ - { - text: 'Design', - value: 'Design', - icon: "🎨" - }, - { - text: 'Development', - value: 'Development', - icon: "💻" - }, - { - text: 'Startups', - value: 'Startups', - icon: "🚀" - }, - { - text: 'Lightning Network', - value: 'Lightning Network', - icon: "⚡️" - }, -] interface Props { - filterChanged?: (newFilter: string) => void + filterChanged?: (newFilter: number | null) => void } -export default function TopicsFilter({ filterChanged }: Props) { +export default function PopularTopicsFilter({ filterChanged }: Props) { - const [selected, setSelected] = useState(filters[0].value); + const [selected, setSelected] = useState(null); - const filterClicked = (newValue: string) => { - if (selected === newValue) - return + const topicsQuery = useAllTopicsQuery(); + + + const filterClicked = (_newValue: number) => { + const newValue = selected !== _newValue ? _newValue : null; setSelected(newValue); filterChanged?.(newValue); } @@ -42,16 +25,28 @@ export default function TopicsFilter({ filterChanged }: Props) {

    Topics

      - {filters.map((f, idx) =>
    • filterClicked(f.value)} - > - {f.icon} - - {f.text} - -
    • )} + {topicsQuery.loading ? + Array(4).fill(0).map((_, idx) =>
    • + + + +
    • + ) + : + topicsQuery.data?.allTopics.map((f, idx) =>
    • filterClicked(f.id)} + > + {f.icon} + + {f.title} + +
    • )}
    ) diff --git a/src/features/Hackathons/Components/TopicsFilter/allTopics.graphql b/src/features/Hackathons/Components/TopicsFilter/allTopics.graphql new file mode 100644 index 0000000..0cb6368 --- /dev/null +++ b/src/features/Hackathons/Components/TopicsFilter/allTopics.graphql @@ -0,0 +1,7 @@ +query allTopics { + allTopics { + id + title + icon + } +} diff --git a/src/features/Hackathons/pages/HackathonsPage/HackathonsPage.stories.tsx b/src/features/Hackathons/pages/HackathonsPage/HackathonsPage.stories.tsx new file mode 100644 index 0000000..c60f938 --- /dev/null +++ b/src/features/Hackathons/pages/HackathonsPage/HackathonsPage.stories.tsx @@ -0,0 +1,20 @@ +import { ComponentStory, ComponentMeta } from '@storybook/react'; + +import HackathonsPage from './HackathonsPage'; + +export default { + title: 'Hackathons/Hackathons Page/Page', + component: HackathonsPage, + argTypes: { + backgroundColor: { control: 'color' }, + }, +} as ComponentMeta; + + +const Template: ComponentStory = (args) => + +export const Default = Template.bind({}); +Default.args = { +} + + diff --git a/src/features/Hackathons/pages/HackathonsPage/HackathonsPage.tsx b/src/features/Hackathons/pages/HackathonsPage/HackathonsPage.tsx index 744d934..6d55391 100644 --- a/src/features/Hackathons/pages/HackathonsPage/HackathonsPage.tsx +++ b/src/features/Hackathons/pages/HackathonsPage/HackathonsPage.tsx @@ -1,7 +1,9 @@ import { useReducer, useState } from 'react' -import { useFeedQuery } from 'src/graphql' +import Button from 'src/Components/Button/Button' +import { useGetHackathonsQuery } from 'src/graphql' import { useAppSelector, useInfiniteQuery } from 'src/utils/hooks' +import HackathonsList from '../../Components/HackathonsList/HackathonsList' import SortByFilter from '../../Components/SortByFilter/SortByFilter' import TopicsFilter from '../../Components/TopicsFilter/TopicsFilter' import styles from './styles.module.scss' @@ -9,19 +11,15 @@ import styles from './styles.module.scss' export default function HackathonsPage() { - const [sortByFilter, setSortByFilter] = useState('all') - const [topicsFilter, setTopicsFilter] = useState('all') + const [sortByFilter, setSortByFilter] = useState(null) + const [topicsFilter, setTopicsFilter] = useState(null) - - const feedQuery = useFeedQuery({ + const hackathonsQuery = useGetHackathonsQuery({ variables: { - take: 10, - skip: 0, sortBy: sortByFilter, topic: Number(topicsFilter) }, }) - const { fetchMore, isFetchingMore } = useInfiniteQuery(feedQuery, 'getFeed') const { navHeight } = useAppSelector((state) => ({ navHeight: state.ui.navHeight })); @@ -31,7 +29,7 @@ export default function HackathonsPage() { className={`page-container pt-16 w-full ${styles.grid}`} > - +
    + +
) } diff --git a/src/features/Hackathons/pages/HackathonsPage/allHackathons.graphql b/src/features/Hackathons/pages/HackathonsPage/allHackathons.graphql new file mode 100644 index 0000000..39e93ee --- /dev/null +++ b/src/features/Hackathons/pages/HackathonsPage/allHackathons.graphql @@ -0,0 +1,17 @@ +query getHackathons($sortBy: String, $topic: Int) { + getAllHackathons(sortBy: $sortBy, topic: $topic) { + id + title + description + cover_image + start_date + end_date + location + website + topics { + id + title + icon + } + } +} diff --git a/src/features/Hackathons/pages/HackathonsPage/styles.module.scss b/src/features/Hackathons/pages/HackathonsPage/styles.module.scss index 92cd659..2f6412e 100644 --- a/src/features/Hackathons/pages/HackathonsPage/styles.module.scss +++ b/src/features/Hackathons/pages/HackathonsPage/styles.module.scss @@ -4,14 +4,11 @@ gap: 0; @media screen and (min-width: 680px) { - grid-template-columns: 1fr 2fr 0; + grid-template-columns: 1fr 2fr; gap: 32px; } @media screen and (min-width: 1024px) { - grid-template-columns: - minmax(200px, 1fr) - minmax(50%, 70ch) - minmax(200px, 1fr); + grid-template-columns: calc(min(30%, 326px)) 1fr; } } diff --git a/src/features/Hackathons/types/hackathons.interface.ts b/src/features/Hackathons/types/hackathons.interface.ts index c45d2bf..fb12fff 100644 --- a/src/features/Hackathons/types/hackathons.interface.ts +++ b/src/features/Hackathons/types/hackathons.interface.ts @@ -1,13 +1,3 @@ -export interface Hackathon { - id: number - title: string - date: string - location: string - description: string - cover_image: string - topics: Array<{ - id: number, - title: string - }>, - url: string -} \ No newline at end of file +import { Hackathon as ApiHackathon, } from "src/graphql" + +export type Hackathon = ApiHackathon \ No newline at end of file diff --git a/src/features/Posts/pages/FeedPage/PopularTopicsFilter/PopularTopicsFilter.tsx b/src/features/Posts/pages/FeedPage/PopularTopicsFilter/PopularTopicsFilter.tsx index 1189759..a719455 100644 --- a/src/features/Posts/pages/FeedPage/PopularTopicsFilter/PopularTopicsFilter.tsx +++ b/src/features/Posts/pages/FeedPage/PopularTopicsFilter/PopularTopicsFilter.tsx @@ -2,27 +2,6 @@ import React, { useState } from 'react' import Skeleton from 'react-loading-skeleton'; import { usePopularTopicsQuery } from 'src/graphql'; -const filters = [ - { - text: "🔥 All", - value: 0 - }, { - text: "Lightning Network", - value: 1 - }, { - text: "Bitcoin", - value: 2 - }, { - text: "Cybersecurity", - value: 3 - }, { - text: "Bounties", - value: 4 - }, { - text: "Grants", - value: 5 - }, -] interface Props { filterChanged?: (newFilter: number | null) => void @@ -30,7 +9,7 @@ interface Props { export default function PopularTopicsFilter({ filterChanged }: Props) { - const [selected, setSelected] = useState(filters[0].value); + const [selected, setSelected] = useState(null); const topicsQuery = usePopularTopicsQuery(); @@ -59,10 +38,10 @@ export default function PopularTopicsFilter({ filterChanged }: Props) { : topicsQuery.data?.popularTopics.map((f, idx) =>
  • filterClicked(f.id)} > - {f.icon} + {f.icon} {f.title} diff --git a/src/features/Posts/pages/FeedPage/SortBy/SortBy.tsx b/src/features/Posts/pages/FeedPage/SortBy/SortBy.tsx index de1405f..a98cbcc 100644 --- a/src/features/Posts/pages/FeedPage/SortBy/SortBy.tsx +++ b/src/features/Posts/pages/FeedPage/SortBy/SortBy.tsx @@ -3,8 +3,8 @@ import { Nullable } from 'remirror'; const filters = [ { - text: "🔥 Popular", - value: 'popular' + text: "🔥 Hottest", + value: 'hottest' }, { text: "📆 Newest", value: 'newest' @@ -34,7 +34,7 @@ export default function SortBy({ filterChanged }: Props) {
      {filters.map((f, idx) =>
    • filterClicked(f.value)} > {f.text} diff --git a/src/graphql/index.tsx b/src/graphql/index.tsx index 180c50a..5e06c4f 100644 --- a/src/graphql/index.tsx +++ b/src/graphql/index.tsx @@ -63,6 +63,19 @@ export type Category = { votes_sum: Scalars['Int']; }; +export type Hackathon = { + __typename?: 'Hackathon'; + cover_image: Scalars['String']; + description: Scalars['String']; + end_date: Scalars['Date']; + id: Scalars['Int']; + location: Scalars['String']; + start_date: Scalars['Date']; + title: Scalars['String']; + topics: Array; + website: Scalars['String']; +}; + export type LnurlDetails = { __typename?: 'LnurlDetails'; commentAllowed: Maybe; @@ -139,6 +152,7 @@ export type Query = { allCategories: Array; allProjects: Array; allTopics: Array; + getAllHackathons: Array; getCategory: Category; getFeed: Array; getLnurlDetailsForProject: LnurlDetails; @@ -159,6 +173,12 @@ export type QueryAllProjectsArgs = { }; +export type QueryGetAllHackathonsArgs = { + sortBy: InputMaybe; + topic: InputMaybe; +}; + + export type QueryGetCategoryArgs = { id: Scalars['Int']; }; @@ -297,6 +317,19 @@ export type SearchProjectsQueryVariables = Exact<{ export type SearchProjectsQuery = { __typename?: 'Query', searchProjects: Array<{ __typename?: 'Project', id: number, thumbnail_image: string, title: string, category: { __typename?: 'Category', title: string, id: number } }> }; +export type AllTopicsQueryVariables = Exact<{ [key: string]: never; }>; + + +export type AllTopicsQuery = { __typename?: 'Query', allTopics: Array<{ __typename?: 'Topic', id: number, title: string, icon: string }> }; + +export type GetHackathonsQueryVariables = Exact<{ + sortBy: InputMaybe; + topic: InputMaybe; +}>; + + +export type GetHackathonsQuery = { __typename?: 'Query', getAllHackathons: Array<{ __typename?: 'Hackathon', id: number, title: string, description: string, cover_image: string, start_date: any, end_date: any, location: string, website: string, topics: Array<{ __typename?: 'Topic', id: number, title: string, icon: string }> }> }; + export type TrendingPostsQueryVariables = Exact<{ [key: string]: never; }>; @@ -450,6 +483,90 @@ export function useSearchProjectsLazyQuery(baseOptions?: Apollo.LazyQueryHookOpt export type SearchProjectsQueryHookResult = ReturnType; export type SearchProjectsLazyQueryHookResult = ReturnType; export type SearchProjectsQueryResult = Apollo.QueryResult; +export const AllTopicsDocument = gql` + query allTopics { + allTopics { + id + title + icon + } +} + `; + +/** + * __useAllTopicsQuery__ + * + * To run a query within a React component, call `useAllTopicsQuery` and pass it any options that fit your needs. + * When your component renders, `useAllTopicsQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useAllTopicsQuery({ + * variables: { + * }, + * }); + */ +export function useAllTopicsQuery(baseOptions?: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(AllTopicsDocument, options); + } +export function useAllTopicsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(AllTopicsDocument, options); + } +export type AllTopicsQueryHookResult = ReturnType; +export type AllTopicsLazyQueryHookResult = ReturnType; +export type AllTopicsQueryResult = Apollo.QueryResult; +export const GetHackathonsDocument = gql` + query getHackathons($sortBy: String, $topic: Int) { + getAllHackathons(sortBy: $sortBy, topic: $topic) { + id + title + description + cover_image + start_date + end_date + location + website + topics { + id + title + icon + } + } +} + `; + +/** + * __useGetHackathonsQuery__ + * + * To run a query within a React component, call `useGetHackathonsQuery` and pass it any options that fit your needs. + * When your component renders, `useGetHackathonsQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGetHackathonsQuery({ + * variables: { + * sortBy: // value for 'sortBy' + * topic: // value for 'topic' + * }, + * }); + */ +export function useGetHackathonsQuery(baseOptions?: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(GetHackathonsDocument, options); + } +export function useGetHackathonsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(GetHackathonsDocument, options); + } +export type GetHackathonsQueryHookResult = ReturnType; +export type GetHackathonsLazyQueryHookResult = ReturnType; +export type GetHackathonsQueryResult = Apollo.QueryResult; export const TrendingPostsDocument = gql` query TrendingPosts { getTrendingPosts { diff --git a/src/mocks/data/hackathon.ts b/src/mocks/data/hackathon.ts index d2a3b18..4f3484e 100644 --- a/src/mocks/data/hackathon.ts +++ b/src/mocks/data/hackathon.ts @@ -1,3 +1,4 @@ +import { Hackathon } from "src/graphql" import { topics } from "./topics" import { getCoverImage, getItems } from "./utils" @@ -12,61 +13,67 @@ export const hackathons = [ { id: 1, title: 'Fulmo Hackday', - date: '22nd - 28th March, 2022', + start_date: new Date(2022, 2, 22), + end_date: new Date(2022, 2, 28), location: "Instanbul, Turkey", cover_image: getCoverImage(), description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam quam felis ut interdum commodo, scelerisque.", topics: generateTopics(), - url: "https://bolt.fun/hackathons/shock-the-web" + website: "https://bolt.fun/hackathons/shock-the-web" }, { id: 2, title: 'Lightning Leagues', - date: '22nd - 28th March, 2022', + start_date: new Date(2022, 2, 22), + end_date: new Date(2022, 2, 28), location: "Instanbul, Turkey", cover_image: getCoverImage(), description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam quam felis ut interdum commodo, scelerisque.", topics: generateTopics(), - url: "https://bolt.fun/hackathons/shock-the-web" + website: "https://bolt.fun/hackathons/shock-the-web" }, { id: 3, title: 'Surfing on Lightning', - date: '22nd - 28th March, 2022', + start_date: new Date(2022, 2, 22), + end_date: new Date(2022, 2, 28), location: "Instanbul, Turkey", cover_image: getCoverImage(), description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam quam felis ut interdum commodo, scelerisque.", topics: generateTopics(), - url: "https://bolt.fun/hackathons/shock-the-web" + website: "https://bolt.fun/hackathons/shock-the-web" }, { id: 4, title: 'Lightning Startups', - date: '22nd - 28th March, 2022', + start_date: new Date(2022, 2, 22), + end_date: new Date(2022, 2, 28), location: "Instanbul, Turkey", cover_image: getCoverImage(), description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam quam felis ut interdum commodo, scelerisque.", topics: generateTopics(), - url: "https://bolt.fun/hackathons/shock-the-web" + website: "https://bolt.fun/hackathons/shock-the-web" }, { id: 5, title: 'Design-a-thon', - date: '22nd - 28th March, 2022', + start_date: new Date(2022, 2, 22), + end_date: new Date(2022, 2, 28), location: "Instanbul, Turkey", cover_image: getCoverImage(), description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam quam felis ut interdum commodo, scelerisque.", topics: generateTopics(), - url: "https://bolt.fun/hackathons/shock-the-web" + website: "https://bolt.fun/hackathons/shock-the-web" }, { id: 6, title: 'Lightning Olympics', - date: '22nd - 28th March, 2022', + start_date: new Date(2022, 2, 22), + end_date: new Date(2022, 2, 28), location: "Instanbul, Turkey", cover_image: getCoverImage(), description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam quam felis ut interdum commodo, scelerisque.", topics: generateTopics(), - url: "https://bolt.fun/hackathons/shock-the-web" + website: "https://bolt.fun/hackathons/shock-the-web" }, -] \ No newline at end of file +].map(i => ({ ...i, __typename: "Hackathon" })) as Hackathon[] \ No newline at end of file diff --git a/src/mocks/handlers.ts b/src/mocks/handlers.ts index 8d30b7c..e6ee116 100644 --- a/src/mocks/handlers.ts +++ b/src/mocks/handlers.ts @@ -1,6 +1,6 @@ import { graphql } from 'msw' -import { allCategories, getCategory, getFeed, getPostById, getProject, getTrendingPosts, hottestProjects, newProjects, popularTopics, projectsByCategory, searchProjects } from './resolvers' +import { allCategories, getAllHackathons, getCategory, getFeed, getPostById, getProject, getTrendingPosts, hottestProjects, newProjects, popularTopics, projectsByCategory, searchProjects } from './resolvers' import { NavCategoriesQuery, ExploreProjectsQuery, @@ -21,6 +21,10 @@ import { TrendingPostsQuery, PopularTopicsQuery, PopularTopicsQueryVariables, + GetHackathonsQuery, + GetHackathonsQueryVariables, + AllTopicsQuery, + AllTopicsQueryVariables, } from 'src/graphql' const delay = (ms = 1000) => new Promise((res) => setTimeout(res, ms + Math.random() * 1000)) @@ -112,6 +116,15 @@ export const handlers = [ ) }), + graphql.query('allTopics', async (req, res, ctx) => { + await delay() + return res( + ctx.data({ + allTopics: popularTopics() + }) + ) + }), + graphql.query('Feed', async (req, res, ctx) => { await delay() @@ -148,4 +161,15 @@ export const handlers = [ ) }), + + graphql.query('getHackathons', async (req, res, ctx) => { + await delay() + + return res( + ctx.data({ + getAllHackathons: getAllHackathons() + }) + ) + }), + ] \ No newline at end of file diff --git a/src/mocks/resolvers.ts b/src/mocks/resolvers.ts index a75bf95..cff9a2c 100644 --- a/src/mocks/resolvers.ts +++ b/src/mocks/resolvers.ts @@ -2,6 +2,7 @@ import { MOCK_DATA } from "./data"; import { Query, QueryGetFeedArgs, QueryGetPostByIdArgs } from 'src/graphql' import { Chance } from "chance"; import { topics } from "./data/topics"; +import { hackathons } from "./data/hackathon"; const chance = new Chance() @@ -63,4 +64,8 @@ export function getTrendingPosts(): Query['getTrendingPosts'] { export function popularTopics() { return topics; +} + +export function getAllHackathons() { + return hackathons; } \ No newline at end of file diff --git a/src/redux/features/wallet.slice.ts b/src/redux/features/wallet.slice.ts index 0e2b486..f6be12a 100644 --- a/src/redux/features/wallet.slice.ts +++ b/src/redux/features/wallet.slice.ts @@ -1,5 +1,4 @@ -import { WebLNProvider } from "webln"; -import { createSlice, PayloadAction } from "@reduxjs/toolkit"; +import { createSlice } from "@reduxjs/toolkit"; diff --git a/src/utils/helperFunctions.tsx b/src/utils/helperFunctions.tsx index ef365c7..2c5cd5b 100644 --- a/src/utils/helperFunctions.tsx +++ b/src/utils/helperFunctions.tsx @@ -10,8 +10,6 @@ export function randomItem(...args: any[]) { } export function randomItems(cnt: number, ...args: any[]) { - console.log(cnt); - return shuffle(args).slice(0, cnt); } diff --git a/src/utils/hooks/useInfiniteQuery.ts b/src/utils/hooks/useInfiniteQuery.ts index bd56178..1095419 100644 --- a/src/utils/hooks/useInfiniteQuery.ts +++ b/src/utils/hooks/useInfiniteQuery.ts @@ -1,5 +1,4 @@ import { QueryResult } from "@apollo/client"; -import { useUpdateEffect } from "@react-hookz/web"; import { useCallback, useState } from "react"; export const useInfiniteQuery = (query: QueryResult, dataField: string) => {