134 lines
4.0 KiB
TypeScript
134 lines
4.0 KiB
TypeScript
import Image from "next/image";
|
|
import Link from "next/link";
|
|
import { notFound } from "next/navigation";
|
|
import Header from "@/components/Header";
|
|
import Footer from "@/components/Footer";
|
|
import DetailBanner from "@/components/DetailBanner";
|
|
import ArticleBody from "@/components/ArticleBody";
|
|
import ShareLikeActions from "@/components/ShareLikeActions";
|
|
import {
|
|
getAllBusinessSlugs,
|
|
getBusinessBlogPost,
|
|
getBusinessBySlug,
|
|
} from "@/data/business";
|
|
import styles from "./blog.module.css";
|
|
|
|
export function generateStaticParams() {
|
|
return getAllBusinessSlugs().flatMap((slug) => {
|
|
const business = getBusinessBySlug(slug);
|
|
return (business?.posts ?? []).map((post) => ({
|
|
slug,
|
|
postSlug: post.slug,
|
|
}));
|
|
});
|
|
}
|
|
|
|
export async function generateMetadata({
|
|
params,
|
|
}: {
|
|
params: Promise<{ slug: string; postSlug: string }>;
|
|
}) {
|
|
const { slug, postSlug } = await params;
|
|
const data = getBusinessBlogPost(slug, postSlug);
|
|
if (!data) return { title: "Blog Details | IranBay" };
|
|
return {
|
|
title: `${data.post.title} | Blog Details | IranBay`,
|
|
description: data.post.intro,
|
|
};
|
|
}
|
|
|
|
export default async function BlogDetailPage({
|
|
params,
|
|
}: {
|
|
params: Promise<{ slug: string; postSlug: string }>;
|
|
}) {
|
|
const { slug, postSlug } = await params;
|
|
const data = getBusinessBlogPost(slug, postSlug);
|
|
if (!data) notFound();
|
|
|
|
const { business, post, related } = data;
|
|
|
|
return (
|
|
<div className={styles.page}>
|
|
<Header />
|
|
<main className={styles.shell}>
|
|
<DetailBanner title="Blog Details" breadcrumbs={business.breadcrumbs} />
|
|
|
|
<div className={styles.layout}>
|
|
<article className={styles.article}>
|
|
<div className={styles.meta}>
|
|
<span>
|
|
<img src="/images/icons/calendar.svg" alt="" />
|
|
{post.date}
|
|
</span>
|
|
<span>
|
|
<img src="/images/icons/user.svg" alt="" />
|
|
{post.author}
|
|
</span>
|
|
<span>
|
|
<img src="/images/icons/category.svg" alt="" />
|
|
{post.category}
|
|
</span>
|
|
</div>
|
|
<h2 className={styles.title}>{post.title}.</h2>
|
|
<p className={styles.intro}>{post.intro}</p>
|
|
|
|
<div className={styles.hero}>
|
|
<Image
|
|
src={post.hero}
|
|
alt=""
|
|
fill
|
|
className={styles.heroImg}
|
|
sizes="(max-width: 1100px) 100vw, 1232px"
|
|
priority
|
|
/>
|
|
</div>
|
|
|
|
<h3 className={styles.sectionTitle}>{post.title}.</h3>
|
|
<ArticleBody blocks={post.body} />
|
|
|
|
<div className={styles.actions}>
|
|
<ShareLikeActions />
|
|
</div>
|
|
</article>
|
|
|
|
<aside className={styles.sidebar} aria-label="Related posts">
|
|
{related.map((item) => (
|
|
<Link
|
|
key={item.slug}
|
|
href={`/businesses/${business.slug}/blog/${item.slug}`}
|
|
className={styles.related}
|
|
>
|
|
<div className={styles.relatedMedia}>
|
|
<Image
|
|
src={item.image}
|
|
alt=""
|
|
fill
|
|
className={styles.relatedImg}
|
|
sizes="154px"
|
|
/>
|
|
</div>
|
|
<div className={styles.relatedBody}>
|
|
<h3>{item.title}</h3>
|
|
<p>{item.excerpt}</p>
|
|
<div className={styles.relatedMeta}>
|
|
<span>
|
|
<img src="/images/icons/calendar.svg" alt="" />
|
|
{item.date}
|
|
</span>
|
|
<span>
|
|
<img src="/images/icons/user.svg" alt="" />
|
|
{item.author}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
))}
|
|
</aside>
|
|
</div>
|
|
</main>
|
|
<Footer />
|
|
</div>
|
|
);
|
|
}
|