Comment
In this section we want to add the functionality of commenting under the news.
1. Create CommentList Component
First we need to update the fields of usePost
in the NewsPage.tsx
to retrieve the replies.
const {data: post} = usePost({
id: postId,
fields: {
replies: {
variables: {
limit: 100,
},
fields: {
createdBy: {
member: 'basic'
},
authMemberProps: 'all',
}
}
}
})
Now we can create our CommentList component.
import {Post} from "@tribeplatform/gql-client/types";
import {DeleteNews} from "./DeleteNews";
export const CommentList = ({post}: { post?: Post }) => {
return (
<div>
{post?.replies?.nodes?.map(reply => (
<div className="lg:rounded-lg bg-hacker-body my-5 px-5 py-2 flex">
<div className="flex-grow">
<div className="text-xs">{reply.createdBy?.member?.name} says:</div>
<div dangerouslySetInnerHTML={{__html: reply.shortContent as string}}/>
</div>
<DeleteNews post={reply}/>
</div>
))}
</div>
)
}
We are also getting the authMemberProps
for the replies, therefore we can easily reuse our DeleteNews
component
to have the functionality of deleting comments.
2. Create CommentComposer Component
We use useAddReply
hook to reply to a post. We can easily create a component that comments under a post.
import {Post, PostMappingTypeEnum} from "@tribeplatform/gql-client/types";
import {useState} from "react";
import {useAddReply} from "@tribeplatform/react-sdk/hooks";
export const CommentComposer = ({post}: { post?: Post }) => {
const [text, setText] = useState<string>()
const {mutateAsync: addReply} = useAddReply()
return (
<div>
<input
className="shadow appearance-none border lg:rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
type="text" placeholder="What's on your mind?" onChange={event => setText(event.target.value)} value={text}
/>
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded my-2"
onClick={() => {
addReply({
postId: post?.id as string,
input: {
postTypeId: "4DznH0SQ6k2IQUT",
publish: true,
mappingFields: [{
key: 'content',
type: PostMappingTypeEnum.HTML,
value: JSON.stringify(`<p>${text}</p>`)
}],
}
}).then(() => {
setText('');
})
}}
>
Add Comment
</button>
</div>
)
}
We used the id of the "Comment" post type. If you are using your own community
use the postTypes
query to find the id of the "Comment" post type.
3. Update NewsPage to show the comments
Now we can easily add these components to our NewsPage component.
import {useParams} from "react-router-dom";
import {usePost} from "@tribeplatform/react-sdk/hooks";
import {CommentList} from "./CommentList";
import {CommentComposer} from "./CommentComposer";
export const NewsPage = () => {
const params = useParams()
const postId = params.postId as string
const {data: post} = usePost({
id: postId,
fields: {
replies: {
variables: {
limit: 100,
},
fields: {
createdBy: {
member: 'basic'
},
authMemberProps: 'all',
}
}
}
})
return (
<div className="w-full lg:w-1/2 mx-auto my-5">
<div className="lg:rounded-lg bg-hacker-body p-5">
<div className="text-center text-2xl font-bold">
{post?.title}
</div>
<div dangerouslySetInnerHTML={{__html: post?.shortContent as string}} className="mt-5">
</div>
</div>
<h2 className="text-2xl font-bold mt-5">Comments ({post?.repliesCount ?? 0})</h2>
<CommentList post={post}/>
<CommentComposer post={post}/>
</div>
)
}
Now it's all set. You can start viewing, adding, and deleting comments.
You can see the final result here.