From 770cc422013a8a60a4cfef1adde9e0bfb4301731 Mon Sep 17 00:00:00 2001 From: MTG2000 Date: Mon, 19 Sep 2022 10:27:27 +0300 Subject: [PATCH 1/2] update: prizes & tracks section --- .../PrizesSection/PrizesSection.tsx | 112 +++++++++++++++++- .../PrizesSection/styles.module.scss | 26 ++++ 2 files changed, 135 insertions(+), 3 deletions(-) diff --git a/src/features/Tournaments/pages/OverviewPage/PrizesSection/PrizesSection.tsx b/src/features/Tournaments/pages/OverviewPage/PrizesSection/PrizesSection.tsx index d910a2e..cac98e9 100644 --- a/src/features/Tournaments/pages/OverviewPage/PrizesSection/PrizesSection.tsx +++ b/src/features/Tournaments/pages/OverviewPage/PrizesSection/PrizesSection.tsx @@ -9,8 +9,39 @@ interface Props { export default function PrizesSection({ prizes }: Props) { return (
-

Prizes

-
+

{data.tracks.length > 0 ? "Prizes & Tracks" : "Prizes"}

+
+ {data.tracks.map((track, trackNumber) =>
+
+
+ {`${track.title} +

{track.title}

+

{track.description}

+
+
+ {/* One Prize */} + {track.prizes.length === 1 && +
+

{track.prizes[0].title}

+

{track.prizes[0].amount}

+
+ } + {/* Four Prizez */} + {track.prizes.length === 4 && +
+ {track.prizes.map((prize, idx) =>
+

{prize.title}

+

{prize.amount}

+
)} +
+ } +
+
+
)} +
+ {/*
{prizes.map((prize, idx) =>
@@ -20,7 +51,82 @@ export default function PrizesSection({ prizes }: Props) {

{prize.amount}

)} -
+
*/} ) } + +const data = { + prizes: [], + tracks: [ + { + id: 1, + title: "Grand Champion", + description: "Our Grand Champion, a.k.a “The Legend of Lightning” will be the best in show, la créme de la créme. Every project entered in the tournament will be eligible for this award, no matter what track they choose.", + image: "https://s3-alpha-sig.figma.com/img/33fa/68dc/1015f7806d8706cbb29b057f85482755?Expires=1664755200&Signature=QdesbJJcLG84k-SudRv9ah-tVSf~zv4NZKU1EQM9cz-L7qZ1crx7awSVBFZdP~p4R7h1FsUqQfSNHsOPQOKTRiWOL~mpKLe6SAlKhdeqrm8RCNmnhNHpMOxJrCGAsJ7vQDkUKFw9VsJjufTjtEgLHN-EWH5L~RvNHKa06f6rRyiMeRl5HCu9JWT5Spjb0zK7IrU2gT7G~Dw0FTdbE35uxCbN9pU-XuPLbqmAIsPBR-gV4uuf21NBapFOLFDazi-tDzIJO--vH6C4RjuI-i3sl1WV75-SM0DW9MVNBvXiWfPrtGXbNd379xJXQoCBVxv4qzl3YkdoxFUG1-uwKTrVaA__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + prizes: [ + { + id: 1, + title: "the legend", + amount: "1 BTC" + } + ] + }, + { + id: 2, + title: "Bitcoin Adoption Track", + description: "On-chain applications have been the bed rock of bitcoin’s explosive growth and adoption over the last decade. Slowly, steadily, and securely, bitcoin’s base layer always seeks to evolve and improve.", + image: "https://s3-alpha-sig.figma.com/img/cb90/77b4/5ea853a671d0cb1c64bde10dd8955d39?Expires=1664755200&Signature=aXtIhKJg58wRTQlJIGWxpfCN2hxJx8L0~8Hu5aH8LKUVAYrxSV5Tvvxevx9xDnf-RpjTVfB6D7RKuVQjfIiftB4Ym80oOlW9tNzYUo991cJhdYnqaGzJ6Ht2kF7NHmxbiY5RUMYj8bGf2AF1A2a7wuW~DaqHyLQ0s2sszwH2EAv31QTH1DAOO97pQzQ5asas7qGjARWh45QEfw6F8e~6iq3UWHXtIcJ0HMJO4q3ONhsMkuC6XQNfAmWTRwKb3tPZ79oehWgDeyOMGQkRS0uaal~6fNkheEN5DuRBH2dbXtqB6va0PJCTB1l8P558HXhKQjHXRLPPReIci72jPuTzdA__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + prizes: [ + { + id: 2, + title: " 1st", + amount: "$5k" + }, + { + id: 3, + title: " 2nd", + amount: "$2.5k" + }, + { + id: 4, + title: " 3rd", + amount: "$1.5k" + }, + { + id: 5, + title: " Design", + amount: "$1k" + }, + ] + }, + { + id: 3, + title: "Building for Africa track", + description: "With ~1.4bn inhabitants, Africa is ripe for bitcoin adoption. In partnership with ABC 22, this track seeks to encourage makers to build solutions that are local to the African continent.", + image: "https://s3-alpha-sig.figma.com/img/c306/f172/7ce7befa9414372e6d0ede739be46de8?Expires=1664755200&Signature=BBfOTJzk7Si7zs9dOBhTdIhoKCvUDxAr6Do0wCZaIq9PD2Jcfxu3ANbiogzihC5O2Rwz3sKsajsRCd8eSs8HGrHrQh89SfNIl0~MYjMz12yWpsc1vC5M5hmXH~VQzCTOWsSki9BimcpCu0IOWfJFjY-p0rlo8UFhdDe56DiRUOSW0pAm5UxTstzOew6X015xA3qQWwUIea2JAtlsI5RqMQMRB-QlaKFlQvYHBU6YzLUNTuTn4MfOd-1oZXKtDArubYnSrJb2rJAXqccxgsXceDl8jq8HXKwkBR95-sG3UDZB7q7qb1Nk3HlsDtirGNlOjLx~vDKpOuyIk5ufAkdJmQ__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", + prizes: [ + { + id: 6, + title: " 1st", + amount: "$5k" + }, + { + id: 7, + title: " 2nd", + amount: "$2.5k" + }, + { + id: 8, + title: " 3rd", + amount: "$1.5k" + }, + { + id: 9, + title: " Design", + amount: "$1k" + }, + ] + }, + ] +} diff --git a/src/features/Tournaments/pages/OverviewPage/PrizesSection/styles.module.scss b/src/features/Tournaments/pages/OverviewPage/PrizesSection/styles.module.scss index baecc03..a43c236 100644 --- a/src/features/Tournaments/pages/OverviewPage/PrizesSection/styles.module.scss +++ b/src/features/Tournaments/pages/OverviewPage/PrizesSection/styles.module.scss @@ -2,6 +2,32 @@ @import url("https://fonts.googleapis.com/css2?family=Luckiest+Guy&display=swap"); +.prizes { + font-family: "Luckiest Guy", cursive; + h4 { + color: white; + -webkit-text-stroke: 1px black; + } + + @include gt-md { + h4 { + -webkit-text-stroke: 0.06em black; + } + } + + p[data-attr="1"] { + color: #fb923c; + } + + p[data-attr="2"] { + color: #4ade80; + } + + p[data-attr="3"] { + color: #3b82f6; + } +} + .grid { font-family: "Luckiest Guy", cursive; display: grid; From 4bcffa7403d805dfa2c05144b829409b3c1b035c Mon Sep 17 00:00:00 2001 From: MTG2000 Date: Mon, 19 Sep 2022 10:42:44 +0300 Subject: [PATCH 2/2] update: log unexpected errors in login api & post story api --- api/functions/graphql/types/post.js | 215 +++++++++++++++------------- api/functions/login/login.js | 26 ++-- api/utils/logger.js | 9 ++ 3 files changed, 142 insertions(+), 108 deletions(-) create mode 100644 api/utils/logger.js diff --git a/api/functions/graphql/types/post.js b/api/functions/graphql/types/post.js index 49a91ba..1bf7999 100644 --- a/api/functions/graphql/types/post.js +++ b/api/functions/graphql/types/post.js @@ -18,6 +18,7 @@ const { marked } = require('marked'); const { resolveImgObjectToUrl } = require('../../../utils/resolveImageUrl'); const { ImageInput } = require('./misc'); const { deleteImage } = require('../../../services/imageUpload.service'); +const { logError } = require('../../../utils/logger'); const POST_TYPE = enumType({ @@ -435,97 +436,129 @@ const createStory = extendType({ let coverImage = null let bodyImageIds = [] - // Edit story - if (id) { - const oldPost = await prisma.story.findFirst({ - where: { id }, - select: { - user_id: true, - is_published: true, - cover_image_id: true, - body_image_ids: true - } - }) - was_published = oldPost.is_published; - if (user.id !== oldPost.user_id) throw new ApolloError("Not post author") - // Body images - bodyImageIds = await getHostedImageIdsFromBody(body, oldPost.body_image_ids) - - // Old cover image is found - if (oldPost.cover_image_id) { - const oldCoverImage = await prisma.hostedImage.findFirst({ - where: { - id: oldPost.cover_image_id + try { + if (id) { + const oldPost = await prisma.story.findFirst({ + where: { id }, + select: { + user_id: true, + is_published: true, + cover_image_id: true, + body_image_ids: true } }) + was_published = oldPost.is_published; + if (user.id !== oldPost.user_id) throw new ApolloError("Not post author") - // New cover image - if (cover_image?.id && cover_image.id !== oldCoverImage?.provider_image_id) { - await deleteImage(oldCoverImage.id) - coverImage = await addCoverImage(cover_image.id) + // Body images + bodyImageIds = await getHostedImageIdsFromBody(body, oldPost.body_image_ids) + + // Old cover image is found + if (oldPost.cover_image_id) { + const oldCoverImage = await prisma.hostedImage.findFirst({ + where: { + id: oldPost.cover_image_id + } + }) + + // New cover image + if (cover_image?.id && cover_image.id !== oldCoverImage?.provider_image_id) { + await deleteImage(oldCoverImage.id) + coverImage = await addCoverImage(cover_image.id) + } else { + coverImage = oldCoverImage + } } else { - coverImage = oldCoverImage + // No old image found and new cover image + if (cover_image?.id) { + coverImage = await addCoverImage(cover_image.id) + } } + + // Remove unused body images + const unusedImagesIds = oldPost.body_image_ids.filter(x => !bodyImageIds.includes(x)); + unusedImagesIds.map(async i => await deleteImage(i)) + } else { - // No old image found and new cover image + // Body images + bodyImageIds = await getHostedImageIdsFromBody(body) + + // New story and new cover image if (cover_image?.id) { coverImage = await addCoverImage(cover_image.id) } } - // Remove unused body images - const unusedImagesIds = oldPost.body_image_ids.filter(x => !bodyImageIds.includes(x)); - unusedImagesIds.map(async i => await deleteImage(i)) - - } else { - // Body images - bodyImageIds = await getHostedImageIdsFromBody(body) - - // New story and new cover image - if (cover_image?.id) { - coverImage = await addCoverImage(cover_image.id) - } - } - - // Preprocess & insert - const htmlBody = marked.parse(body); - const excerpt = htmlBody - .replace(/<[^>]+>/g, '') - .slice(0, 120) - .replace(/&/g, "&") - .replace(/'/g, "'") - .replace(/"/g, '"') - ; + // Preprocess & insert + const htmlBody = marked.parse(body); + const excerpt = htmlBody + .replace(/<[^>]+>/g, '') + .slice(0, 120) + .replace(/&/g, "&") + .replace(/'/g, "'") + .replace(/"/g, '"') + ; - const coverImageRel = coverImage ? { - cover_image_rel: { - connect: - { - id: coverImage ? coverImage.id : null + const coverImageRel = coverImage ? { + cover_image_rel: { + connect: + { + id: coverImage ? coverImage.id : null + } } + } : {} + + if (id) { + await prisma.story.update({ + where: { id }, + data: { + tags: { + set: [] + }, + } + }); + + return prisma.story.update({ + where: { id }, + data: { + title, + body, + cover_image: '', + excerpt, + is_published: was_published || is_published, + tags: { + connectOrCreate: + tags.map(tag => { + tag = tag.toLowerCase().trim(); + return { + where: { + title: tag, + }, + create: { + title: tag + } + } + }) + }, + body_image_ids: bodyImageIds, + ...coverImageRel + } + }) + .catch(error => { + logError(error) + throw new ApolloError("Unexpected error happened...") + }) } - } : {} - if (id) { - await prisma.story.update({ - where: { id }, - data: { - tags: { - set: [] - }, - } - }); - - return prisma.story.update({ - where: { id }, + return prisma.story.create({ data: { title, body, cover_image: '', excerpt, - is_published: was_published || is_published, + is_published, tags: { connectOrCreate: tags.map(tag => { @@ -540,42 +573,24 @@ const createStory = extendType({ } }) }, + user: { + connect: { + id: user.id, + } + }, body_image_ids: bodyImageIds, ...coverImageRel } + }).catch(error => { + logError(error) + throw new ApolloError("Unexpected error happened...") }) - } - return await prisma.story.create({ - data: { - title, - body, - cover_image: '', - excerpt, - is_published, - tags: { - connectOrCreate: - tags.map(tag => { - tag = tag.toLowerCase().trim(); - return { - where: { - title: tag, - }, - create: { - title: tag - } - } - }) - }, - user: { - connect: { - id: user.id, - } - }, - body_image_ids: bodyImageIds, - ...coverImageRel - } - }) + + } catch (error) { + logError(error) + throw new ApolloError("Unexpected error happened...") + } } }) }, diff --git a/api/functions/login/login.js b/api/functions/login/login.js index 49c162d..9dbf7e8 100644 --- a/api/functions/login/login.js +++ b/api/functions/login/login.js @@ -9,6 +9,7 @@ const jose = require('jose'); const { JWT_SECRET } = require('../../utils/consts'); const { generatePrivateKey, getPublicKey } = require('../../utils/nostr-tools'); const { getUserByPubKey } = require('../../auth/utils/helperFuncs'); +const { logError } = require('../../utils/logger'); @@ -28,10 +29,18 @@ const loginHandler = async (req, res) => { if (action === 'link' && user_token) { try { - const { payload } = await jose.jwtVerify(user_token, Buffer.from(JWT_SECRET), { - algorithms: ['HS256'], - }) - const user_id = payload.user_id; + + let user_id; + + try { + const { payload } = await jose.jwtVerify(user_token, Buffer.from(JWT_SECRET), { + algorithms: ['HS256'], + }) + user_id = payload.user_id; + } catch (error) { + return res.status(400).json({ status: 'ERROR', reason: "Invalid user_token" }) + } + const existingKeys = await prisma.userKey.findMany({ where: { user_id }, select: { key: true } }); if (existingKeys.length >= 3) @@ -55,7 +64,8 @@ const loginHandler = async (req, res) => { .json({ status: "OK" }) } catch (error) { - return res.status(400).json({ status: 'ERROR', reason: 'Invalid User Token' }) + logError(error) + return res.status(500).json({ status: 'ERROR', reason: 'Unexpected error happened' }) } } @@ -65,8 +75,7 @@ const loginHandler = async (req, res) => { const user = await getUserByPubKey(key) if (user === null) { - // Check if user had a previous account using this wallet - + // Check if user had a previous account using this wallet const oldAccount = await prisma.user.findFirst({ where: { pubKey: key @@ -136,7 +145,8 @@ const loginHandler = async (req, res) => { return res.status(200).json({ status: "OK" }) } catch (error) { - return res.status(400).json({ status: 'ERROR', reason: 'Unexpected error happened, please try again' }) + logError(error) + return res.status(500).json({ status: 'ERROR', reason: 'Unexpected error happened, please try again' }) } } diff --git a/api/utils/logger.js b/api/utils/logger.js new file mode 100644 index 0000000..5bc72ab --- /dev/null +++ b/api/utils/logger.js @@ -0,0 +1,9 @@ + +function logError(error) { + console.log("Unexpected Error: "); + console.log(error); +} + +module.exports = { + logError +} \ No newline at end of file