From e6a19ecd6f21b89f0abdae9911fe4c4d74656592 Mon Sep 17 00:00:00 2001 From: MTG2000 Date: Thu, 1 Sep 2022 11:04:03 +0300 Subject: [PATCH] feat (overview-page): judges, faqs, counter --- src/Components/VoteButton/VoteButton.tsx | 6 +- .../ProjectPage/VoteButton/VoteButton.tsx | 6 +- .../OverviewPage/FAQsSection/FAQsSection.tsx | 21 ++++ .../JudgesSection/JudgesSection.tsx | 34 ++++++ .../pages/OverviewPage/OverviewPage.tsx | 45 ++----- .../PrizesSection/PrizesSection.tsx | 3 +- .../RegisterCard/RegisterCard.tsx | 60 +++++++++ src/mocks/data/tournament.ts | 115 +++++++++++++++++- src/mocks/data/users.ts | 14 +-- src/utils/helperFunctions.tsx | 2 +- src/utils/hooks/index.ts | 1 + src/utils/hooks/useCountdown.ts | 33 +++++ 12 files changed, 285 insertions(+), 55 deletions(-) create mode 100644 src/features/Tournaments/pages/OverviewPage/FAQsSection/FAQsSection.tsx create mode 100644 src/features/Tournaments/pages/OverviewPage/JudgesSection/JudgesSection.tsx create mode 100644 src/features/Tournaments/pages/OverviewPage/RegisterCard/RegisterCard.tsx create mode 100644 src/utils/hooks/useCountdown.ts diff --git a/src/Components/VoteButton/VoteButton.tsx b/src/Components/VoteButton/VoteButton.tsx index 7defb67..3b1abd6 100644 --- a/src/Components/VoteButton/VoteButton.tsx +++ b/src/Components/VoteButton/VoteButton.tsx @@ -18,7 +18,7 @@ interface Particle { offsetY: number, color: string animation: 'fly-spark-1' | 'fly-spark-2', - animationSpeed: 1 | 2 | 3, + animationSpeed: number, scale: number } @@ -108,11 +108,11 @@ export default function VoteButton({ id: (Math.random() + 1).toString(), offsetX: random(-10, 99), offsetY: random(10, 90), - animation: randomItem(styles.fly_spark_1, styles.fly_spark_1), + animation: randomItem(styles.fly_spark_1, styles.fly_spark_1) as any, animationSpeed: randomItem(1, 1.5, 2), color: `hsl(0deg 86% ${random(50, 63)}%)`, scale: random(1, 1.5) - })) + } as const)) // if on mobile screen, reduce number of sparks particles to 60% setSparks(oldSparks => [...oldSparks, ...newSparks]) diff --git a/src/features/Projects/pages/ProjectPage/VoteButton/VoteButton.tsx b/src/features/Projects/pages/ProjectPage/VoteButton/VoteButton.tsx index c73df42..5bb71dc 100644 --- a/src/features/Projects/pages/ProjectPage/VoteButton/VoteButton.tsx +++ b/src/features/Projects/pages/ProjectPage/VoteButton/VoteButton.tsx @@ -12,7 +12,7 @@ interface Particle { offsetX: number, color: '#ff6a00' | '#ff7717' | '#ff6217' | '#ff8217' | '#ff5717' animation: 'fly-spark-1' | 'fly-spark-2', - animationSpeed: 1 | 2 | 3, + animationSpeed: number, scale: number } @@ -40,11 +40,11 @@ export default function VoteButton({ onVote = () => { }, ...props }: Props) { const newSpark = { id: Math.random().toString(), offsetX: random(1, 99), - animation: randomItem(styles.fly_spark_1, styles.fly_spark_1), + animation: randomItem(styles.fly_spark_1, styles.fly_spark_1) as any, animationSpeed: randomItem(1, 1.5, 2), color: randomItem('#ff6a00', '#ff7717', '#ff6217', '#ff8217', '#ff5717'), scale: random(1.2, 2.2) - }; + } as const; // if on mobile screen, reduce number of sparks particles to 60% if (!isMobileScreen || Math.random() > .4) { diff --git a/src/features/Tournaments/pages/OverviewPage/FAQsSection/FAQsSection.tsx b/src/features/Tournaments/pages/OverviewPage/FAQsSection/FAQsSection.tsx new file mode 100644 index 0000000..2d45895 --- /dev/null +++ b/src/features/Tournaments/pages/OverviewPage/FAQsSection/FAQsSection.tsx @@ -0,0 +1,21 @@ +import React, { useMemo } from 'react' +import Accordion from 'src/Components/Accordion/Accordion'; +import { Tournament } from 'src/graphql' + +interface Props { + faqs: Tournament['faqs'] +} + + +export default function FAQsSection({ faqs }: Props) { + + + return ( +
+

