The Node.js® Website
1import { useTranslations } from 'next-intl';
2import type { ComponentProps, FC } from 'react';
3
4import BlogPostCard from '@/components/Common/BlogPostCard';
5import LinkTabs from '@/components/Common/LinkTabs';
6import Pagination from '@/components/Common/Pagination';
7import type { BlogPostsRSC } from '@/types';
8import { mapAuthorToCardAuthors } from '@/util/blogUtils';
9
10type WithBlogCategoriesProps = {
11 categories: ComponentProps<typeof LinkTabs>['tabs'];
12 blogData: BlogPostsRSC & { category: string; page: number };
13};
14
15const mapPaginationPages = (category: string, pages: number) =>
16 [...Array(pages).keys()].map(page => ({
17 url: `/blog/${category}/page/${page + 1}`,
18 }));
19
20const WithBlogCategories: FC<WithBlogCategoriesProps> = ({
21 categories,
22 blogData,
23}) => {
24 const t = useTranslations();
25
26 return (
27 <>
28 <LinkTabs
29 label={t('layouts.blog.selectCategory')}
30 tabs={categories}
31 activeTab={blogData.category}
32 >
33 <div className="grid grid-cols-[repeat(auto-fill,minmax(theme(spacing.80),1fr))] [grid-gap:theme(spacing.12)_theme(spacing.8)] xs:grid-cols-[1fr]">
34 {blogData.posts.map(post => (
35 <BlogPostCard
36 key={post.slug}
37 title={post.title}
38 category={post.categories[0]}
39 authors={mapAuthorToCardAuthors(post.author)}
40 date={post.date}
41 slug={post.slug}
42 />
43 ))}
44 </div>
45 </LinkTabs>
46
47 <div className="mt-4 border-t border-t-neutral-200 pt-5 dark:border-t-neutral-900 md:mt-8">
48 <Pagination
49 currentPage={blogData.page}
50 pages={mapPaginationPages(
51 blogData.category,
52 blogData.pagination.pages
53 )}
54 />
55 </div>
56 </>
57 );
58};
59
60export default WithBlogCategories;