Files

77 lines
2.2 KiB
TypeScript

import { notFound } from 'next/navigation'
import type { Metadata } from 'next'
import { getCategoryBySlug, getArticles, getAllCategories } from '@/lib/directus'
import ArticleCard from '@/components/article/ArticleCard'
import LoadMoreButton from '@/components/article/LoadMoreButton'
interface Props {
params: Promise<{ category: string }>
}
export const revalidate = false
export async function generateStaticParams() {
try {
const categories = await getAllCategories()
return categories.map((cat) => ({ category: cat.slug }))
} catch {
return []
}
}
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { category: categorySlug } = await params
try {
const category = await getCategoryBySlug(categorySlug)
if (!category) return {}
return {
title: category.name,
description:
category.description ?? `Latest ${category.name} news and articles on Kotobane.`,
}
} catch {
return {}
}
}
export default async function CategoryPage({ params }: Props) {
const { category: categorySlug } = await params
let category = null
let articles: import('@/lib/types').Article[] = []
try {
const cat = await getCategoryBySlug(categorySlug)
const arts = cat ? await getArticles({ categoryId: cat.id, limit: 24 }) : []
category = cat
articles = arts
} catch {
category = null
}
if (!category) notFound()
return (
<div className="max-w-[1200px] mx-auto px-6 pt-10">
<div className="mb-8">
<h1 className="text-3xl font-bold text-text-primary mb-2">{category.name}</h1>
{category.description && (
<p className="text-text-secondary text-sm">{category.description}</p>
)}
</div>
{articles.length === 0 ? (
<p className="text-text-muted text-sm">No articles yet.</p>
) : (
<>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
{articles.map((article) => (
<ArticleCard key={article.id} article={article} />
))}
</div>
<LoadMoreButton categorySlug={categorySlug} initialCount={articles.length} hasMore={articles.length >= 24} />
</>
)}
</div>
)
}