FAQs

+ ({ heading: faq.question, content:

{faq.answer}

}))} + /> +
+ ) +} diff --git a/src/features/Tournaments/pages/OverviewPage/JudgesSection/JudgesSection.tsx b/src/features/Tournaments/pages/OverviewPage/JudgesSection/JudgesSection.tsx new file mode 100644 index 0000000..b510257 --- /dev/null +++ b/src/features/Tournaments/pages/OverviewPage/JudgesSection/JudgesSection.tsx @@ -0,0 +1,34 @@ +import React, { useMemo } from 'react' +import { Tournament } from 'src/graphql' + +interface Props { + judges: Tournament['judges'] +} + +const bgColors = ['#FDE68A', '#FECACA', '#BFDBFE', '#BBF7D0', '#DDD6FE', '#FBCFE8', '#FED7AA']; + +export default function JudgesSection({ judges }: Props) { + + const colors = useMemo(() => { + return judges.map((_, i) => bgColors[i % bgColors.length]) + }, [judges]) + + return ( +
+

Judges

+
+ {judges.map((judge, idx) =>
+ +
+

{judge.name}

+

{judge.jobTitle}

+
+
)} +
+
+ ) +} diff --git a/src/features/Tournaments/pages/OverviewPage/OverviewPage.tsx b/src/features/Tournaments/pages/OverviewPage/OverviewPage.tsx index ff79155..ec3196c 100644 --- a/src/features/Tournaments/pages/OverviewPage/OverviewPage.tsx +++ b/src/features/Tournaments/pages/OverviewPage/OverviewPage.tsx @@ -4,7 +4,10 @@ import Button from 'src/Components/Button/Button' import Card from 'src/Components/Card/Card' import Avatar from 'src/features/Profiles/Components/Avatar/Avatar' import { Tournament } from 'src/graphql' +import FAQsSection from './FAQsSection/FAQsSection' +import JudgesSection from './JudgesSection/JudgesSection' import PrizesSection from './PrizesSection/PrizesSection' +import RegisterCard from './RegisterCard/RegisterCard' interface Props { data: Pick } @@ -21,47 +25,14 @@ export default function OverviewPage({ data }: Props) {
-

Tournament details

+

Tournament details

{data.description}

- -
-

- + {data.makers_count} makers -

- -
-
-

- Tournament starts in -

-
-
- 17d -
-
- 12h -
-
- 36m -
-
-
-
-

- Sponsors -

-
- - - - -
-
-
+
- + +
) } diff --git a/src/features/Tournaments/pages/OverviewPage/PrizesSection/PrizesSection.tsx b/src/features/Tournaments/pages/OverviewPage/PrizesSection/PrizesSection.tsx index 02262c6..541567c 100644 --- a/src/features/Tournaments/pages/OverviewPage/PrizesSection/PrizesSection.tsx +++ b/src/features/Tournaments/pages/OverviewPage/PrizesSection/PrizesSection.tsx @@ -9,8 +9,7 @@ interface Props { export default function PrizesSection({ prizes }: Props) { return (
- -

Prizes

+

Prizes

{prizes.map(prize =>
diff --git a/src/features/Tournaments/pages/OverviewPage/RegisterCard/RegisterCard.tsx b/src/features/Tournaments/pages/OverviewPage/RegisterCard/RegisterCard.tsx new file mode 100644 index 0000000..7777863 --- /dev/null +++ b/src/features/Tournaments/pages/OverviewPage/RegisterCard/RegisterCard.tsx @@ -0,0 +1,60 @@ +import React from 'react' +import { FaUsers } from 'react-icons/fa' +import Button from 'src/Components/Button/Button' +import Card from 'src/Components/Card/Card' +import Avatar from 'src/features/Profiles/Components/Avatar/Avatar' +import { useCountdown } from 'src/utils/hooks' + +interface Props { + start_date: string; + makers_count: number +} + +export default function RegisterCard({ makers_count, start_date }: Props) { + + const counter = useCountdown(start_date) + + return ( + +
+

+ + {makers_count} makers +

+ +
+
+ {counter.isExpired ? +

Tournament running!

+ : + <> +

+ Tournament starts in +

+
+
+ {counter.days}d +
+
+ {counter.hours}h +
+
+ {counter.minutes}m +
+
+ + } +
+
+

+ Sponsors +

+
+ + + + +
+
+
+ ) +} diff --git a/src/mocks/data/tournament.ts b/src/mocks/data/tournament.ts index 45e4fcd..b04a534 100644 --- a/src/mocks/data/tournament.ts +++ b/src/mocks/data/tournament.ts @@ -41,7 +41,118 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Semper turpis est, ac e makers_count: 668, projects_count: 21, events: [], - faqs: [], - judges: [], + judges: [ + { + name: "Ben Arc", + avatar: "https://s3-alpha-sig.figma.com/img/5e65/c22c/673b8f74ac43f024b036dbc4e6479e0d?Expires=1662940800&Signature=GR54s7FBcLGcPTVclWdmPjzU92tyrYpdUbbDUYKMUkdQbxq2yQlUhZ-AOLDHhOPY4P2G3aW2yT16b1AUbC8RBx1boH25MSrH-jpn6X57IJA-4ZeHP8zCo-yjTLpb8Gn~vudIi9rPfbwJ34stp-VeOAYMuOHlah3YO-B4MBsBv-NqhP7BMY4zz9vGdBLZhOjYQYdLZ2494Ae6L5FpD1ah3WD3U5qUN9dDvYvAtqYfhQeBOnsG6PfYoq8LouCuERC4S26BeooPg8UdGUCf324-SjEihCoL8mQFq80PSsaAZl5~EBOKRUx14FOprizMusaYN0K06E~fjDIDbM2Rmc9Xjg__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + jobTitle: "Maker" + }, + { + name: "Ben Arc", + avatar: "https://s3-alpha-sig.figma.com/img/5e65/c22c/673b8f74ac43f024b036dbc4e6479e0d?Expires=1662940800&Signature=GR54s7FBcLGcPTVclWdmPjzU92tyrYpdUbbDUYKMUkdQbxq2yQlUhZ-AOLDHhOPY4P2G3aW2yT16b1AUbC8RBx1boH25MSrH-jpn6X57IJA-4ZeHP8zCo-yjTLpb8Gn~vudIi9rPfbwJ34stp-VeOAYMuOHlah3YO-B4MBsBv-NqhP7BMY4zz9vGdBLZhOjYQYdLZ2494Ae6L5FpD1ah3WD3U5qUN9dDvYvAtqYfhQeBOnsG6PfYoq8LouCuERC4S26BeooPg8UdGUCf324-SjEihCoL8mQFq80PSsaAZl5~EBOKRUx14FOprizMusaYN0K06E~fjDIDbM2Rmc9Xjg__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + jobTitle: "Maker" + }, + { + name: "Ben Arc", + avatar: "https://s3-alpha-sig.figma.com/img/5e65/c22c/673b8f74ac43f024b036dbc4e6479e0d?Expires=1662940800&Signature=GR54s7FBcLGcPTVclWdmPjzU92tyrYpdUbbDUYKMUkdQbxq2yQlUhZ-AOLDHhOPY4P2G3aW2yT16b1AUbC8RBx1boH25MSrH-jpn6X57IJA-4ZeHP8zCo-yjTLpb8Gn~vudIi9rPfbwJ34stp-VeOAYMuOHlah3YO-B4MBsBv-NqhP7BMY4zz9vGdBLZhOjYQYdLZ2494Ae6L5FpD1ah3WD3U5qUN9dDvYvAtqYfhQeBOnsG6PfYoq8LouCuERC4S26BeooPg8UdGUCf324-SjEihCoL8mQFq80PSsaAZl5~EBOKRUx14FOprizMusaYN0K06E~fjDIDbM2Rmc9Xjg__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + jobTitle: "Maker" + }, + { + name: "Ben Arc", + avatar: "https://s3-alpha-sig.figma.com/img/5e65/c22c/673b8f74ac43f024b036dbc4e6479e0d?Expires=1662940800&Signature=GR54s7FBcLGcPTVclWdmPjzU92tyrYpdUbbDUYKMUkdQbxq2yQlUhZ-AOLDHhOPY4P2G3aW2yT16b1AUbC8RBx1boH25MSrH-jpn6X57IJA-4ZeHP8zCo-yjTLpb8Gn~vudIi9rPfbwJ34stp-VeOAYMuOHlah3YO-B4MBsBv-NqhP7BMY4zz9vGdBLZhOjYQYdLZ2494Ae6L5FpD1ah3WD3U5qUN9dDvYvAtqYfhQeBOnsG6PfYoq8LouCuERC4S26BeooPg8UdGUCf324-SjEihCoL8mQFq80PSsaAZl5~EBOKRUx14FOprizMusaYN0K06E~fjDIDbM2Rmc9Xjg__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + jobTitle: "Maker" + }, + { + name: "Ben Arc", + avatar: "https://s3-alpha-sig.figma.com/img/5e65/c22c/673b8f74ac43f024b036dbc4e6479e0d?Expires=1662940800&Signature=GR54s7FBcLGcPTVclWdmPjzU92tyrYpdUbbDUYKMUkdQbxq2yQlUhZ-AOLDHhOPY4P2G3aW2yT16b1AUbC8RBx1boH25MSrH-jpn6X57IJA-4ZeHP8zCo-yjTLpb8Gn~vudIi9rPfbwJ34stp-VeOAYMuOHlah3YO-B4MBsBv-NqhP7BMY4zz9vGdBLZhOjYQYdLZ2494Ae6L5FpD1ah3WD3U5qUN9dDvYvAtqYfhQeBOnsG6PfYoq8LouCuERC4S26BeooPg8UdGUCf324-SjEihCoL8mQFq80PSsaAZl5~EBOKRUx14FOprizMusaYN0K06E~fjDIDbM2Rmc9Xjg__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + jobTitle: "Maker" + }, + { + name: "Ben Arc", + avatar: "https://s3-alpha-sig.figma.com/img/5e65/c22c/673b8f74ac43f024b036dbc4e6479e0d?Expires=1662940800&Signature=GR54s7FBcLGcPTVclWdmPjzU92tyrYpdUbbDUYKMUkdQbxq2yQlUhZ-AOLDHhOPY4P2G3aW2yT16b1AUbC8RBx1boH25MSrH-jpn6X57IJA-4ZeHP8zCo-yjTLpb8Gn~vudIi9rPfbwJ34stp-VeOAYMuOHlah3YO-B4MBsBv-NqhP7BMY4zz9vGdBLZhOjYQYdLZ2494Ae6L5FpD1ah3WD3U5qUN9dDvYvAtqYfhQeBOnsG6PfYoq8LouCuERC4S26BeooPg8UdGUCf324-SjEihCoL8mQFq80PSsaAZl5~EBOKRUx14FOprizMusaYN0K06E~fjDIDbM2Rmc9Xjg__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + jobTitle: "Maker" + }, + { + name: "Ben Arc", + avatar: "https://s3-alpha-sig.figma.com/img/5e65/c22c/673b8f74ac43f024b036dbc4e6479e0d?Expires=1662940800&Signature=GR54s7FBcLGcPTVclWdmPjzU92tyrYpdUbbDUYKMUkdQbxq2yQlUhZ-AOLDHhOPY4P2G3aW2yT16b1AUbC8RBx1boH25MSrH-jpn6X57IJA-4ZeHP8zCo-yjTLpb8Gn~vudIi9rPfbwJ34stp-VeOAYMuOHlah3YO-B4MBsBv-NqhP7BMY4zz9vGdBLZhOjYQYdLZ2494Ae6L5FpD1ah3WD3U5qUN9dDvYvAtqYfhQeBOnsG6PfYoq8LouCuERC4S26BeooPg8UdGUCf324-SjEihCoL8mQFq80PSsaAZl5~EBOKRUx14FOprizMusaYN0K06E~fjDIDbM2Rmc9Xjg__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + jobTitle: "Maker" + }, + { + name: "Ben Arc", + avatar: "https://s3-alpha-sig.figma.com/img/5e65/c22c/673b8f74ac43f024b036dbc4e6479e0d?Expires=1662940800&Signature=GR54s7FBcLGcPTVclWdmPjzU92tyrYpdUbbDUYKMUkdQbxq2yQlUhZ-AOLDHhOPY4P2G3aW2yT16b1AUbC8RBx1boH25MSrH-jpn6X57IJA-4ZeHP8zCo-yjTLpb8Gn~vudIi9rPfbwJ34stp-VeOAYMuOHlah3YO-B4MBsBv-NqhP7BMY4zz9vGdBLZhOjYQYdLZ2494Ae6L5FpD1ah3WD3U5qUN9dDvYvAtqYfhQeBOnsG6PfYoq8LouCuERC4S26BeooPg8UdGUCf324-SjEihCoL8mQFq80PSsaAZl5~EBOKRUx14FOprizMusaYN0K06E~fjDIDbM2Rmc9Xjg__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + jobTitle: "Maker" + }, + { + name: "Ben Arc", + avatar: "https://s3-alpha-sig.figma.com/img/5e65/c22c/673b8f74ac43f024b036dbc4e6479e0d?Expires=1662940800&Signature=GR54s7FBcLGcPTVclWdmPjzU92tyrYpdUbbDUYKMUkdQbxq2yQlUhZ-AOLDHhOPY4P2G3aW2yT16b1AUbC8RBx1boH25MSrH-jpn6X57IJA-4ZeHP8zCo-yjTLpb8Gn~vudIi9rPfbwJ34stp-VeOAYMuOHlah3YO-B4MBsBv-NqhP7BMY4zz9vGdBLZhOjYQYdLZ2494Ae6L5FpD1ah3WD3U5qUN9dDvYvAtqYfhQeBOnsG6PfYoq8LouCuERC4S26BeooPg8UdGUCf324-SjEihCoL8mQFq80PSsaAZl5~EBOKRUx14FOprizMusaYN0K06E~fjDIDbM2Rmc9Xjg__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + jobTitle: "Maker" + }, + { + name: "Ben Arc", + avatar: "https://s3-alpha-sig.figma.com/img/5e65/c22c/673b8f74ac43f024b036dbc4e6479e0d?Expires=1662940800&Signature=GR54s7FBcLGcPTVclWdmPjzU92tyrYpdUbbDUYKMUkdQbxq2yQlUhZ-AOLDHhOPY4P2G3aW2yT16b1AUbC8RBx1boH25MSrH-jpn6X57IJA-4ZeHP8zCo-yjTLpb8Gn~vudIi9rPfbwJ34stp-VeOAYMuOHlah3YO-B4MBsBv-NqhP7BMY4zz9vGdBLZhOjYQYdLZ2494Ae6L5FpD1ah3WD3U5qUN9dDvYvAtqYfhQeBOnsG6PfYoq8LouCuERC4S26BeooPg8UdGUCf324-SjEihCoL8mQFq80PSsaAZl5~EBOKRUx14FOprizMusaYN0K06E~fjDIDbM2Rmc9Xjg__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + jobTitle: "Maker" + }, + { + name: "Ben Arc", + avatar: "https://s3-alpha-sig.figma.com/img/5e65/c22c/673b8f74ac43f024b036dbc4e6479e0d?Expires=1662940800&Signature=GR54s7FBcLGcPTVclWdmPjzU92tyrYpdUbbDUYKMUkdQbxq2yQlUhZ-AOLDHhOPY4P2G3aW2yT16b1AUbC8RBx1boH25MSrH-jpn6X57IJA-4ZeHP8zCo-yjTLpb8Gn~vudIi9rPfbwJ34stp-VeOAYMuOHlah3YO-B4MBsBv-NqhP7BMY4zz9vGdBLZhOjYQYdLZ2494Ae6L5FpD1ah3WD3U5qUN9dDvYvAtqYfhQeBOnsG6PfYoq8LouCuERC4S26BeooPg8UdGUCf324-SjEihCoL8mQFq80PSsaAZl5~EBOKRUx14FOprizMusaYN0K06E~fjDIDbM2Rmc9Xjg__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + jobTitle: "Maker" + }, + { + name: "Ben Arc", + avatar: "https://s3-alpha-sig.figma.com/img/5e65/c22c/673b8f74ac43f024b036dbc4e6479e0d?Expires=1662940800&Signature=GR54s7FBcLGcPTVclWdmPjzU92tyrYpdUbbDUYKMUkdQbxq2yQlUhZ-AOLDHhOPY4P2G3aW2yT16b1AUbC8RBx1boH25MSrH-jpn6X57IJA-4ZeHP8zCo-yjTLpb8Gn~vudIi9rPfbwJ34stp-VeOAYMuOHlah3YO-B4MBsBv-NqhP7BMY4zz9vGdBLZhOjYQYdLZ2494Ae6L5FpD1ah3WD3U5qUN9dDvYvAtqYfhQeBOnsG6PfYoq8LouCuERC4S26BeooPg8UdGUCf324-SjEihCoL8mQFq80PSsaAZl5~EBOKRUx14FOprizMusaYN0K06E~fjDIDbM2Rmc9Xjg__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + jobTitle: "Maker" + }, + ], + faqs: [ + { + question: "What is Shock the Web?", + answer: + `Shock the Web is a virtual hackathon to promote, explore, build and design web applications that can interact with WebLN enabled wallets and browsers. We want to make building on bitcoin more accessible to the masses of web developers out there. + +Bitcoin development can seem scary for new developers coming in, but it doesn't have to be. With the lightning network's toolkit and libraries a bunch of new opportunities are waiting to be explored. We hope these hackathons can be a chance for you to preview what is possible on bitcoin and the lightning network by fostering collaboration, hopefully shortening (or easing) any developer onboarding time, and helping you connect with other bitcoiners in a fun and friendly space.` + }, + { + question: "When and where will it take place?", + answer: + `Shock the Web is a virtual hackathon to promote, explore, build and design web applications that can interact with WebLN enabled wallets and browsers. We want to make building on bitcoin more accessible to the masses of web developers out there. + +Bitcoin development can seem scary for new developers coming in, but it doesn't have to be. With the lightning network's toolkit and libraries a bunch of new opportunities are waiting to be explored. We hope these hackathons can be a chance for you to preview what is possible on bitcoin and the lightning network by fostering collaboration, hopefully shortening (or easing) any developer onboarding time, and helping you connect with other bitcoiners in a fun and friendly space.` + }, + { + question: "What will we be doing?", + answer: + `Shock the Web is a virtual hackathon to promote, explore, build and design web applications that can interact with WebLN enabled wallets and browsers. We want to make building on bitcoin more accessible to the masses of web developers out there. + +Bitcoin development can seem scary for new developers coming in, but it doesn't have to be. With the lightning network's toolkit and libraries a bunch of new opportunities are waiting to be explored. We hope these hackathons can be a chance for you to preview what is possible on bitcoin and the lightning network by fostering collaboration, hopefully shortening (or easing) any developer onboarding time, and helping you connect with other bitcoiners in a fun and friendly space.` + }, + { + question: "This is my first time hacking on lightning, will there be help?", + answer: + `Shock the Web is a virtual hackathon to promote, explore, build and design web applications that can interact with WebLN enabled wallets and browsers. We want to make building on bitcoin more accessible to the masses of web developers out there. + +Bitcoin development can seem scary for new developers coming in, but it doesn't have to be. With the lightning network's toolkit and libraries a bunch of new opportunities are waiting to be explored. We hope these hackathons can be a chance for you to preview what is possible on bitcoin and the lightning network by fostering collaboration, hopefully shortening (or easing) any developer onboarding time, and helping you connect with other bitcoiners in a fun and friendly space.` + }, + { + question: "This is my first time hacking on lightning, will there be help?", + answer: + `Shock the Web is a virtual hackathon to promote, explore, build and design web applications that can interact with WebLN enabled wallets and browsers. We want to make building on bitcoin more accessible to the masses of web developers out there. + +Bitcoin development can seem scary for new developers coming in, but it doesn't have to be. With the lightning network's toolkit and libraries a bunch of new opportunities are waiting to be explored. We hope these hackathons can be a chance for you to preview what is possible on bitcoin and the lightning network by fostering collaboration, hopefully shortening (or easing) any developer onboarding time, and helping you connect with other bitcoiners in a fun and friendly space.` + }, + { + question: "How many members can I have on my team?", + answer: + `Shock the Web is a virtual hackathon to promote, explore, build and design web applications that can interact with WebLN enabled wallets and browsers. We want to make building on bitcoin more accessible to the masses of web developers out there. + +Bitcoin development can seem scary for new developers coming in, but it doesn't have to be. With the lightning network's toolkit and libraries a bunch of new opportunities are waiting to be explored. We hope these hackathons can be a chance for you to preview what is possible on bitcoin and the lightning network by fostering collaboration, hopefully shortening (or easing) any developer onboarding time, and helping you connect with other bitcoiners in a fun and friendly space.` + }, + { + question: "Who will choose the winners?", + answer: + `Shock the Web is a virtual hackathon to promote, explore, build and design web applications that can interact with WebLN enabled wallets and browsers. We want to make building on bitcoin more accessible to the masses of web developers out there. + +Bitcoin development can seem scary for new developers coming in, but it doesn't have to be. With the lightning network's toolkit and libraries a bunch of new opportunities are waiting to be explored. We hope these hackathons can be a chance for you to preview what is possible on bitcoin and the lightning network by fostering collaboration, hopefully shortening (or easing) any developer onboarding time, and helping you connect with other bitcoiners in a fun and friendly space.` + }, + ], }] \ No newline at end of file diff --git a/src/mocks/data/users.ts b/src/mocks/data/users.ts index eade93e..0d3c720 100644 --- a/src/mocks/data/users.ts +++ b/src/mocks/data/users.ts @@ -1,5 +1,5 @@ import { Chance } from "chance"; -import { GenericMakerRole, MakerSkill, MyProfile, RoleLevelEnum, User } from "src/graphql"; +import { GenericMakerRole, MakerSkill, MyProfile, RoleLevelEnum, User, Tournament } from "src/graphql"; import { randomItem, randomItems } from "src/utils/helperFunctions"; import { posts } from "./posts"; import { getCoverImage, getAvatarImage } from "./utils"; @@ -135,9 +135,9 @@ export const user: User & MyProfile = { thumbnail_image: getCoverImage(), start_date: new Date(2021, 3).toISOString(), end_date: new Date(2021, 4).toISOString(), - tags: [], - website: "https://breez-conf.com" - }, + website: "https://breez-conf.com", + + } as Tournament, { id: 2, title: "Shock the Web 3", @@ -146,9 +146,9 @@ export const user: User & MyProfile = { thumbnail_image: getCoverImage(), start_date: new Date(2022, 7).toISOString(), end_date: new Date(2022, 11).toISOString(), - tags: [], - website: "https://shock-the-web.com" - }, + website: "https://shock-the-web.com", + + } as Tournament, ], similar_makers: [ { diff --git a/src/utils/helperFunctions.tsx b/src/utils/helperFunctions.tsx index f842ac8..23a2e9c 100644 --- a/src/utils/helperFunctions.tsx +++ b/src/utils/helperFunctions.tsx @@ -8,7 +8,7 @@ export function random(min: number, max: number) { return Math.random() * (max - min) + min; } -export function randomItem(...args: any[]) { +export function randomItem(...args: T[]): T { return args[Math.floor(Math.random() * args.length)]; } diff --git a/src/utils/hooks/index.ts b/src/utils/hooks/index.ts index 9d8e667..b1e9be8 100644 --- a/src/utils/hooks/index.ts +++ b/src/utils/hooks/index.ts @@ -12,4 +12,5 @@ export * from './useCurrentSection' export * from './usePreload' export * from './useCarousel' export * from './usePrompt' +export * from './useCountdown' diff --git a/src/utils/hooks/useCountdown.ts b/src/utils/hooks/useCountdown.ts new file mode 100644 index 0000000..f524901 --- /dev/null +++ b/src/utils/hooks/useCountdown.ts @@ -0,0 +1,33 @@ +import { useEffect, useState } from 'react'; + +const useCountdown = (targetDate: string | number | Date) => { + const countDownDate = new Date(targetDate).getTime(); + + const [countDown, setCountDown] = useState( + countDownDate - new Date().getTime() + ); + + useEffect(() => { + const interval = setInterval(() => { + setCountDown(countDownDate - new Date().getTime()); + }, 1000); + + return () => clearInterval(interval); + }, [countDownDate]); + + return getReturnValues(countDown); +}; + +const getReturnValues = (countDown: number) => { + // calculate time left + const days = Math.floor(countDown / (1000 * 60 * 60 * 24)); + const hours = Math.floor( + (countDown % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60) + ); + const minutes = Math.floor((countDown % (1000 * 60 * 60)) / (1000 * 60)); + const seconds = Math.floor((countDown % (1000 * 60)) / 1000); + + return { days, hours, minutes, seconds, isExpired: days + hours + minutes + seconds <= 0 }; +}; + +export { useCountdown }; \ No newline at end of file