Skip to main content

News Page

In the previous section we created a list of news. Now we want to be able to see the full news by clicking on the title in the list.

1. Create NewsPage component

Create a new component NewsPage.tsx which uses the usePost hook to retrieve a post and show it.

components/NewsPage.tsx
import {useParams} from "react-router-dom";
import {usePost} from "@tribeplatform/react-sdk/hooks";

export const NewsPage = () => {
const params = useParams()
const postId = params.postId as string
const {data: post} = usePost({
id: postId,
})

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>
</div>
)
}

2. Set up router

Add the route for news page in App.tsx.

App.tsx
import React from 'react';
import {Routes, Route} from "react-router-dom";
import NewsList from "./components/NewsList";
import {NewsPage} from "./components/NewsPage";

function App() {
return (
<Routes>
<Route path="/" element={<NewsList/>}/>
<Route path="/:postId" element={<NewsPage/>}/>
</Routes>
);
}

export default App;

Now make the title clickable and redirect to news page.

"components/NewsList.tsx
import React from 'react';
import {simplifyPaginatedResult} from "@tribeplatform/react-sdk/utils";
import {Post} from "@tribeplatform/gql-client/types";
import {Link} from "react-router-dom";
import {useFeed} from "@tribeplatform/react-sdk/hooks";
import InfiniteScroll from 'react-infinite-scroller';

function NewsList() {
const {
data,
fetchNextPage,
hasNextPage,
} = useFeed({
fields: {
reactions: {
fields: 'all',
variables: {
limit: 10,
}
},
authMemberProps: 'all',
createdBy: {
member: 'basic'
}
},
variables: {
limit: 10,
}
})
const {nodes: posts} = simplifyPaginatedResult<Post>(data)

return (
<div className="lg:w-3/4 m-auto flex flex-col">
<InfiniteScroll
pageStart={0}
loadMore={fetchNextPage}
hasMore={hasNextPage}
>
{posts.map((post, i) => (
<div className="flex gap-2 bg-hacker-body p-2" key={post?.id}>
<div className="flex flex-col justify-center">
{i + 1}.
</div>
<div className="flex flex-col flex-grow">
<Link to={`/${post.id}`}>
<div>
{post.title}
</div>
</Link>
<div className="flex gap-2 text-xs text-gray-500">
<div>
By {post.createdBy?.member?.name}
</div>
|
<div>
{post.reactionsCount} upvotes
</div>
|
<div>
{post.repliesCount} comments
</div>
</div>
</div>
</div>
))}
</InfiniteScroll>
</div>
);
}

export default NewsList;
note

You can see the final result here.