The Node.js® Website
at main 1.8 kB view raw
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;