refactor: improve blog page and category page type handling

- Add NextPageProps type for consistent page props handling
- Resolve async params and searchParams in blog and category pages
- Simplify type annotations and improve type safety
- Remove redundant type definitions
This commit is contained in:
javayhu 2025-03-06 01:24:55 +08:00
parent 707e4400f7
commit 5017ed9f7f
2 changed files with 41 additions and 38 deletions

View File

@ -1,24 +1,28 @@
import BlogGrid from "@/components/blog/blog-grid";
import EmptyGrid from "@/components/shared/empty-grid";
import CustomPagination from "@/components/shared/pagination";
import { siteConfig } from "@/config/site";
import { POSTS_PER_PAGE } from "@/lib/constants";
import { allPosts, allCategories } from "content-collections";
import { siteConfig } from "@/config/site";
import { constructMetadata } from "@/lib/metadata";
import type { Metadata } from "next";
import { allCategories, allPosts } from "content-collections";
import { NextPageProps } from "@/types/next-page-props";
export async function generateMetadata({
params,
}: {
params: { slug: string };
params: Promise<{ slug: string }>;
}): Promise<Metadata | undefined> {
const resolvedParams = await params;
const { slug } = resolvedParams;
const category = allCategories.find(
(category) => category.slug === params.slug
(category) => category.slug === slug
);
if (!category) {
console.warn(
`generateMetadata, category not found for slug: ${params.slug}`,
`generateMetadata, category not found for slug: ${slug}`,
);
return;
}
@ -31,7 +35,7 @@ export async function generateMetadata({
return constructMetadata({
title: `${category.name}`,
description: category.description,
canonicalUrl: `${siteConfig.url}/blog/category/${params.slug}`,
canonicalUrl: `${siteConfig.url}/blog/category/${slug}`,
// image: ogImageUrl.toString(),
});
}
@ -39,33 +43,33 @@ export async function generateMetadata({
export default async function BlogCategoryPage({
params,
searchParams,
}: {
params: { slug: string; locale: string };
searchParams?: { [key: string]: string | string[] | undefined };
}) {
const { page } = searchParams as { [key: string]: string };
}: NextPageProps) {
const resolvedParams = await params;
const { slug, locale } = resolvedParams;
const resolvedSearchParams = await searchParams;
const { page } = resolvedSearchParams as { [key: string]: string } || {};
const currentPage = page ? Number(page) : 1;
const startIndex = (currentPage - 1) * POSTS_PER_PAGE;
const endIndex = startIndex + POSTS_PER_PAGE;
// Filter posts by category and locale
const filteredPosts = allPosts.filter(
(post) =>
post.published &&
post.locale === params.locale &&
post.categories.some(category => category.slug === params.slug)
(post) =>
post.published &&
post.locale === locale &&
post.categories.some(category => category.slug === slug)
);
// Sort posts by date (newest first)
const sortedPosts = [...filteredPosts].sort(
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()
);
// Paginate posts
const paginatedPosts = sortedPosts.slice(startIndex, endIndex);
const totalCount = filteredPosts.length;
const totalPages = Math.ceil(totalCount / POSTS_PER_PAGE);
console.log(
"BlogCategoryPage, totalCount",
totalCount,
@ -85,7 +89,7 @@ export default async function BlogCategoryPage({
<div className="mt-8 flex items-center justify-center">
<CustomPagination
routePreix={`/blog/category/${params.slug}`}
routePreix={`/blog/category/${resolvedParams.slug}`}
totalPages={totalPages}
/>
</div>

View File

@ -4,6 +4,7 @@ import BlogGrid from '@/components/blog/blog-grid';
import EmptyGrid from '@/components/shared/empty-grid';
import CustomPagination from '@/components/shared/pagination';
import { POSTS_PER_PAGE } from '@/lib/constants';
import { NextPageProps } from '@/types/next-page-props';
export async function generateMetadata(): Promise<Metadata> {
return {
@ -12,40 +13,38 @@ export async function generateMetadata(): Promise<Metadata> {
};
}
interface BlogPageProps {
params: {
locale: string;
};
searchParams?: { [key: string]: string | string[] | undefined };
}
export default async function BlogPage({ params, searchParams }: BlogPageProps) {
const { locale } = params;
const { page } = searchParams as { [key: string]: string };
export default async function BlogPage({
params,
searchParams
}: NextPageProps) {
const resolvedParams = await params;
const { locale } = resolvedParams;
const resolvedSearchParams = await searchParams;
const { page } = resolvedSearchParams as { [key: string]: string } || {};
const currentPage = page ? Number(page) : 1;
const startIndex = (currentPage - 1) * POSTS_PER_PAGE;
const endIndex = startIndex + POSTS_PER_PAGE;
// Filter posts by locale
const localePosts = allPosts.filter(
(post) => post.locale === locale && post.published
);
// If no posts found for the current locale, show all published posts
const filteredPosts = localePosts.length > 0
? localePosts
const filteredPosts = localePosts.length > 0
? localePosts
: allPosts.filter((post) => post.published);
// Sort posts by date (newest first)
const sortedPosts = [...filteredPosts].sort(
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()
);
// Paginate posts
const paginatedPosts = sortedPosts.slice(startIndex, endIndex);
const totalCount = filteredPosts.length;
const totalPages = Math.ceil(totalCount / POSTS_PER_PAGE);
console.log(
"BlogPage, totalCount",
totalCount,