From 80c9e31467beaa82385b409ebe0f428708fa8a60 Mon Sep 17 00:00:00 2001 From: MTG2000 Date: Fri, 20 May 2022 15:32:38 +0300 Subject: [PATCH] feat: connect feed filters apis with ui, change filters list style --- functions/graphql/nexus-typegen.ts | 22 +-- functions/graphql/schema.graphql | 8 +- functions/graphql/types/category.js | 2 +- functions/graphql/types/post.js | 54 +++++- functions/graphql/types/project.js | 2 +- functions/graphql/types/users.js | 3 +- .../migration.sql | 9 + .../migration.sql | 17 ++ prisma/schema.prisma | 4 +- src/App.tsx | 2 +- src/Components/VoteButton/VoteButton.tsx | 42 +++-- src/Components/VoteButton/styles.module.css | 1 + .../pages/HackathonsPage/HackathonsPage.tsx | 2 +- .../Comments/CommentCard/CommentCard.tsx | 2 +- .../Posts/Components/Comments/types.ts | 2 +- .../PostCard/BountyCard/BountyCard.tsx | 4 +- .../Components/PostCard/Header/Header.tsx | 20 ++- .../PostCard/QuestionCard/QuestionCard.tsx | 8 +- .../PostCard/StoryCard/StoryCard.tsx | 4 +- .../Components/TrendingCard/TrendingCard.tsx | 2 +- .../TrendingCard/trendingPosts.graphql | 6 +- .../Posts/pages/FeedPage/FeedPage.tsx | 14 +- .../PopularCategories.stories.tsx | 20 --- .../PopularCategories/PopularCategories.tsx | 54 ------ .../PopularTopicsFilter.stories.tsx | 20 +++ .../PopularTopicsFilter.tsx | 74 +++++++++ .../PopularTopicsFilter/popularTopics.graphql | 7 + .../Posts/pages/FeedPage/SortBy/SortBy.tsx | 2 +- .../Posts/pages/FeedPage/feed.graphql | 20 +-- .../Components/AuthorCard/AuthorCard.tsx | 2 +- .../BountyPageContent/BountyPageContent.tsx | 8 +- .../Components/PostActions/PostActions.tsx | 10 +- .../QuestionPageContent.tsx | 9 +- .../StoryPageContent/StoryPageContent.tsx | 13 +- .../pages/PostDetailsPage/PostDetailsPage.tsx | 2 +- .../pages/PostDetailsPage/postDetails.graphql | 22 +-- src/features/Posts/types/posts.interface.ts | 4 +- .../pages/ExplorePage/ExplorePage.tsx | 14 +- .../ProjectsRow/ProjectsRow.Skeleton.tsx | 4 +- .../ExplorePage/ProjectsRow/ProjectsRow.tsx | 4 +- src/graphql/index.tsx | 155 +++++++++++++----- src/mocks/data/hackathon.ts | 2 +- src/mocks/data/posts.ts | 12 +- src/mocks/handlers.ts | 2 +- src/styles/index.scss | 3 +- src/utils/apollo.ts | 2 +- 46 files changed, 445 insertions(+), 250 deletions(-) create mode 100644 prisma/migrations/20220520073846_rename_created_at_to_created_at/migration.sql create mode 100644 prisma/migrations/20220520084451_add_name_column_to_users_table/migration.sql delete mode 100644 src/features/Posts/pages/FeedPage/PopularCategories/PopularCategories.stories.tsx delete mode 100644 src/features/Posts/pages/FeedPage/PopularCategories/PopularCategories.tsx create mode 100644 src/features/Posts/pages/FeedPage/PopularTopicsFilter/PopularTopicsFilter.stories.tsx create mode 100644 src/features/Posts/pages/FeedPage/PopularTopicsFilter/PopularTopicsFilter.tsx create mode 100644 src/features/Posts/pages/FeedPage/PopularTopicsFilter/popularTopics.graphql diff --git a/functions/graphql/nexus-typegen.ts b/functions/graphql/nexus-typegen.ts index 9242718..96c1137 100644 --- a/functions/graphql/nexus-typegen.ts +++ b/functions/graphql/nexus-typegen.ts @@ -58,10 +58,8 @@ export interface NexusGenObjects { cover_image: string; // String! createdAt: NexusGenScalars['Date']; // Date! deadline: string; // String! - excerpt: string; // String! id: number; // Int! reward_amount: number; // Int! - tags: NexusGenRootTypes['Tag'][]; // [Tag!]! title: string; // String! votes_count: number; // Int! } @@ -87,7 +85,7 @@ export interface NexusGenObjects { PostComment: { // root type author: NexusGenRootTypes['User']; // User! body: string; // String! - created_at: NexusGenScalars['Date']; // Date! + createdAt: NexusGenScalars['Date']; // Date! id: number; // Int! parentId?: number | null; // Int votes_count: number; // Int! @@ -109,9 +107,7 @@ export interface NexusGenObjects { answers_count: number; // Int! body: string; // String! createdAt: NexusGenScalars['Date']; // Date! - excerpt: string; // String! id: number; // Int! - tags: NexusGenRootTypes['Tag'][]; // [Tag!]! title: string; // String! votes_count: number; // Int! } @@ -119,9 +115,7 @@ export interface NexusGenObjects { body: string; // String! cover_image: string; // String! createdAt: NexusGenScalars['Date']; // Date! - excerpt: string; // String! id: number; // Int! - tags: NexusGenRootTypes['Tag'][]; // [Tag!]! title: string; // String! votes_count: number; // Int! } @@ -135,8 +129,8 @@ export interface NexusGenObjects { title: string; // String! } User: { // root type + avatar: string; // String! id: number; // Int! - image: string; // String! name: string; // String! } Vote: { // root type @@ -222,7 +216,7 @@ export interface NexusGenFieldTypes { PostComment: { // field return type author: NexusGenRootTypes['User']; // User! body: string; // String! - created_at: NexusGenScalars['Date']; // Date! + createdAt: NexusGenScalars['Date']; // Date! id: number; // Int! parentId: number | null; // Int votes_count: number; // Int! @@ -254,6 +248,7 @@ export interface NexusGenFieldTypes { getTrendingPosts: NexusGenRootTypes['Post'][]; // [Post!]! hottestProjects: NexusGenRootTypes['Project'][]; // [Project!]! newProjects: NexusGenRootTypes['Project'][]; // [Project!]! + popularTopics: NexusGenRootTypes['Topic'][]; // [Topic!]! projectsByCategory: NexusGenRootTypes['Project'][]; // [Project!]! searchProjects: NexusGenRootTypes['Project'][]; // [Project!]! } @@ -295,8 +290,8 @@ export interface NexusGenFieldTypes { title: string; // String! } User: { // field return type + avatar: string; // String! id: number; // Int! - image: string; // String! name: string; // String! } Vote: { // field return type @@ -321,7 +316,6 @@ export interface NexusGenFieldTypes { createdAt: NexusGenScalars['Date']; // Date! excerpt: string; // String! id: number; // Int! - tags: NexusGenRootTypes['Tag'][]; // [Tag!]! title: string; // String! votes_count: number; // Int! } @@ -380,7 +374,7 @@ export interface NexusGenFieldTypeNames { PostComment: { // field return type name author: 'User' body: 'String' - created_at: 'Date' + createdAt: 'Date' id: 'Int' parentId: 'Int' votes_count: 'Int' @@ -412,6 +406,7 @@ export interface NexusGenFieldTypeNames { getTrendingPosts: 'Post' hottestProjects: 'Project' newProjects: 'Project' + popularTopics: 'Topic' projectsByCategory: 'Project' searchProjects: 'Project' } @@ -453,8 +448,8 @@ export interface NexusGenFieldTypeNames { title: 'String' } User: { // field return type name + avatar: 'String' id: 'Int' - image: 'String' name: 'String' } Vote: { // field return type name @@ -479,7 +474,6 @@ export interface NexusGenFieldTypeNames { createdAt: 'Date' excerpt: 'String' id: 'Int' - tags: 'Tag' title: 'String' votes_count: 'Int' } diff --git a/functions/graphql/schema.graphql b/functions/graphql/schema.graphql index 5164ddb..0a27383 100644 --- a/functions/graphql/schema.graphql +++ b/functions/graphql/schema.graphql @@ -73,7 +73,6 @@ interface PostBase { createdAt: Date! excerpt: String! id: Int! - tags: [Tag!]! title: String! votes_count: Int! } @@ -81,7 +80,7 @@ interface PostBase { type PostComment { author: User! body: String! - created_at: Date! + createdAt: Date! id: Int! parentId: Int votes_count: Int! @@ -108,13 +107,14 @@ type Query { allProjects(skip: Int = 0, take: Int = 50): [Project!]! allTopics: [Topic!]! getCategory(id: Int!): Category! - getFeed(skip: Int = 0, sortBy: String = "all", take: Int = 10, topic: Int): [Post!]! + getFeed(skip: Int = 0, sortBy: String = "all", take: Int = 10, topic: Int = 0): [Post!]! getLnurlDetailsForProject(project_id: Int!): LnurlDetails! getPostById(id: Int!, type: POST_TYPE!): Post! getProject(id: Int!): Project! getTrendingPosts: [Post!]! hottestProjects(skip: Int = 0, take: Int = 50): [Project!]! newProjects(skip: Int = 0, take: Int = 50): [Project!]! + popularTopics: [Topic!]! projectsByCategory(category_id: Int!, skip: Int = 0, take: Int = 10): [Project!]! searchProjects(search: String!, skip: Int = 0, take: Int = 50): [Project!]! } @@ -161,8 +161,8 @@ type Topic { } type User { + avatar: String! id: Int! - image: String! name: String! } diff --git a/functions/graphql/types/category.js b/functions/graphql/types/category.js index 1c888d4..7cfcf5b 100644 --- a/functions/graphql/types/category.js +++ b/functions/graphql/types/category.js @@ -18,7 +18,7 @@ const Category = objectType({ t.nonNull.int('votes_sum', { async resolve(parent) { - const projects = await prisma.category.findUnique({ where: { id: parent.id } }).project(); + const projects = await prisma.category.findUnique({ where: { id: parent.id } }).project() return projects.reduce((total, project) => total + project.votes_count, 0); } }); diff --git a/functions/graphql/types/post.js b/functions/graphql/types/post.js index 136d364..688a165 100644 --- a/functions/graphql/types/post.js +++ b/functions/graphql/types/post.js @@ -52,6 +52,26 @@ const allTopics = extendType({ } }) + +const popularTopics = extendType({ + type: "Query", + definition(t) { + t.nonNull.list.nonNull.field('popularTopics', { + type: "Topic", + resolve: () => { + return prisma.topic.findMany({ + take: 6, + orderBy: { + stories: { + _count: 'desc' + } + }, + }); + } + }) + } +}) + const PostBase = interfaceType({ name: 'PostBase', resolveType(item) { @@ -61,11 +81,10 @@ const PostBase = interfaceType({ t.nonNull.int('id'); t.nonNull.string('title'); t.nonNull.date('createdAt'); - t.nonNull.string('excerpt'); - t.nonNull.string('body'); - t.nonNull.list.nonNull.field('tags', { - type: "Tag" + t.nonNull.string('excerpt', { + resolve: (parent) => parent.body.slice(0, 150) }); + t.nonNull.string('body'); t.nonNull.int('votes_count'); }, }) @@ -82,7 +101,10 @@ const Story = objectType({ t.nonNull.list.nonNull.field('comments', { type: "PostComment", resolve: (parent) => prisma.story.findUnique({ where: { id: parent.id } }).comments() - + }); + t.nonNull.list.nonNull.field('tags', { + type: "Tag", + resolve: (parent) => prisma.story.findUnique({ where: { id: parent.id } }).tags() }); t.nonNull.int('comments_count', { resolve: async (parent) => { @@ -149,6 +171,11 @@ const Bounty = objectType({ return prisma.bounty.findUnique({ where: { id: parent.id } }).user(); } }); + + t.nonNull.list.nonNull.field('tags', { + type: "Tag", + resolve: (parent) => [] + }); }, }) @@ -160,6 +187,12 @@ const Question = objectType({ resolve: () => 'Question', }); + + t.nonNull.list.nonNull.field('tags', { + type: "Tag", + resolve: (parent) => prisma.question.findUnique({ where: { id: parent.id } }).tags() + }); + t.nonNull.int('answers_count'); t.nonNull.list.nonNull.field('comments', { type: "PostComment", @@ -181,7 +214,7 @@ const PostComment = objectType({ name: 'PostComment', definition(t) { t.nonNull.int('id'); - t.nonNull.date('created_at'); + t.nonNull.date('createdAt'); t.nonNull.string('body'); t.nonNull.field('author', { type: "User" @@ -212,13 +245,17 @@ const getFeed = extendType({ sortBy: stringArg({ default: "all" }), // all, popular, trending, newest - topic: intArg() + topic: intArg({ + default: 0 + }) }, resolve(_, { take, skip, topic, sortBy, }) { + + return prisma.story.findMany({ orderBy: { createdAt: "desc" }, where: { - topic_id: topic, + topic_id: topic ? topic : undefined, }, skip, take, @@ -296,6 +333,7 @@ module.exports = { Post, // Queries allTopics, + popularTopics, getFeed, getPostById, getTrendingPosts diff --git a/functions/graphql/types/project.js b/functions/graphql/types/project.js index 92e071a..4887239 100644 --- a/functions/graphql/types/project.js +++ b/functions/graphql/types/project.js @@ -123,7 +123,7 @@ const newProjects = extendType({ const take = args.take || 50; const skip = args.skip || 0; return prisma.project.findMany({ - orderBy: { created_at: "desc" }, + orderBy: { createdAt: "desc" }, skip, take, }); diff --git a/functions/graphql/types/users.js b/functions/graphql/types/users.js index d6bd504..25cb206 100644 --- a/functions/graphql/types/users.js +++ b/functions/graphql/types/users.js @@ -5,8 +5,7 @@ const User = objectType({ definition(t) { t.nonNull.int('id'); t.nonNull.string('name'); - t.nonNull.string('image'); - + t.nonNull.string('avatar'); } }) diff --git a/prisma/migrations/20220520073846_rename_created_at_to_created_at/migration.sql b/prisma/migrations/20220520073846_rename_created_at_to_created_at/migration.sql new file mode 100644 index 0000000..5a9cc09 --- /dev/null +++ b/prisma/migrations/20220520073846_rename_created_at_to_created_at/migration.sql @@ -0,0 +1,9 @@ +/* + Warnings: + + - You are about to drop the column `created_at` on the `Project` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "Project" DROP COLUMN "created_at", +ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP; diff --git a/prisma/migrations/20220520084451_add_name_column_to_users_table/migration.sql b/prisma/migrations/20220520084451_add_name_column_to_users_table/migration.sql new file mode 100644 index 0000000..d632f20 --- /dev/null +++ b/prisma/migrations/20220520084451_add_name_column_to_users_table/migration.sql @@ -0,0 +1,17 @@ +/* + Warnings: + + - You are about to drop the column `username` on the `User` table. All the data in the column will be lost. + - A unique constraint covering the columns `[name]` on the table `User` will be added. If there are existing duplicate values, this will fail. + - Added the required column `name` to the `User` table without a default value. This is not possible if the table is not empty. + +*/ +-- DropIndex +DROP INDEX "User_username_key"; + +-- AlterTable +ALTER TABLE "User" DROP COLUMN "username", +ADD COLUMN "name" TEXT NOT NULL; + +-- CreateIndex +CREATE UNIQUE INDEX "User_name_key" ON "User"("name"); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index f83a7cd..2ce991c 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -37,7 +37,7 @@ model Vote { model User { id Int @id @default(autoincrement()) - username String @unique + name String @unique lightning_address String? avatar String @@ -74,7 +74,7 @@ model Project { category_id Int votes_count Int @default(0) vote Vote[] - created_at DateTime @default(now()) + createdAt DateTime @default(now()) awards Award[] tags Tag[] diff --git a/src/App.tsx b/src/App.tsx index bb396a5..5df2256 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -39,7 +39,7 @@ function App() { - return
+ return
}> diff --git a/src/Components/VoteButton/VoteButton.tsx b/src/Components/VoteButton/VoteButton.tsx index 006f85b..d9e7d57 100644 --- a/src/Components/VoteButton/VoteButton.tsx +++ b/src/Components/VoteButton/VoteButton.tsx @@ -199,20 +199,36 @@ export default function VoteButton({ key={increment.id} className={styles.vote_counter} >+{increment.value})} - {sparks.map(spark => -
+
) - } + opacity: 1, + scale: 1, + top: 0, + left: 0, + color: 'green' + }} + /> + {sparks.map(spark => +
) + } +
+
) diff --git a/src/Components/VoteButton/styles.module.css b/src/Components/VoteButton/styles.module.css index 89c1f1b..8350e48 100644 --- a/src/Components/VoteButton/styles.module.css +++ b/src/Components/VoteButton/styles.module.css @@ -136,6 +136,7 @@ transform: scale(var(--scale)); opacity: 0; will-change: transform; + z-index: 3000; animation-name: fly-spark-1; animation-duration: calc(var(--animationSpeed) * 1s); diff --git a/src/features/Hackathons/pages/HackathonsPage/HackathonsPage.tsx b/src/features/Hackathons/pages/HackathonsPage/HackathonsPage.tsx index f6a295b..744d934 100644 --- a/src/features/Hackathons/pages/HackathonsPage/HackathonsPage.tsx +++ b/src/features/Hackathons/pages/HackathonsPage/HackathonsPage.tsx @@ -18,7 +18,7 @@ export default function HackathonsPage() { take: 10, skip: 0, sortBy: sortByFilter, - category: topicsFilter + topic: Number(topicsFilter) }, }) const { fetchMore, isFetchingMore } = useInfiniteQuery(feedQuery, 'getFeed') diff --git a/src/features/Posts/Components/Comments/CommentCard/CommentCard.tsx b/src/features/Posts/Components/Comments/CommentCard/CommentCard.tsx index dfffaa5..0349996 100644 --- a/src/features/Posts/Components/Comments/CommentCard/CommentCard.tsx +++ b/src/features/Posts/Components/Comments/CommentCard/CommentCard.tsx @@ -12,7 +12,7 @@ interface Props { export default function CommentCard({ comment, onReply }: Props) { return (
-
+

{comment.body}

diff --git a/src/features/Posts/Components/Comments/types.ts b/src/features/Posts/Components/Comments/types.ts index 1d563f1..85ac024 100644 --- a/src/features/Posts/Components/Comments/types.ts +++ b/src/features/Posts/Components/Comments/types.ts @@ -4,7 +4,7 @@ import { Author } from "src/features/Posts/types"; export interface Comment { id: number author: Author - created_at: string + createdAt: string body: string votes_count: number parentId: number | null diff --git a/src/features/Posts/Components/PostCard/BountyCard/BountyCard.tsx b/src/features/Posts/Components/PostCard/BountyCard/BountyCard.tsx index 0e1455b..7547c30 100644 --- a/src/features/Posts/Components/PostCard/BountyCard/BountyCard.tsx +++ b/src/features/Posts/Components/PostCard/BountyCard/BountyCard.tsx @@ -12,7 +12,7 @@ export type BountyCardType = Pick
-
+
diff --git a/src/features/Posts/Components/PostCard/Header/Header.tsx b/src/features/Posts/Components/PostCard/Header/Header.tsx index a73325f..47bbc21 100644 --- a/src/features/Posts/Components/PostCard/Header/Header.tsx +++ b/src/features/Posts/Components/PostCard/Header/Header.tsx @@ -6,7 +6,7 @@ interface Props { author: { id: number, name: string, - image: string + avatar: string } date: string; size?: 'sm' | 'md' | 'lg'; @@ -27,21 +27,25 @@ const nameSize: UnionToObjectKeys = { export default function Header({ size = 'md', - showTimeAgo = true, + showTimeAgo = false, ...props }: Props) { const passedTime = dayjs().diff(props.date, 'hour'); - const dateToShow = passedTime < 24 ? - `${dayjs().diff(props.date, 'hour')}h ago` - : - dayjs(props.date).format('MMMM DD'); + + const dateToShow = () => { + const passedTime = dayjs().diff(props.date, 'hour'); + if (passedTime === 0) return 'now'; + if (passedTime < 24) return `${dayjs().diff(props.date, 'hour')}h ago` + return dayjs(props.date).format('MMMM DD'); + } + return (
- +

{props.author.name}

-

{dateToShow}

+

{dateToShow()}

{/* {showTimeAgo &&

{dayjs().diff(props.date, 'hour') < 24 ? `${dayjs().diff(props.date, 'hour')}h ago` : undefined} diff --git a/src/features/Posts/Components/PostCard/QuestionCard/QuestionCard.tsx b/src/features/Posts/Components/PostCard/QuestionCard/QuestionCard.tsx index b09a584..ffa5d0a 100644 --- a/src/features/Posts/Components/PostCard/QuestionCard/QuestionCard.tsx +++ b/src/features/Posts/Components/PostCard/QuestionCard/QuestionCard.tsx @@ -11,7 +11,7 @@ export type QuestionCardType = Pick> }; interface Props { @@ -33,7 +33,7 @@ export default function QuestionCard({ question }: Props) {

{/* */}
-
+

{question.title}

@@ -61,7 +61,7 @@ export default function QuestionCard({ question }: Props) {
{question.comments.slice(0, 2).map(comment =>
-
+

{trimText(comment.body, 80)}

)}
diff --git a/src/features/Posts/Components/PostCard/StoryCard/StoryCard.tsx b/src/features/Posts/Components/PostCard/StoryCard/StoryCard.tsx index cbb9d5e..890b3e6 100644 --- a/src/features/Posts/Components/PostCard/StoryCard/StoryCard.tsx +++ b/src/features/Posts/Components/PostCard/StoryCard/StoryCard.tsx @@ -10,7 +10,7 @@ export type StoryCardType = Pick
-
+

{story.title}

diff --git a/src/features/Posts/Components/TrendingCard/TrendingCard.tsx b/src/features/Posts/Components/TrendingCard/TrendingCard.tsx index be83a81..14b0e68 100644 --- a/src/features/Posts/Components/TrendingCard/TrendingCard.tsx +++ b/src/features/Posts/Components/TrendingCard/TrendingCard.tsx @@ -26,7 +26,7 @@ export default function TrendingCard() { trendingPosts.data?.getTrendingPosts.map(post => { return
  • - +

    {post.title}

  • diff --git a/src/features/Posts/Components/TrendingCard/trendingPosts.graphql b/src/features/Posts/Components/TrendingCard/trendingPosts.graphql index 2be00bb..76f5baf 100644 --- a/src/features/Posts/Components/TrendingCard/trendingPosts.graphql +++ b/src/features/Posts/Components/TrendingCard/trendingPosts.graphql @@ -5,7 +5,7 @@ query TrendingPosts { title author { id - image + avatar } } ... on Bounty { @@ -13,7 +13,7 @@ query TrendingPosts { title author { id - image + avatar } } @@ -22,7 +22,7 @@ query TrendingPosts { title author { id - image + avatar } } } diff --git a/src/features/Posts/pages/FeedPage/FeedPage.tsx b/src/features/Posts/pages/FeedPage/FeedPage.tsx index f4283b8..e905a94 100644 --- a/src/features/Posts/pages/FeedPage/FeedPage.tsx +++ b/src/features/Posts/pages/FeedPage/FeedPage.tsx @@ -4,7 +4,7 @@ import { useFeedQuery } from 'src/graphql' import { useAppSelector, useInfiniteQuery } from 'src/utils/hooks' import PostsList from '../../Components/PostsList/PostsList' import TrendingCard from '../../Components/TrendingCard/TrendingCard' -import PopularCategories from './PopularCategories/PopularCategories' +import PopularTopicsFilter from './PopularTopicsFilter/PopularTopicsFilter' import SortBy from './SortBy/SortBy' import styles from './styles.module.scss' @@ -12,15 +12,15 @@ import styles from './styles.module.scss' export default function FeedPage() { const [sortByFilter, setSortByFilter] = useState('all') - const [categoryFilter, setCategoryFilter] = useState('all') + const [topicFilter, setTopicFilter] = useState(null) const feedQuery = useFeedQuery({ variables: { - take: 10, + take: 3, skip: 0, sortBy: sortByFilter, - category: categoryFilter + topic: topicFilter }, }) const { fetchMore, isFetchingMore } = useInfiniteQuery(feedQuery, 'getFeed') @@ -42,9 +42,9 @@ export default function FeedPage() { -
    -
    +
    diff --git a/src/features/Posts/pages/FeedPage/PopularCategories/PopularCategories.stories.tsx b/src/features/Posts/pages/FeedPage/PopularCategories/PopularCategories.stories.tsx deleted file mode 100644 index 65eec3e..0000000 --- a/src/features/Posts/pages/FeedPage/PopularCategories/PopularCategories.stories.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { ComponentStory, ComponentMeta } from '@storybook/react'; - -import PopularCategories from './PopularCategories'; - -export default { - title: 'Posts/Feed Page/Components/PopularCategories', - component: PopularCategories, - argTypes: { - backgroundColor: { control: 'color' }, - }, -} as ComponentMeta; - - -const Template: ComponentStory = (args) =>
    - -export const Default = Template.bind({}); -Default.args = { -} - - diff --git a/src/features/Posts/pages/FeedPage/PopularCategories/PopularCategories.tsx b/src/features/Posts/pages/FeedPage/PopularCategories/PopularCategories.tsx deleted file mode 100644 index ea3adac..0000000 --- a/src/features/Posts/pages/FeedPage/PopularCategories/PopularCategories.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import React, { useState } from 'react' - -const filters = [ - { - text: "🔥 All", - value: 'all' - }, { - text: "Lightning Network", - value: 'lightning-network' - }, { - text: "Bitcoin", - value: 'bitcoin' - }, { - text: "Cybersecurity", - value: 'cybersecurity' - }, { - text: "Bounties", - value: 'bounties' - }, { - text: "Grants", - value: 'Grants' - }, -] - -interface Props { - filterChanged?: (newFilter: string) => void -} - -export default function PopularCategories({ filterChanged }: Props) { - - const [selected, setSelected] = useState(filters[0].value); - - const filterClicked = (newValue: string) => { - if (selected === newValue) - return - setSelected(newValue); - filterChanged?.(newValue); - } - - return ( -
    -

    Popular Categories

    -
      - {filters.map((f, idx) =>
    • filterClicked(f.value)} - > - {f.text} -
    • )} -
    -
    - ) -} diff --git a/src/features/Posts/pages/FeedPage/PopularTopicsFilter/PopularTopicsFilter.stories.tsx b/src/features/Posts/pages/FeedPage/PopularTopicsFilter/PopularTopicsFilter.stories.tsx new file mode 100644 index 0000000..f8f11e8 --- /dev/null +++ b/src/features/Posts/pages/FeedPage/PopularTopicsFilter/PopularTopicsFilter.stories.tsx @@ -0,0 +1,20 @@ +import { ComponentStory, ComponentMeta } from '@storybook/react'; + +import PopularTopicsFilter from './PopularTopicsFilter'; + +export default { + title: 'Posts/Feed Page/Components/Popular Topics Filter', + component: PopularTopicsFilter, + argTypes: { + backgroundColor: { control: 'color' }, + }, +} as ComponentMeta; + + +const Template: ComponentStory = (args) =>
    + +export const Default = Template.bind({}); +Default.args = { +} + + diff --git a/src/features/Posts/pages/FeedPage/PopularTopicsFilter/PopularTopicsFilter.tsx b/src/features/Posts/pages/FeedPage/PopularTopicsFilter/PopularTopicsFilter.tsx new file mode 100644 index 0000000..9989772 --- /dev/null +++ b/src/features/Posts/pages/FeedPage/PopularTopicsFilter/PopularTopicsFilter.tsx @@ -0,0 +1,74 @@ +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) => void +} + +export default function PopularTopicsFilter({ filterChanged }: Props) { + + const [selected, setSelected] = useState(filters[0].value); + + const topicsQuery = usePopularTopicsQuery(); + + + const filterClicked = (newValue: number) => { + if (selected === newValue) + return + setSelected(newValue); + filterChanged?.(newValue); + } + + return ( +
    +

    Topics

    +
      + {topicsQuery.loading ? + Array(4).fill(0).map((_, idx) =>
    • + + + +
    • + ) + : + topicsQuery.data?.popularTopics.map((f, idx) =>
    • filterClicked(f.id)} + > + {f.icon} + + {f.title} + +
    • )} +
    +
    + ) +} diff --git a/src/features/Posts/pages/FeedPage/PopularTopicsFilter/popularTopics.graphql b/src/features/Posts/pages/FeedPage/PopularTopicsFilter/popularTopics.graphql new file mode 100644 index 0000000..9fff9f4 --- /dev/null +++ b/src/features/Posts/pages/FeedPage/PopularTopicsFilter/popularTopics.graphql @@ -0,0 +1,7 @@ +query PopularTopics { + popularTopics { + id + title + icon + } +} diff --git a/src/features/Posts/pages/FeedPage/SortBy/SortBy.tsx b/src/features/Posts/pages/FeedPage/SortBy/SortBy.tsx index 265a7b9..d4746fe 100644 --- a/src/features/Posts/pages/FeedPage/SortBy/SortBy.tsx +++ b/src/features/Posts/pages/FeedPage/SortBy/SortBy.tsx @@ -29,7 +29,7 @@ export default function SortBy({ filterChanged }: Props) { } return ( -
    +

    Sort By

      {filters.map((f, idx) =>
    • - +

      {author.name}

      Joined on {dayjs(author.join_date).format('MMMM DD, YYYY')}

      diff --git a/src/features/Posts/pages/PostDetailsPage/Components/BountyPageContent/BountyPageContent.tsx b/src/features/Posts/pages/PostDetailsPage/Components/BountyPageContent/BountyPageContent.tsx index 87f3d80..23483c7 100644 --- a/src/features/Posts/pages/PostDetailsPage/Components/BountyPageContent/BountyPageContent.tsx +++ b/src/features/Posts/pages/PostDetailsPage/Components/BountyPageContent/BountyPageContent.tsx @@ -9,6 +9,8 @@ import Button from "src/Components/Button/Button"; import { FiGithub, FiShare2 } from "react-icons/fi"; import BountyApplicants from "./BountyApplicants"; import VoteButton from "src/Components/VoteButton/VoteButton"; +import { RiFlashlightLine } from "react-icons/ri"; +import { numberFormatter } from "src/utils/helperFunctions"; interface Props { @@ -21,14 +23,16 @@ export default function BountyPageContent({ bounty }: Props) { {/* Header */}
      -
      +

      {bounty.title} Bounty

      Reward: {bounty.reward_amount} sats
      - +
      + {numberFormatter(bounty.votes_count)} votes +
      32 Comments
      diff --git a/src/features/Posts/pages/PostDetailsPage/Components/PostActions/PostActions.tsx b/src/features/Posts/pages/PostDetailsPage/Components/PostActions/PostActions.tsx index 0ce906e..a0096b9 100644 --- a/src/features/Posts/pages/PostDetailsPage/Components/PostActions/PostActions.tsx +++ b/src/features/Posts/pages/PostDetailsPage/Components/PostActions/PostActions.tsx @@ -1,10 +1,12 @@ import { BsBookmark } from "react-icons/bs" -import { MdIosShare, MdLocalFireDepartment } from "react-icons/md" +import { MdIosShare } from "react-icons/md" import VoteButton from "src/Components/VoteButton/VoteButton" +interface Props { + votes_count: number +} - -export default function PostActions() { +export default function PostActions(props: Props) { const actions = [ { @@ -19,7 +21,7 @@ export default function PostActions() { return (
        - + {actions.map((action, idx) =>
      • diff --git a/src/features/Posts/pages/PostDetailsPage/Components/QuestionPageContent/QuestionPageContent.tsx b/src/features/Posts/pages/PostDetailsPage/Components/QuestionPageContent/QuestionPageContent.tsx index d88d220..f83e9a0 100644 --- a/src/features/Posts/pages/PostDetailsPage/Components/QuestionPageContent/QuestionPageContent.tsx +++ b/src/features/Posts/pages/PostDetailsPage/Components/QuestionPageContent/QuestionPageContent.tsx @@ -6,6 +6,7 @@ import Badge from "src/Components/Badge/Badge"; import { BiComment } from "react-icons/bi"; import { RiFlashlightLine } from "react-icons/ri"; import { CommentsSection } from "src/features/Posts/Components/Comments"; +import { numberFormatter } from "src/utils/helperFunctions"; interface Props { @@ -17,7 +18,7 @@ export default function QuestionPageContent({ question }: Props) { <>
        -
        +

        {question.title}

        {question.tags.map(tag => @@ -26,7 +27,7 @@ export default function QuestionPageContent({ question }: Props) {
        - {question.votes_count} votes + {numberFormatter(question.votes_count)} votes
        32 Comments @@ -38,9 +39,9 @@ export default function QuestionPageContent({ question }: Props) {
        -
        + {/*
        -
        +
        */} ) } diff --git a/src/features/Posts/pages/PostDetailsPage/Components/StoryPageContent/StoryPageContent.tsx b/src/features/Posts/pages/PostDetailsPage/Components/StoryPageContent/StoryPageContent.tsx index 92e47ac..8cf2e00 100644 --- a/src/features/Posts/pages/PostDetailsPage/Components/StoryPageContent/StoryPageContent.tsx +++ b/src/features/Posts/pages/PostDetailsPage/Components/StoryPageContent/StoryPageContent.tsx @@ -6,6 +6,7 @@ import Badge from "src/Components/Badge/Badge"; import { BiComment } from "react-icons/bi"; import { RiFlashlightLine } from "react-icons/ri"; import { CommentsSection } from "src/features/Posts/Components/Comments"; +import { numberFormatter } from "src/utils/helperFunctions"; interface Props { @@ -17,16 +18,16 @@ export default function StoryPageContent({ story }: Props) { <>
        -
        +

        {story.title}

        -
        + {story.tags.length > 0 &&
        {story.tags.map(tag => {tag.title} )} -
        +
        }
        - {story.votes_count} votes + {numberFormatter(story.votes_count)} votes
        {story.comments_count} Comments @@ -37,9 +38,9 @@ export default function StoryPageContent({ story }: Props) {
        -
        + {/*
        -
        +
        */} ) } diff --git a/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx b/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx index 33e7436..65e9854 100644 --- a/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx +++ b/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx @@ -44,7 +44,7 @@ export default function PostDetailsPage() { top: `${navHeight + 16}px`, maxHeight: `calc(100vh - ${navHeight}px - 16px)`, }}> - +
        diff --git a/src/features/Posts/pages/PostDetailsPage/postDetails.graphql b/src/features/Posts/pages/PostDetailsPage/postDetails.graphql index 4d83e07..6f7d8b7 100644 --- a/src/features/Posts/pages/PostDetailsPage/postDetails.graphql +++ b/src/features/Posts/pages/PostDetailsPage/postDetails.graphql @@ -3,11 +3,11 @@ query PostDetails($id: Int!, $type: POST_TYPE!) { ... on Story { id title - date + createdAt author { id name - image + avatar } body tags { @@ -20,25 +20,25 @@ query PostDetails($id: Int!, $type: POST_TYPE!) { comments_count comments { id - created_at + createdAt body votes_count parentId author { id name - image + avatar } } } ... on Bounty { id title - date + createdAt author { id name - image + avatar } body tags { @@ -58,18 +58,18 @@ query PostDetails($id: Int!, $type: POST_TYPE!) { author { id name - image + avatar } } } ... on Question { id title - date + createdAt author { id name - image + avatar } body tags { @@ -81,14 +81,14 @@ query PostDetails($id: Int!, $type: POST_TYPE!) { answers_count comments { id - created_at + createdAt body votes_count parentId author { id name - image + avatar } } } diff --git a/src/features/Posts/types/posts.interface.ts b/src/features/Posts/types/posts.interface.ts index 4de0f14..e70fd05 100644 --- a/src/features/Posts/types/posts.interface.ts +++ b/src/features/Posts/types/posts.interface.ts @@ -4,7 +4,7 @@ import { Tag } from "src/utils/interfaces" export type User = { id: number name: string - image: string + avatar: string } export type Author = User & { @@ -14,7 +14,7 @@ export type Author = User & { export type PostBase1 = { id: number title: string - date: string + createdAt: string author: Author excerpt: string tags: Tag[] diff --git a/src/features/Projects/pages/ExplorePage/ExplorePage.tsx b/src/features/Projects/pages/ExplorePage/ExplorePage.tsx index 363f94f..d964cdc 100644 --- a/src/features/Projects/pages/ExplorePage/ExplorePage.tsx +++ b/src/features/Projects/pages/ExplorePage/ExplorePage.tsx @@ -4,14 +4,16 @@ import ProjectsSection from "./ProjectsSection/ProjectsSection"; export default function ExplorePage() { return ( - <> -
        -
        -
        +
        + +
        + {/*
        */} - - +
        + +
        +
        ) } diff --git a/src/features/Projects/pages/ExplorePage/ProjectsRow/ProjectsRow.Skeleton.tsx b/src/features/Projects/pages/ExplorePage/ProjectsRow/ProjectsRow.Skeleton.tsx index f99fe57..27dc4fd 100644 --- a/src/features/Projects/pages/ExplorePage/ProjectsRow/ProjectsRow.Skeleton.tsx +++ b/src/features/Projects/pages/ExplorePage/ProjectsRow/ProjectsRow.Skeleton.tsx @@ -6,10 +6,10 @@ export default function ProjectsRowSkeleton() { return (
        -

        +

        -
        +
        {Array(5).fill(0).map((_, idx) => ( ))} diff --git a/src/features/Projects/pages/ExplorePage/ProjectsRow/ProjectsRow.tsx b/src/features/Projects/pages/ExplorePage/ProjectsRow/ProjectsRow.tsx index 530f837..b7bcbde 100644 --- a/src/features/Projects/pages/ExplorePage/ProjectsRow/ProjectsRow.tsx +++ b/src/features/Projects/pages/ExplorePage/ProjectsRow/ProjectsRow.tsx @@ -83,13 +83,13 @@ export default function ProjectsRow({ title, categoryId, projects }: Props) { return (
        -

        +

        {title} {categoryId > 0 && }

        -
        +
        ; title: Scalars['String']; votes_count: Scalars['Int']; }; @@ -110,7 +118,7 @@ export type PostComment = { __typename?: 'PostComment'; author: User; body: Scalars['String']; - created_at: Scalars['String']; + createdAt: Scalars['Date']; id: Scalars['Int']; parentId: Maybe; votes_count: Scalars['Int']; @@ -137,6 +145,7 @@ export type Query = { __typename?: 'Query'; allCategories: Array; allProjects: Array; + allTopics: Array; getCategory: Category; getFeed: Array; getLnurlDetailsForProject: LnurlDetails; @@ -145,6 +154,7 @@ export type Query = { getTrendingPosts: Array; hottestProjects: Array; newProjects: Array; + popularTopics: Array; projectsByCategory: Array; searchProjects: Array; }; @@ -162,10 +172,10 @@ export type QueryGetCategoryArgs = { export type QueryGetFeedArgs = { - category?: InputMaybe; skip?: InputMaybe; sortBy?: InputMaybe; take?: InputMaybe; + topic?: InputMaybe; }; @@ -216,7 +226,7 @@ export type Question = PostBase & { author: User; body: Scalars['String']; comments: Array; - date: Scalars['String']; + createdAt: Scalars['Date']; excerpt: Scalars['String']; id: Scalars['Int']; tags: Array; @@ -232,11 +242,12 @@ export type Story = PostBase & { comments: Array; comments_count: Scalars['Int']; cover_image: Scalars['String']; - date: Scalars['String']; + createdAt: Scalars['Date']; excerpt: Scalars['String']; id: Scalars['Int']; tags: Array; title: Scalars['String']; + topic: Topic; type: Scalars['String']; votes_count: Scalars['Int']; }; @@ -247,13 +258,29 @@ export type Tag = { title: Scalars['String']; }; +export type Topic = { + __typename?: 'Topic'; + icon: Scalars['String']; + id: Scalars['Int']; + title: Scalars['String']; +}; + export type User = { __typename?: 'User'; + avatar: Scalars['String']; id: Scalars['Int']; - image: Scalars['String']; name: Scalars['String']; }; +export enum Vote_Item_Type { + Bounty = 'Bounty', + Comment = 'Comment', + Project = 'Project', + Question = 'Question', + Story = 'Story', + User = 'User' +} + export type Vote = { __typename?: 'Vote'; amount_in_sat: Scalars['Int']; @@ -264,6 +291,17 @@ export type Vote = { project: Project; }; +export type Vote2 = { + __typename?: 'Vote2'; + amount_in_sat: Scalars['Int']; + id: Scalars['Int']; + item_id: Scalars['Int']; + item_type: Vote_Item_Type; + paid: Scalars['Boolean']; + payment_hash: Scalars['String']; + payment_request: Scalars['String']; +}; + export type NavCategoriesQueryVariables = Exact<{ [key: string]: never; }>; @@ -279,17 +317,22 @@ export type SearchProjectsQuery = { __typename?: 'Query', searchProjects: Array< export type TrendingPostsQueryVariables = Exact<{ [key: string]: never; }>; -export type TrendingPostsQuery = { __typename?: 'Query', getTrendingPosts: Array<{ __typename?: 'Bounty', id: number, title: string, author: { __typename?: 'User', id: number, image: string } } | { __typename?: 'Question', id: number, title: string, author: { __typename?: 'User', id: number, image: string } } | { __typename?: 'Story', id: number, title: string, author: { __typename?: 'User', id: number, image: string } }> }; +export type TrendingPostsQuery = { __typename?: 'Query', getTrendingPosts: Array<{ __typename?: 'Bounty', id: number, title: string, author: { __typename?: 'User', id: number, avatar: string } } | { __typename?: 'Question', id: number, title: string, author: { __typename?: 'User', id: number, avatar: string } } | { __typename?: 'Story', id: number, title: string, author: { __typename?: 'User', id: number, avatar: string } }> }; + +export type PopularTopicsQueryVariables = Exact<{ [key: string]: never; }>; + + +export type PopularTopicsQuery = { __typename?: 'Query', popularTopics: Array<{ __typename?: 'Topic', id: number, title: string, icon: string }> }; export type FeedQueryVariables = Exact<{ take: InputMaybe; skip: InputMaybe; sortBy: InputMaybe; - category: InputMaybe; + topic: InputMaybe; }>; -export type FeedQuery = { __typename?: 'Query', getFeed: Array<{ __typename?: 'Bounty', id: number, title: string, date: string, excerpt: string, votes_count: number, type: string, cover_image: string, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'User', id: number, name: string, image: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> } | { __typename?: 'Question', id: number, title: string, date: string, excerpt: string, votes_count: number, type: string, answers_count: number, author: { __typename?: 'User', id: number, name: string, image: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, created_at: string, body: string, author: { __typename?: 'User', id: number, name: string, image: string } }> } | { __typename?: 'Story', id: number, title: string, date: string, excerpt: string, votes_count: number, type: string, cover_image: string, comments_count: number, author: { __typename?: 'User', id: number, name: string, image: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> }> }; +export type FeedQuery = { __typename?: 'Query', getFeed: Array<{ __typename?: 'Bounty', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, cover_image: string, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> } | { __typename?: 'Question', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, answers_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, createdAt: any, body: string, author: { __typename?: 'User', id: number, name: string, avatar: string } }> } | { __typename?: 'Story', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, cover_image: string, comments_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> }> }; export type PostDetailsQueryVariables = Exact<{ id: Scalars['Int']; @@ -297,7 +340,7 @@ export type PostDetailsQueryVariables = Exact<{ }>; -export type PostDetailsQuery = { __typename?: 'Query', getPostById: { __typename?: 'Bounty', id: number, title: string, date: string, body: string, votes_count: number, type: string, cover_image: string, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'User', id: number, name: string, image: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, applications: Array<{ __typename?: 'BountyApplication', id: number, date: string, workplan: string, author: { __typename?: 'User', id: number, name: string, image: string } }> } | { __typename?: 'Question', id: number, title: string, date: string, body: string, votes_count: number, type: string, answers_count: number, author: { __typename?: 'User', id: number, name: string, image: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, created_at: string, body: string, votes_count: number, parentId: number | null, author: { __typename?: 'User', id: number, name: string, image: string } }> } | { __typename?: 'Story', id: number, title: string, date: string, body: string, votes_count: number, type: string, cover_image: string, comments_count: number, author: { __typename?: 'User', id: number, name: string, image: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, created_at: string, body: string, votes_count: number, parentId: number | null, author: { __typename?: 'User', id: number, name: string, image: string } }> } }; +export type PostDetailsQuery = { __typename?: 'Query', getPostById: { __typename?: 'Bounty', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, cover_image: string, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, applications: Array<{ __typename?: 'BountyApplication', id: number, date: string, workplan: string, author: { __typename?: 'User', id: number, name: string, avatar: string } }> } | { __typename?: 'Question', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, answers_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, createdAt: any, body: string, votes_count: number, parentId: number | null, author: { __typename?: 'User', id: number, name: string, avatar: string } }> } | { __typename?: 'Story', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, cover_image: string, comments_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, createdAt: any, body: string, votes_count: number, parentId: number | null, author: { __typename?: 'User', id: number, name: string, avatar: string } }> } }; export type CategoryPageQueryVariables = Exact<{ categoryId: Scalars['Int']; @@ -431,7 +474,7 @@ export const TrendingPostsDocument = gql` title author { id - image + avatar } } ... on Bounty { @@ -439,7 +482,7 @@ export const TrendingPostsDocument = gql` title author { id - image + avatar } } ... on Question { @@ -447,7 +490,7 @@ export const TrendingPostsDocument = gql` title author { id - image + avatar } } } @@ -480,17 +523,53 @@ export function useTrendingPostsLazyQuery(baseOptions?: Apollo.LazyQueryHookOpti export type TrendingPostsQueryHookResult = ReturnType; export type TrendingPostsLazyQueryHookResult = ReturnType; export type TrendingPostsQueryResult = Apollo.QueryResult; +export const PopularTopicsDocument = gql` + query PopularTopics { + popularTopics { + id + title + icon + } +} + `; + +/** + * __usePopularTopicsQuery__ + * + * To run a query within a React component, call `usePopularTopicsQuery` and pass it any options that fit your needs. + * When your component renders, `usePopularTopicsQuery` 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 } = usePopularTopicsQuery({ + * variables: { + * }, + * }); + */ +export function usePopularTopicsQuery(baseOptions?: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(PopularTopicsDocument, options); + } +export function usePopularTopicsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(PopularTopicsDocument, options); + } +export type PopularTopicsQueryHookResult = ReturnType; +export type PopularTopicsLazyQueryHookResult = ReturnType; +export type PopularTopicsQueryResult = Apollo.QueryResult; export const FeedDocument = gql` - query Feed($take: Int, $skip: Int, $sortBy: String, $category: String) { - getFeed(take: $take, skip: $skip, sortBy: $sortBy, category: $category) { + query Feed($take: Int, $skip: Int, $sortBy: String, $topic: Int) { + getFeed(take: $take, skip: $skip, sortBy: $sortBy, topic: $topic) { ... on Story { id title - date + createdAt author { id name - image + avatar } excerpt tags { @@ -505,11 +584,11 @@ export const FeedDocument = gql` ... on Bounty { id title - date + createdAt author { id name - image + avatar } excerpt tags { @@ -526,11 +605,11 @@ export const FeedDocument = gql` ... on Question { id title - date + createdAt author { id name - image + avatar } excerpt tags { @@ -542,12 +621,12 @@ export const FeedDocument = gql` answers_count comments { id - created_at + createdAt body author { id name - image + avatar } } } @@ -570,7 +649,7 @@ export const FeedDocument = gql` * take: // value for 'take' * skip: // value for 'skip' * sortBy: // value for 'sortBy' - * category: // value for 'category' + * topic: // value for 'topic' * }, * }); */ @@ -591,11 +670,11 @@ export const PostDetailsDocument = gql` ... on Story { id title - date + createdAt author { id name - image + avatar } body tags { @@ -608,25 +687,25 @@ export const PostDetailsDocument = gql` comments_count comments { id - created_at + createdAt body votes_count parentId author { id name - image + avatar } } } ... on Bounty { id title - date + createdAt author { id name - image + avatar } body tags { @@ -646,18 +725,18 @@ export const PostDetailsDocument = gql` author { id name - image + avatar } } } ... on Question { id title - date + createdAt author { id name - image + avatar } body tags { @@ -669,14 +748,14 @@ export const PostDetailsDocument = gql` answers_count comments { id - created_at + createdAt body votes_count parentId author { id name - image + avatar } } } diff --git a/src/mocks/data/hackathon.ts b/src/mocks/data/hackathon.ts index e4026b5..34d3602 100644 --- a/src/mocks/data/hackathon.ts +++ b/src/mocks/data/hackathon.ts @@ -1,7 +1,7 @@ import { random, randomItem, randomItems } from "src/utils/helperFunctions" import { getCoverImage } from "./utils" -const topics = [ +export const topics = [ { id: 1, title: '🎨 Design' diff --git a/src/mocks/data/posts.ts b/src/mocks/data/posts.ts index a9983c0..ae090fd 100644 --- a/src/mocks/data/posts.ts +++ b/src/mocks/data/posts.ts @@ -4,13 +4,14 @@ import { Bounty, Post, Question, Story } from "src/features/Posts/types"; import { random, randomItem } from "src/utils/helperFunctions"; import { getAvatarImage, getCoverImage } from "./utils"; import { Chance } from 'chance' +import { topics } from "./hackathon"; const getDate = () => dayjs().subtract(random(5, 48), 'hour').toString(); const getAuthor = () => ({ id: 12, name: "John Doe", - image: getAvatarImage(), + avatar: getAvatarImage(), join_date: getDate() }) @@ -23,7 +24,7 @@ export const generatePostComments = (cnt: number = 1): Story['comments'] => { const comment = { id: i + 1, body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nisi, at ut sit id. Vulputate aliquet aliquam penatibus ac, et dictum est etiam. Sagittis odio dui sed viverra donec rutrum iaculis vitae morbi.", - created_at: getDate(), + createdAt: getDate(), author: getAuthor(), votes_count: 123, parentId @@ -85,7 +86,7 @@ export let posts = { body: postBody, cover_image: getCoverImage(), comments_count: 3, - date: getDate(), + createdAt: getDate(), votes_count: 120, excerpt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In odio libero accumsan...', type: "Story", @@ -96,6 +97,7 @@ export let posts = { ], author: getAuthor(), comments: generatePostComments(3), + topic: randomItem(...topics) }, ] as Story[], @@ -107,7 +109,7 @@ export let posts = { body: postBody, cover_image: getCoverImage(), applicants_count: 31, - date: getDate(), + createdAt: getDate(), votes_count: 120, excerpt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In odio libero accumsan...', tags: [ @@ -129,7 +131,7 @@ export let posts = { title: 'Digital Editor, Mars Review of Books', body: postBody, answers_count: 3, - date: getDate(), + createdAt: getDate(), votes_count: 70, excerpt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In odio libero accumsan...', tags: [ diff --git a/src/mocks/handlers.ts b/src/mocks/handlers.ts index 42afcde..e3b0a52 100644 --- a/src/mocks/handlers.ts +++ b/src/mocks/handlers.ts @@ -106,7 +106,7 @@ export const handlers = [ const { take, skip } = req.variables; return res( ctx.data({ - getFeed: getFeed({ take, skip }) + getFeed: getFeed({ take, skip, }) }) ) }), diff --git a/src/styles/index.scss b/src/styles/index.scss index 98aca03..0cfdffb 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -11,9 +11,8 @@ body { } .page-container { - width: 98%; + width: calc(min(100% - 64px, 1440px)); margin: 0 auto; - max-width: 1440px; } svg { diff --git a/src/utils/apollo.ts b/src/utils/apollo.ts index fd7e395..c356363 100644 --- a/src/utils/apollo.ts +++ b/src/utils/apollo.ts @@ -50,7 +50,7 @@ export const apolloClient = new ApolloClient({ typePolicies: { Query: { fields: { - getFeed: offsetLimitPagination(['sortBy', 'category']) + getFeed: offsetLimitPagination(['sortBy', 'topic']) }, }, },