diff --git a/app/category/[slug]/page.js b/app/category/[slug]/page.js new file mode 100644 index 0000000..5c619c4 --- /dev/null +++ b/app/category/[slug]/page.js @@ -0,0 +1,88 @@ +import { notFound } from 'next/navigation'; +import Link from 'next/link'; +import Header from '@/components/Header'; +import Footer from '@/components/Footer'; +import ArticleCard from '@/components/ArticleCard'; +import { listCategories, getCategoryArticles } from '@/lib/engine'; + +export const dynamic = 'force-dynamic'; + +const COLOR_MAP = { + emerald: { bg: 'bg-emerald-50 dark:bg-emerald-950', text: 'text-emerald-700 dark:text-emerald-300', border: 'border-emerald-200 dark:border-emerald-800' }, + red: { bg: 'bg-red-50 dark:bg-red-950', text: 'text-red-700 dark:text-red-300', border: 'border-red-200 dark:border-red-800' }, + amber: { bg: 'bg-amber-50 dark:bg-amber-950', text: 'text-amber-700 dark:text-amber-300', border: 'border-amber-200 dark:border-amber-800' }, + blue: { bg: 'bg-blue-50 dark:bg-blue-950', text: 'text-blue-700 dark:text-blue-300', border: 'border-blue-200 dark:border-blue-800' }, +}; + +export async function generateMetadata({ params }) { + const { slug } = await params; + const cats = await listCategories(); + const cat = cats.find(c => c.slug === slug); + if (!cat) return { title: 'Категория не найдена' }; + return { + title: `${cat.name} — ZeroPost`, + description: cat.description, + alternates: { canonical: `https://zeropost.ru/category/${slug}` }, + }; +} + +export default async function CategoryPage({ params }) { + const { slug } = await params; + const [cats, articles] = await Promise.all([ + listCategories(), + getCategoryArticles(slug, { limit: 30 }), + ]); + const cat = cats.find(c => c.slug === slug); + if (!cat) notFound(); + + const colors = COLOR_MAP[cat.color] || COLOR_MAP.emerald; + + return ( + <> +
+
+ + {/* Шапка категории */} +
+
+ {cat.icon} +

{cat.name}

+
+

{cat.description}

+
{articles.length} {articles.length === 1 ? 'статья' : articles.length < 5 ? 'статьи' : 'статей'}
+
+ + {/* Навигация по категориям */} +
+ {cats.map(c => ( + + {c.icon} {c.name} + + ))} +
+ + {/* Статьи */} + {articles.length > 0 ? ( +
+ {articles.map(a => )} +
+ ) : ( +
+
{cat.icon}
+

Статей пока нет

+

Скоро здесь появятся материалы по теме «{cat.name}»

+
+ )} +
+