From c73a21190bb6d7d290d35b04ddb5f6b39320c794 Mon Sep 17 00:00:00 2001 From: MTG2000 Date: Tue, 19 Apr 2022 17:54:06 +0300 Subject: [PATCH] feat: story content page, bounty content page --- functions/graphql/types/post.js | 1 - package-lock.json | 30 ++++++++ package.json | 2 + .../PostCard/BountyCard/BountyCard.tsx | 13 +++- .../PostCard/QuestionCard/QuestionCard.tsx | 14 +++- .../PostCard/StoryCard/StoryCard.tsx | 12 ++- .../AuthorCard/AuthorCard.stories.tsx | 2 +- .../PageContent/BountyPageContent.tsx | 76 +++++++++++++++++++ .../PageContent/PageContent.stories.tsx | 27 +++++++ .../Components/PageContent/PageContent.tsx | 25 ++++-- .../PageContent/StoryPageContent.tsx | 39 ++++++++++ .../Components/PageContent/styles.module.css | 32 ++++++++ .../PostActions/PostAction.stories.tsx | 4 +- .../Components/PostActions/PostActions.tsx | 4 +- .../pages/PostDetailsPage/PostDetailsPage.tsx | 6 +- src/features/Posts/types/posts.interface.ts | 5 ++ src/mocks/data/posts.ts | 37 ++++++++- src/mocks/data/utils.ts | 8 +- 18 files changed, 312 insertions(+), 25 deletions(-) create mode 100644 src/features/Posts/pages/PostDetailsPage/Components/PageContent/BountyPageContent.tsx create mode 100644 src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.stories.tsx create mode 100644 src/features/Posts/pages/PostDetailsPage/Components/PageContent/StoryPageContent.tsx create mode 100644 src/features/Posts/pages/PostDetailsPage/Components/PageContent/styles.module.css diff --git a/functions/graphql/types/post.js b/functions/graphql/types/post.js index b50c7b5..e22730c 100644 --- a/functions/graphql/types/post.js +++ b/functions/graphql/types/post.js @@ -1,7 +1,6 @@ const { intArg, objectType, - stringArg, extendType, nonNull, interfaceType, diff --git a/package-lock.json b/package-lock.json index ba3cfcf..a46345c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "linkifyjs": "^3.0.5", "lodash.debounce": "^4.0.8", "lodash.throttle": "^4.1.1", + "marked": "^4.0.14", "nexus": "^1.3.0", "prisma": "3.5.0", "react": "^17.0.2", @@ -69,6 +70,7 @@ "@storybook/react": "^6.3.12", "@types/lodash.debounce": "^4.0.6", "@types/lodash.throttle": "^4.1.6", + "@types/marked": "^4.0.3", "@types/react-copy-to-clipboard": "^5.0.2", "autoprefixer": "^9.8.8", "gh-pages": "^3.2.3", @@ -9644,6 +9646,12 @@ "@types/react": "*" } }, + "node_modules/@types/marked": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.3.tgz", + "integrity": "sha512-HnMWQkLJEf/PnxZIfbm0yGJRRZYYMhb++O9M36UCTA9z53uPvVoSlAwJr3XOpDEryb7Hwl1qAx/MV6YIW1RXxg==", + "dev": true + }, "node_modules/@types/mdast": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", @@ -24915,6 +24923,17 @@ "react": ">= 0.14.0" } }, + "node_modules/marked": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.14.tgz", + "integrity": "sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/match-sorter": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz", @@ -68092,6 +68111,12 @@ "@types/react": "*" } }, + "@types/marked": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.3.tgz", + "integrity": "sha512-HnMWQkLJEf/PnxZIfbm0yGJRRZYYMhb++O9M36UCTA9z53uPvVoSlAwJr3XOpDEryb7Hwl1qAx/MV6YIW1RXxg==", + "dev": true + }, "@types/mdast": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", @@ -80011,6 +80036,11 @@ "dev": true, "requires": {} }, + "marked": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.14.tgz", + "integrity": "sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ==" + }, "match-sorter": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz", diff --git a/package.json b/package.json index 3286bf5..cc50442 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "linkifyjs": "^3.0.5", "lodash.debounce": "^4.0.8", "lodash.throttle": "^4.1.1", + "marked": "^4.0.14", "nexus": "^1.3.0", "prisma": "3.5.0", "react": "^17.0.2", @@ -119,6 +120,7 @@ "@storybook/react": "^6.3.12", "@types/lodash.debounce": "^4.0.6", "@types/lodash.throttle": "^4.1.6", + "@types/marked": "^4.0.3", "@types/react-copy-to-clipboard": "^5.0.2", "autoprefixer": "^9.8.8", "gh-pages": "^3.2.3", diff --git a/src/features/Posts/Components/PostCard/BountyCard/BountyCard.tsx b/src/features/Posts/Components/PostCard/BountyCard/BountyCard.tsx index cef4220..bbaf9e8 100644 --- a/src/features/Posts/Components/PostCard/BountyCard/BountyCard.tsx +++ b/src/features/Posts/Components/PostCard/BountyCard/BountyCard.tsx @@ -6,8 +6,19 @@ import Badge from "src/Components/Badge/Badge" import Button from "src/Components/Button/Button" import { Link } from "react-router-dom" +type BountyCardType = Pick; interface Props { - bounty: Bounty + bounty: BountyCardType } export default function BountyCard({ bounty }: Props) { return ( diff --git a/src/features/Posts/Components/PostCard/QuestionCard/QuestionCard.tsx b/src/features/Posts/Components/PostCard/QuestionCard/QuestionCard.tsx index a5a366d..357e3ab 100644 --- a/src/features/Posts/Components/PostCard/QuestionCard/QuestionCard.tsx +++ b/src/features/Posts/Components/PostCard/QuestionCard/QuestionCard.tsx @@ -3,12 +3,20 @@ import { Question } from "src/features/Posts/types" import Header from "../Header/Header" import { FiUsers } from "react-icons/fi" import Badge from "src/Components/Badge/Badge" -import Avatar from "src/features/Profiles/Components/Avatar/Avatar" -import dayjs from "dayjs" import { Link } from "react-router-dom" +type QuestionCardType = Pick; interface Props { - question: Question + question: QuestionCardType } export default function QuestionCard({ question }: Props) { return ( diff --git a/src/features/Posts/Components/PostCard/StoryCard/StoryCard.tsx b/src/features/Posts/Components/PostCard/StoryCard/StoryCard.tsx index babe031..6dd945a 100644 --- a/src/features/Posts/Components/PostCard/StoryCard/StoryCard.tsx +++ b/src/features/Posts/Components/PostCard/StoryCard/StoryCard.tsx @@ -4,8 +4,18 @@ import Header from "../Header/Header" import { BiComment } from 'react-icons/bi' import { Link } from "react-router-dom" +type StoryCardType = Pick; + interface Props { - story: Story + story: StoryCardType } export default function StoryCard({ story }: Props) { return ( diff --git a/src/features/Posts/pages/PostDetailsPage/Components/AuthorCard/AuthorCard.stories.tsx b/src/features/Posts/pages/PostDetailsPage/Components/AuthorCard/AuthorCard.stories.tsx index c5144de..34a5607 100644 --- a/src/features/Posts/pages/PostDetailsPage/Components/AuthorCard/AuthorCard.stories.tsx +++ b/src/features/Posts/pages/PostDetailsPage/Components/AuthorCard/AuthorCard.stories.tsx @@ -4,7 +4,7 @@ import { MOCK_DATA } from 'src/mocks/data'; import AuthorCard from './AuthorCard'; export default { - title: 'Posts/Post Page/Components/AuthorCard', + title: 'Posts/Post Details Page/Components/AuthorCard', component: AuthorCard, argTypes: { backgroundColor: { control: 'color' }, diff --git a/src/features/Posts/pages/PostDetailsPage/Components/PageContent/BountyPageContent.tsx b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/BountyPageContent.tsx new file mode 100644 index 0000000..55e6a2a --- /dev/null +++ b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/BountyPageContent.tsx @@ -0,0 +1,76 @@ +import Header from "src/features/Posts/Components/PostCard/Header/Header" +import { Bounty, } from "src/features/Posts/types" +import { marked } from 'marked'; +import styles from './styles.module.css' +import Badge from "src/Components/Badge/Badge"; +import { BiComment } from "react-icons/bi"; +import VotesCount from "src/Components/VotesCount/VotesCount"; +import Button from "src/Components/Button/Button"; +import { FiGithub, FiShare2 } from "react-icons/fi"; + + +interface Props { + bounty: Bounty +} + +export default function BountyPageContent({ bounty }: Props) { + return ( +
+ + {/* Header */} +
+
+

{bounty.title} Bounty

+
+ Reward: + {bounty.reward_amount} sats +
+
+ +
+ 32 Comments +
+
+
+ + + +
+
+
+
+ {/* Body */} +
+ {bounty.tags.map(tag => + {tag.title} + )} +
+ {/* Applicants */} +
+

Applicants

+
    +
  • +
    +
    +

    Work Plan

    +

    I will create the widget using nextjs, react and typescript. and also convert it into a npm package.

    +
    +
  • +
  • +
    +
    +

    Work Plan

    +

    I will create the widget using nextjs, react and typescript. and also convert it into a npm package.

    +
    +
  • +
+
+
+ ) +} diff --git a/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.stories.tsx b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.stories.tsx new file mode 100644 index 0000000..17f5d2a --- /dev/null +++ b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.stories.tsx @@ -0,0 +1,27 @@ +import { ComponentStory, ComponentMeta } from '@storybook/react'; +import { MOCK_DATA } from 'src/mocks/data'; + +import PageContent from './PageContent'; + +export default { + title: 'Posts/Post Details Page/Components/PageContent', + component: PageContent, + argTypes: { + backgroundColor: { control: 'color' }, + }, +} as ComponentMeta; + + +const Template: ComponentStory = (args) =>
+ +export const Story = Template.bind({}); +Story.args = { + post: MOCK_DATA.posts.stories[0] +} + +export const Bounty = Template.bind({}); +Bounty.args = { + post: MOCK_DATA.posts.bounties[0] +} + + diff --git a/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.tsx b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.tsx index b2b2567..3929658 100644 --- a/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.tsx +++ b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.tsx @@ -1,5 +1,12 @@ import Header from "src/features/Posts/Components/PostCard/Header/Header" -import { Post } from "src/features/Posts/types" +import { isBounty, isQuestion, isStory, Post } from "src/features/Posts/types" +import { marked } from 'marked'; +import styles from './styles.module.css' +import Badge from "src/Components/Badge/Badge"; +import { BiComment } from "react-icons/bi"; +import { RiFlashlightLine } from "react-icons/ri"; +import StoryPageContent from "./StoryPageContent"; +import BountyPageContent from "./BountyPageContent"; interface Props { @@ -7,9 +14,15 @@ interface Props { } export default function PageContent({ post }: Props) { - return ( -
-
-
- ) + if (isStory(post)) + return + + if (isBounty(post)) + return + + // if (isQuestion(post)) + // return + + return null + } diff --git a/src/features/Posts/pages/PostDetailsPage/Components/PageContent/StoryPageContent.tsx b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/StoryPageContent.tsx new file mode 100644 index 0000000..bd3b3f0 --- /dev/null +++ b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/StoryPageContent.tsx @@ -0,0 +1,39 @@ +import Header from "src/features/Posts/Components/PostCard/Header/Header" +import { Story } from "src/features/Posts/types" +import { marked } from 'marked'; +import styles from './styles.module.css' +import Badge from "src/Components/Badge/Badge"; +import { BiComment } from "react-icons/bi"; +import { RiFlashlightLine } from "react-icons/ri"; + + +interface Props { + story: Story +} + +export default function StoryPageContent({ story }: Props) { + return ( +
+
+
+

{story.title}

+
+ {story.tags.map(tag => + {tag.title} + )} +
+
+
+ {story.votes_count} votes +
+
+ 32 Comments +
+
+
+ +
+
+
+ ) +} diff --git a/src/features/Posts/pages/PostDetailsPage/Components/PageContent/styles.module.css b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/styles.module.css new file mode 100644 index 0000000..8b3abea --- /dev/null +++ b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/styles.module.css @@ -0,0 +1,32 @@ +.body h1 { + font-size: 48px; + line-height: 54px; + margin-bottom: min(0.5em); +} +.body h2 { + font-size: 36px; + line-height: 50px; + margin-bottom: min(0.5em); +} +.body h3 { + font-size: 29px; + line-height: 40px; + margin-bottom: min(0.5em); +} +.body h4 { + font-size: 22px; + line-height: 31px; + margin-bottom: min(0.5em); +} +.body h5 { + font-size: 19px; + line-height: 26px; + margin-bottom: min(0.5em); +} + +.body p, +.body ul { + font-size: 16px; + line-height: 22px; + margin-bottom: 1.5em; +} diff --git a/src/features/Posts/pages/PostDetailsPage/Components/PostActions/PostAction.stories.tsx b/src/features/Posts/pages/PostDetailsPage/Components/PostActions/PostAction.stories.tsx index 561d356..103e765 100644 --- a/src/features/Posts/pages/PostDetailsPage/Components/PostActions/PostAction.stories.tsx +++ b/src/features/Posts/pages/PostDetailsPage/Components/PostActions/PostAction.stories.tsx @@ -3,7 +3,7 @@ import { ComponentStory, ComponentMeta } from '@storybook/react'; import PostActions from './PostActions'; export default { - title: 'Posts/Post Page/Components/PostActions', + title: 'Posts/Post Details Page/Components/PostActions', component: PostActions, argTypes: { backgroundColor: { control: 'color' }, @@ -11,7 +11,7 @@ export default { } as ComponentMeta; -const Template: ComponentStory = (args) =>
+const Template: ComponentStory = (args) =>
export const Default = Template.bind({}); Default.args = { diff --git a/src/features/Posts/pages/PostDetailsPage/Components/PostActions/PostActions.tsx b/src/features/Posts/pages/PostDetailsPage/Components/PostActions/PostActions.tsx index a89d156..f225b1e 100644 --- a/src/features/Posts/pages/PostDetailsPage/Components/PostActions/PostActions.tsx +++ b/src/features/Posts/pages/PostDetailsPage/Components/PostActions/PostActions.tsx @@ -22,9 +22,9 @@ export default function PostActions() { ] return ( -
    +
      {actions.map((action, idx) =>
    • {action.value} diff --git a/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx b/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx index 8e28a87..62d177d 100644 --- a/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx +++ b/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx @@ -5,6 +5,7 @@ import { useAppSelector, useInfiniteQuery } from 'src/utils/hooks' import PostsList from '../../Components/PostsList/PostsList' import TrendingCard from '../../Components/TrendingCard/TrendingCard' import AuthorCard from './Components/AuthorCard/AuthorCard' +import PageContent from './Components/PageContent/PageContent' import PostActions from './Components/PostActions/PostActions' import styles from './styles.module.css' @@ -38,9 +39,8 @@ export default function PostDetailsPage() { -

      - Lorem ipsum, dolor sit amet consectetur adipisicing elit. Nesciunt, tenetur sapiente magnam pariatur, optio, veniam debitis ab earum tempora repellendus vel? Sed quidem commodi deserunt dolore ex cupiditate ab obcaecati et nisi incidunt facilis repellat ea voluptatem molestiae, minima placeat dolorem expedita dolor quas esse. At mollitia perferendis nihil iste quisquam facilis fuga cupiditate vero, repellat eveniet ipsam, voluptatem ea in voluptatibus alias voluptates est soluta assumenda quam quaerat consequatur? Nobis aliquid atque facere, nostrum velit obcaecati earum eaque dolores et tempora repellendus ratione explicabo repellat, porro tempore unde totam molestiae quia voluptatum officia, ipsum dolorem non pariatur? Possimus esse voluptatem debitis, quod odit nobis optio reiciendis ullam repudiandae cum ratione animi sequi a? Soluta animi sit facere sint facilis incidunt aspernatur quia distinctio suscipit laboriosam magnam ex maxime, vel quas voluptate harum ut. Voluptatum quasi nemo itaque autem repellat possimus ab enim recusandae libero suscipit quas labore, saepe praesentium nesciunt pariatur velit cupiditate soluta! Possimus vel provident incidunt aperiam quaerat impedit consequatur nesciunt consectetur. Facere modi sequi itaque, tempore ea nemo similique aliquam harum, molestiae officia ullam animi repellat consequuntur odio. Provident tenetur voluptas error temporibus porro, sequi reiciendis fugiat id. Laboriosam minima aperiam error, commodi doloribus odit libero alias ipsa molestiae maiores non tempore dolorem veniam quod quo ex id, velit necessitatibus neque sed? Sit dicta maxime neque amet non architecto ab cum eaque provident. Aut, omnis veniam ex ut quod repellat. Minus eius magni ipsum ducimus, tempora nemo suscipit perspiciatis facilis vitae placeat impedit? Accusamus natus iusto nisi, repudiandae minus quibusdam hic? Vero magni tenetur ipsum voluptate suscipit eos, pariatur nulla labore corrupti atque repellat provident velit ab iusto perspiciatis error eum, earum facilis ut ea, quas quod magnam. Suscipit iusto in magni ratione doloribus corrupti, quis esse repellat odit fugiat minus at, pariatur aliquid voluptate id perspiciatis provident ad dolores accusantium similique ea. Quos numquam officiis ad rem repellendus. Tempora quae totam suscipit dolorem non aperiam repellat consectetur tenetur nemo harum asperiores deserunt veniam, laboriosam iusto quas molestiae modi! Fugiat ea recusandae libero provident veritatis modi vel dolor consectetur similique officiis quo veniam quos mollitia, cumque autem ex eius quis aliquam dignissimos vero. Deserunt, iure, ducimus ipsam minima dolor corporis blanditiis incidunt vitae velit saepe obcaecati accusamus libero, optio quidem atque totam doloremque natus harum alias consectetur odit. Ea, temporibus alias ex tempore, similique praesentium aliquam, inventore corrupti nulla repellat autem esse. Nisi at aperiam reprehenderit, maiores mollitia exercitationem provident ipsa odio sed nihil iste quo aspernatur vero architecto repudiandae! Tempora, doloribus cupiditate itaque eveniet corporis corrupti et molestias. Nulla consequatur neque pariatur laboriosam provident vero exercitationem eligendi numquam, corporis eius aliquam accusamus a minima cumque quia, molestias atque at, quidem aperiam! Aut ullam vel eligendi. Vitae nobis ad minus sed exercitationem? Expedita, laudantium ipsum nemo adipisci qui quam distinctio aliquid facere eligendi consequatur repellat, animi ex a assumenda dicta temporibus illo voluptatum aspernatur non architecto natus iste pariatur. Error fugit cumque impedit doloribus qui, iste laudantium voluptate aspernatur, quod voluptatibus corrupti, quidem nostrum. Aperiam fugit dicta error, molestias tempore officiis, repellat nisi nam adipisci optio in iusto totam. Tempore optio facilis blanditiis velit eum ut, asperiores et numquam, aperiam quidem veritatis aliquid! Cupiditate exercitationem quibusdam consequuntur optio nemo velit, at quo obcaecati voluptates repellat beatae rerum pariatur nostrum officiis culpa molestiae dolorum sapiente dignissimos facilis ullam quisquam consequatur, accusantium vitae? Temporibus odio similique aspernatur autem, culpa est ratione quaerat eum vel accusamus distinctio eius adipisci animi unde iure debitis eos doloremque officia optio aliquam consequuntur nihil ducimus consequatur. Blanditiis dolor, maiores dolore suscipit ipsam officia ad. Corporis et ratione voluptate ut tempora voluptatem, quisquam aspernatur animi labore aut eius modi beatae ipsam obcaecati numquam voluptatum reiciendis excepturi dignissimos at fugiat natus quidem ad necessitatibus. Expedita inventore dignissimos neque quis dolorum iure non veniam quia, voluptas sint itaque sed cum enim. Ut nesciunt delectus ipsam? Delectus sunt ab enim dolores natus? Libero animi assumenda sint cupiditate nulla id deserunt unde error praesentium omnis suscipit nisi veritatis laudantium aperiam, impedit alias temporibus velit eligendi incidunt? Impedit voluptatibus voluptates nostrum tempora tenetur magni totam quo hic ab quod non, minima, aliquam officia commodi temporibus nisi pariatur rerum voluptatum! Nobis, cumque voluptatibus quisquam tempora corrupti dolore perspiciatis quis culpa? -

      + +