77 lines
2.2 KiB
TypeScript
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>
|
|
)
|
|
}
|