diff --git a/api/functions/graphql/nexus-typegen.ts b/api/functions/graphql/nexus-typegen.ts
index d260935..40fd548 100644
--- a/api/functions/graphql/nexus-typegen.ts
+++ b/api/functions/graphql/nexus-typegen.ts
@@ -660,6 +660,7 @@ export interface NexusGenFieldTypes {
excerpt: string; // String!
id: number; // Int!
is_published: boolean | null; // Boolean
+ project: NexusGenRootTypes['Project'] | null; // Project
tags: NexusGenRootTypes['Tag'][]; // [Tag!]!
title: string; // String!
type: string; // String!
@@ -1051,6 +1052,7 @@ export interface NexusGenFieldTypeNames {
excerpt: 'String'
id: 'Int'
is_published: 'Boolean'
+ project: 'Project'
tags: 'Tag'
title: 'String'
type: 'String'
diff --git a/api/functions/graphql/schema.graphql b/api/functions/graphql/schema.graphql
index a570aee..486e3bc 100644
--- a/api/functions/graphql/schema.graphql
+++ b/api/functions/graphql/schema.graphql
@@ -399,6 +399,7 @@ type Story implements PostBase {
excerpt: String!
id: Int!
is_published: Boolean
+ project: Project
tags: [Tag!]!
title: String!
type: String!
diff --git a/api/functions/graphql/types/post.js b/api/functions/graphql/types/post.js
index c207d65..f899854 100644
--- a/api/functions/graphql/types/post.js
+++ b/api/functions/graphql/types/post.js
@@ -114,6 +114,13 @@ const Story = objectType({
});
+ t.field('project', {
+ type: "Project",
+ resolve(parent) {
+ return null
+ }
+ })
+
},
})
diff --git a/src/features/Posts/Components/PostCard/Header/Header.Skeleton.tsx b/src/features/Posts/Components/PostCard/Header/Header.Skeleton.tsx
index 41b4a0e..31b7404 100644
--- a/src/features/Posts/Components/PostCard/Header/Header.Skeleton.tsx
+++ b/src/features/Posts/Components/PostCard/Header/Header.Skeleton.tsx
@@ -8,7 +8,7 @@ interface Props {
export default function HeaderSkeleton({ size = 'md', }: Props) {
return (
-
+
diff --git a/src/features/Posts/Components/PostCard/PostCard/PostCard.Skeleton.tsx b/src/features/Posts/Components/PostCard/PostCard/PostCard.Skeleton.tsx
index 9fab751..d91584e 100644
--- a/src/features/Posts/Components/PostCard/PostCard/PostCard.Skeleton.tsx
+++ b/src/features/Posts/Components/PostCard/PostCard/PostCard.Skeleton.tsx
@@ -1,14 +1,20 @@
import Skeleton from "react-loading-skeleton"
-import HeaderSkeleton from "../Header/Header.Skeleton"
import Badge from 'src/Components/Badge/Badge'
+import Card from "src/Components/Card/Card"
export default function PostCardSkeleton() {
- return
-
-
+ return
+
-
-
+
+
+
+
+
@@ -24,6 +30,8 @@ export default function PostCardSkeleton() {
-
+
+
+
}
diff --git a/src/features/Posts/Components/PostCard/PostCardHeader/PostCardHeader.tsx b/src/features/Posts/Components/PostCard/PostCardHeader/PostCardHeader.tsx
new file mode 100644
index 0000000..9074902
--- /dev/null
+++ b/src/features/Posts/Components/PostCard/PostCardHeader/PostCardHeader.tsx
@@ -0,0 +1,52 @@
+import Avatar from 'src/features/Profiles/Components/Avatar/Avatar';
+import dayjs from 'dayjs'
+import { UnionToObjectKeys } from 'src/utils/types/utils';
+import { trimText } from 'src/utils/helperFunctions';
+import { Link } from 'react-router-dom';
+import { createRoute } from 'src/utils/routing';
+import { Project, User } from 'src/graphql';
+
+interface Props {
+ author?: Pick
+ project?: Pick | null
+ date: string;
+}
+
+
+export default function PostCardHeader(props: Props) {
+
+
+ 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');
+ }
+
+ if (!props.author) return null
+
+ return (
+
+
+
+
+
+ {props.project &&
+
+ }
+
+
+
+ {trimText(props.author.name, 30)}
+
+ {props.project && <>
+ for
+
+ {trimText(props.project.title, 30)}
+
+ >}
+
+
{dateToShow()}
+
+ )
+}
diff --git a/src/features/Posts/Components/PostCard/StoryCard/StoryCard.tsx b/src/features/Posts/Components/PostCard/StoryCard/StoryCard.tsx
index d31164c..e85e7d2 100644
--- a/src/features/Posts/Components/PostCard/StoryCard/StoryCard.tsx
+++ b/src/features/Posts/Components/PostCard/StoryCard/StoryCard.tsx
@@ -1,5 +1,4 @@
import { Story } from "src/features/Posts/types"
-import Header from "../Header/Header"
import { Link } from "react-router-dom"
import VoteButton from "src/Components/VoteButton/VoteButton"
import { useVote } from "src/utils/hooks"
@@ -8,6 +7,7 @@ import Badge from "src/Components/Badge/Badge"
import { createRoute } from "src/utils/routing"
import { BiComment } from "react-icons/bi"
import Card from "src/Components/Card/Card"
+import PostCardHeader from "../PostCardHeader/PostCardHeader"
export type StoryCardType = Pick & {
tags: Array>,
author: Pick
@@ -34,30 +35,37 @@ export default function StoryCard({ story }: Props) {
itemType: Vote_Item_Type.Story
});
- return (
-
- {story.cover_image &&
}
-
-
-
-
{story.title}
-
-
{story.excerpt}...
-
- {story.tags.map(tag =>
- {tag.title}
- )}
-
-
-
-
-
-
{story.comments_count} Comments
+ return (
+
+
+
+ {story.cover_image &&
+
+
+
+ }
+
+
+
{story.title}
+
+
{story.excerpt}...
+
+ {story.tags.map(tag =>
+ {tag.title}
+ )}
+
+
+
+
+
+
+ {story.comments_count} Comments
+
-
-
+
+
)
}
diff --git a/src/features/Posts/pages/FeedPage/feed.graphql b/src/features/Posts/pages/FeedPage/feed.graphql
index bc76c2d..d25f74c 100644
--- a/src/features/Posts/pages/FeedPage/feed.graphql
+++ b/src/features/Posts/pages/FeedPage/feed.graphql
@@ -19,6 +19,12 @@ query Feed($take: Int, $skip: Int, $sortBy: String, $tag: Int) {
type
cover_image
comments_count
+ project {
+ id
+ title
+ thumbnail_image
+ hashtag
+ }
}
... on Bounty {
id
diff --git a/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.skeleton.tsx b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.skeleton.tsx
index e5ac08c..98ed6b5 100644
--- a/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.skeleton.tsx
+++ b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.skeleton.tsx
@@ -8,10 +8,13 @@ import HeaderSkeleton from "src/features/Posts/Components/PostCard/Header/Header
export default function PageContentSkeleton() {
return
+
+
+
+
-
{Array(3).fill(0).map((_, idx) =>
hidden
diff --git a/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.tsx b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.tsx
index 0945666..2c2628b 100644
--- a/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.tsx
+++ b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/PageContent.tsx
@@ -1,4 +1,4 @@
-import { isBounty, isQuestion, isStory, Post } from "src/features/Posts/types"
+import { isBounty, isQuestion, isStory } from "src/features/Posts/types"
import StoryPageContent from "../StoryPageContent/StoryPageContent";
import BountyPageContent from "../BountyPageContent/BountyPageContent";
import QuestionPageContent from "../QuestionPageContent/QuestionPageContent";
diff --git a/src/features/Posts/pages/PostDetailsPage/Components/PostPageHeader/PostPageHeader.tsx b/src/features/Posts/pages/PostDetailsPage/Components/PostPageHeader/PostPageHeader.tsx
new file mode 100644
index 0000000..5fd5890
--- /dev/null
+++ b/src/features/Posts/pages/PostDetailsPage/Components/PostPageHeader/PostPageHeader.tsx
@@ -0,0 +1,54 @@
+import Avatar from 'src/features/Profiles/Components/Avatar/Avatar';
+import dayjs from 'dayjs'
+import { trimText } from 'src/utils/helperFunctions';
+import { Link } from 'react-router-dom';
+import { createRoute } from 'src/utils/routing';
+import { Project, User } from 'src/graphql';
+
+interface Props {
+ author?: Pick
+ project?: Pick | null
+ date: string;
+ className?: string
+}
+
+
+export default function PostPageHeader(props: Props) {
+
+
+ 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');
+ }
+
+ if (!props.author) return null
+
+ return (
+
+
+
+
+
+ {props.project &&
+
+ }
+
+
+
+
+ {trimText(props.author.name, 30)}
+
+ {props.project && <>
+ for
+
+ {trimText(props.project.title, 30)}
+
+ >}
+
+
Published {dateToShow()}
+
+
+ )
+}
diff --git a/src/features/Posts/pages/PostDetailsPage/Components/StoryPageContent/StoryPageContent.tsx b/src/features/Posts/pages/PostDetailsPage/Components/StoryPageContent/StoryPageContent.tsx
index 9587bd7..05314bb 100644
--- a/src/features/Posts/pages/PostDetailsPage/Components/StoryPageContent/StoryPageContent.tsx
+++ b/src/features/Posts/pages/PostDetailsPage/Components/StoryPageContent/StoryPageContent.tsx
@@ -1,4 +1,4 @@
-import Header from "src/features/Posts/Components/PostCard/Header/Header"
+
import { Story } from "src/features/Posts/types"
import { marked } from 'marked';
import styles from '../PageContent/styles.module.scss'
@@ -10,6 +10,7 @@ import { useUpdateStory } from './useUpdateStory'
import { FaPen } from "react-icons/fa";
import DOMPurify from 'dompurify';
import Card from "src/Components/Card/Card";
+import PostPageHeader from "../PostPageHeader/PostPageHeader";
interface Props {
@@ -29,6 +30,11 @@ export default function StoryPageContent({ story }: Props) {
<>
+
{story.cover_image &&
}
{story.title}
-
{story.tags.length > 0 &&
{story.tags.map(tag =>
{tag.title}
diff --git a/src/features/Posts/pages/PostDetailsPage/Components/StoryPageContent/useUpdateStory.tsx b/src/features/Posts/pages/PostDetailsPage/Components/StoryPageContent/useUpdateStory.tsx
index 88629c7..ac64108 100644
--- a/src/features/Posts/pages/PostDetailsPage/Components/StoryPageContent/useUpdateStory.tsx
+++ b/src/features/Posts/pages/PostDetailsPage/Components/StoryPageContent/useUpdateStory.tsx
@@ -30,8 +30,6 @@ export const useUpdateStory = (story: Story) => {
dispatch(stageStory({
...story,
cover_image: story.cover_image ? { id: null, name: null, url: story.cover_image } : null,
- project: null,
- // TODO: UPDATE WHEN API READY
}))
navigate(createRoute({ type: "write-story" }))
diff --git a/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.skeleton.tsx b/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.skeleton.tsx
index 091c0ef..001f01d 100644
--- a/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.skeleton.tsx
+++ b/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.skeleton.tsx
@@ -1,18 +1,8 @@
-import { Helmet } from 'react-helmet'
-import { useParams } from 'react-router-dom'
-import LoadingPage from 'src/Components/LoadingPage/LoadingPage'
-import NotFoundPage from 'src/features/Shared/pages/NotFoundPage/NotFoundPage'
-import { usePostDetailsQuery } from 'src/graphql'
-import { capitalize } from 'src/utils/helperFunctions'
import { useAppSelector, } from 'src/utils/hooks'
-import { PostCardSkeleton } from '../../Components/PostCard'
import TrendingCard from '../../Components/TrendingCard/TrendingCard'
-import AuthorCard from './Components/AuthorCard/AuthorCard'
import AuthorCardSkeleton from './Components/AuthorCard/AuthorCard.skeleton'
-import PageContent from './Components/PageContent/PageContent'
import PageContentSkeleton from './Components/PageContent/PageContent.skeleton'
-import PostActions from './Components/PostActions/PostActions'
import PostActionsSkeleton from './Components/PostActions/PostActions.skeleton'
import styles from './styles.module.scss'
diff --git a/src/features/Posts/pages/PostDetailsPage/postDetails.graphql b/src/features/Posts/pages/PostDetailsPage/postDetails.graphql
index e2a1d51..91d8cc5 100644
--- a/src/features/Posts/pages/PostDetailsPage/postDetails.graphql
+++ b/src/features/Posts/pages/PostDetailsPage/postDetails.graphql
@@ -19,6 +19,12 @@ query PostDetails($id: Int!, $type: POST_TYPE!) {
type
cover_image
is_published
+ project {
+ id
+ title
+ thumbnail_image
+ hashtag
+ }
# comments_count
# comments {
# id
diff --git a/src/graphql/index.tsx b/src/graphql/index.tsx
index 54e66ad..e2770dd 100644
--- a/src/graphql/index.tsx
+++ b/src/graphql/index.tsx
@@ -642,6 +642,7 @@ export type Story = PostBase & {
excerpt: Scalars['String'];
id: Scalars['Int'];
is_published: Maybe;
+ project: Maybe;
tags: Array;
title: Scalars['String'];
type: Scalars['String'];
@@ -959,7 +960,7 @@ export type FeedQueryVariables = Exact<{
}>;
-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 | null, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> } | { __typename?: 'Question', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> } | { __typename?: 'Story', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, cover_image: string | null, comments_count: number, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, 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 | null, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> } | { __typename?: 'Question', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> } | { __typename?: 'Story', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, cover_image: string | null, comments_count: number, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, project: { __typename?: 'Project', id: number, title: string, thumbnail_image: string, hashtag: string } | null }> };
export type PostDetailsQueryVariables = Exact<{
id: Scalars['Int'];
@@ -967,7 +968,7 @@ export type PostDetailsQueryVariables = Exact<{
}>;
-export type PostDetailsQuery = { __typename?: 'Query', getPostById: { __typename?: 'Bounty', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, cover_image: string | null, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, applications: Array<{ __typename?: 'BountyApplication', id: number, date: string, workplan: string, author: { __typename?: 'Author', id: number, name: string, avatar: string } }> } | { __typename?: 'Question', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> } | { __typename?: 'Story', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, cover_image: string | null, is_published: boolean | null, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: 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 | null, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, applications: Array<{ __typename?: 'BountyApplication', id: number, date: string, workplan: string, author: { __typename?: 'Author', id: number, name: string, avatar: string } }> } | { __typename?: 'Question', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> } | { __typename?: 'Story', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, cover_image: string | null, is_published: boolean | null, author: { __typename?: 'Author', id: number, name: string, avatar: string, join_date: any }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, project: { __typename?: 'Project', id: number, title: string, thumbnail_image: string, hashtag: string } | null } };
type UserBasicInfo_MyProfile_Fragment = { __typename?: 'MyProfile', id: number, name: string, avatar: string, join_date: any, role: string | null, jobTitle: string | null, lightning_address: string | null, website: string | null, twitter: string | null, discord: string | null, github: string | null, linkedin: string | null, bio: string | null, location: string | null };
@@ -1885,6 +1886,12 @@ export const FeedDocument = gql`
type
cover_image
comments_count
+ project {
+ id
+ title
+ thumbnail_image
+ hashtag
+ }
}
... on Bounty {
id
@@ -1982,6 +1989,12 @@ export const PostDetailsDocument = gql`
type
cover_image
is_published
+ project {
+ id
+ title
+ thumbnail_image
+ hashtag
+ }
}
... on Bounty {
id