60 lines
1.7 KiB
React
60 lines
1.7 KiB
React
import Link from 'next/link';
|
|
import { notFound } from 'next/navigation';
|
|
import { formatDate, getArticleBySlug, getArticles } from '../../../lib/articles';
|
|
|
|
export function generateStaticParams() {
|
|
return getArticles().map((article) => ({ slug: article.slug }));
|
|
}
|
|
|
|
export async function generateMetadata({ params }) {
|
|
const { slug } = await params;
|
|
const article = getArticleBySlug(decodeURIComponent(slug));
|
|
|
|
if (!article) {
|
|
return { title: 'Статья не найдена' };
|
|
}
|
|
|
|
return {
|
|
title: `${article.title} | ProgCode.Ru`,
|
|
description: article.excerpt,
|
|
};
|
|
}
|
|
|
|
export default async function ArticlePage({ params }) {
|
|
const { slug } = await params;
|
|
const article = getArticleBySlug(decodeURIComponent(slug));
|
|
|
|
if (!article) {
|
|
notFound();
|
|
}
|
|
|
|
return (
|
|
<main>
|
|
<article className="article-page">
|
|
<nav className="top-nav" aria-label="Навигация">
|
|
<Link href="/">Все статьи</Link>
|
|
</nav>
|
|
|
|
<header className="article-hero">
|
|
<div className="article-hero__text">
|
|
<div className="meta-line">
|
|
<time dateTime={article.date}>{formatDate(article.date)}</time>
|
|
<span>{article.author}</span>
|
|
<span>{article.readingMinutes} мин</span>
|
|
</div>
|
|
<h1>{article.title}</h1>
|
|
<div className="tag-list">
|
|
{article.categories.map((category) => (
|
|
<span key={category}>{category}</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
<img src={article.cover} alt="" />
|
|
</header>
|
|
|
|
<div className="article-content" dangerouslySetInnerHTML={{ __html: article.contentHtml }} />
|
|
</article>
|
|
</main>
|
|
);
|
|
}
|