Skip to main content

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.

"components/CommentList.tsx
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>
)
}
note

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.

components/CommentComposer.tsx
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>
)
}
note

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.

"components/NewsPage.tsx
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.

note

You can see the final result here.