From 2d5ceeb6faf3a034f48cd3e51d90efddf8046f1b Mon Sep 17 00:00:00 2001 From: maxiaoteng Date: Sun, 29 Dec 2024 17:20:49 +0800 Subject: [PATCH 1/2] feat(pagination): Implement pagination for tag pages --- app/tags/[tag]/page.tsx | 31 ++++++++++++++++++++++++++++--- layouts/ListLayoutWithTags.tsx | 5 ++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/app/tags/[tag]/page.tsx b/app/tags/[tag]/page.tsx index ba3591f8d..8e96d8d84 100644 --- a/app/tags/[tag]/page.tsx +++ b/app/tags/[tag]/page.tsx @@ -8,6 +8,8 @@ import { genPageMetadata } from 'app/seo' import { Metadata } from 'next' import { notFound } from 'next/navigation' +const POSTS_PER_PAGE = 5 + export async function generateMetadata(props: { params: Promise<{ tag: string }> }): Promise { @@ -34,16 +36,39 @@ export const generateStaticParams = async () => { return paths } -export default async function TagPage(props: { params: Promise<{ tag: string }> }) { +export default async function TagPage(props: { + params: Promise<{ tag: string }> + searchParams: Promise<{ page: string }> +}) { const params = await props.params const tag = decodeURI(params.tag) + const searchParams = await props.searchParams + const pageNumber = parseInt(searchParams.page || '1') // Capitalize first letter and convert space to dash const title = tag[0].toUpperCase() + tag.split(' ').join('-').slice(1) const filteredPosts = allCoreContent( sortPosts(allBlogs.filter((post) => post.tags && post.tags.map((t) => slug(t)).includes(tag))) ) - if (filteredPosts.length === 0) { + const initialDisplayPosts = filteredPosts.slice( + POSTS_PER_PAGE * (pageNumber - 1), + POSTS_PER_PAGE * pageNumber + ) + + if (initialDisplayPosts.length === 0) { return notFound() } - return + + const pagination = { + currentPage: pageNumber, + totalPages: Math.ceil(filteredPosts.length / POSTS_PER_PAGE), + } + + return ( + + ) } diff --git a/layouts/ListLayoutWithTags.tsx b/layouts/ListLayoutWithTags.tsx index a7d21b5fc..2b774a3e0 100644 --- a/layouts/ListLayoutWithTags.tsx +++ b/layouts/ListLayoutWithTags.tsx @@ -23,7 +23,6 @@ interface ListLayoutProps { function Pagination({ totalPages, currentPage }: PaginationProps) { const pathname = usePathname() - const basePath = pathname.split('/')[1] const prevPage = currentPage - 1 > 0 const nextPage = currentPage + 1 <= totalPages @@ -37,7 +36,7 @@ function Pagination({ totalPages, currentPage }: PaginationProps) { )} {prevPage && ( Previous @@ -52,7 +51,7 @@ function Pagination({ totalPages, currentPage }: PaginationProps) { )} {nextPage && ( - + Next )} From 088754f90ff07b2d61dcc48326c6c70eb6db3b68 Mon Sep 17 00:00:00 2001 From: maxiaoteng Date: Mon, 6 Jan 2025 15:42:57 +0800 Subject: [PATCH 2/2] feat(blog): refactor blog pagination and remove deprecated page component --- app/blog/page.tsx | 10 ++++++++-- app/blog/page/[page]/page.tsx | 35 ----------------------------------- 2 files changed, 8 insertions(+), 37 deletions(-) delete mode 100644 app/blog/page/[page]/page.tsx diff --git a/app/blog/page.tsx b/app/blog/page.tsx index 4dcbddcfb..cb8a75a97 100644 --- a/app/blog/page.tsx +++ b/app/blog/page.tsx @@ -2,18 +2,24 @@ import ListLayout from '@/layouts/ListLayoutWithTags' import { allCoreContent, sortPosts } from 'pliny/utils/contentlayer' import { allBlogs } from 'contentlayer/generated' import { genPageMetadata } from 'app/seo' +import { notFound } from 'next/navigation' const POSTS_PER_PAGE = 5 export const metadata = genPageMetadata({ title: 'Blog' }) -export default function BlogPage() { +export default async function BlogPage(props: { searchParams: Promise<{ page: string }> }) { const posts = allCoreContent(sortPosts(allBlogs)) - const pageNumber = 1 + const searchParams = await props.searchParams + const pageNumber = parseInt(searchParams.page || '1') const initialDisplayPosts = posts.slice( POSTS_PER_PAGE * (pageNumber - 1), POSTS_PER_PAGE * pageNumber ) + if (initialDisplayPosts.length === 0) { + return notFound() + } + const pagination = { currentPage: pageNumber, totalPages: Math.ceil(posts.length / POSTS_PER_PAGE), diff --git a/app/blog/page/[page]/page.tsx b/app/blog/page/[page]/page.tsx deleted file mode 100644 index bdd27033b..000000000 --- a/app/blog/page/[page]/page.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import ListLayout from '@/layouts/ListLayoutWithTags' -import { allCoreContent, sortPosts } from 'pliny/utils/contentlayer' -import { allBlogs } from 'contentlayer/generated' - -const POSTS_PER_PAGE = 5 - -export const generateStaticParams = async () => { - const totalPages = Math.ceil(allBlogs.length / POSTS_PER_PAGE) - const paths = Array.from({ length: totalPages }, (_, i) => ({ page: (i + 1).toString() })) - - return paths -} - -export default async function Page(props: { params: Promise<{ page: string }> }) { - const params = await props.params - const posts = allCoreContent(sortPosts(allBlogs)) - const pageNumber = parseInt(params.page as string) - const initialDisplayPosts = posts.slice( - POSTS_PER_PAGE * (pageNumber - 1), - POSTS_PER_PAGE * pageNumber - ) - const pagination = { - currentPage: pageNumber, - totalPages: Math.ceil(posts.length / POSTS_PER_PAGE), - } - - return ( - - ) -}