Files
kaman-cable/src/app/blog/page.tsx
T

108 lines
4.1 KiB
TypeScript

import type { Metadata } from "next";
import Link from "next/link";
import SlotImage from "@/components/SlotImage";
import SlotLink from "@/components/SlotLink";
import { blogDate, blogHref, blogImage, fetchBlogs, getLocalBlogPosts } from "@/lib/blog";
import { pageMetadata } from "@/lib/seo";
import { fetchStaticImageSlots, overlaySlotImages, pickSlot } from "@/lib/static-images";
export const revalidate = 60;
export async function generateMetadata({
searchParams,
}: {
searchParams: Promise<{ page?: string }>;
}): Promise<Metadata> {
const { page: pageParam } = await searchParams;
const page = Math.max(1, Number(pageParam) || 1);
return pageMetadata({
title: page > 1 ? `وبلاگ — صفحه ${page}` : "وبلاگ",
description: "آخرین اخبار و مقالات فنی صنایع سیم و کابل کمان.",
path: page > 1 ? `/blog?page=${page}` : "/blog",
image: "/images/samples/production-line.avif",
});
}
export default async function BlogPage({
searchParams,
}: {
searchParams: Promise<{ page?: string }>;
}) {
const { page: pageParam } = await searchParams;
const page = Math.max(1, Number(pageParam) || 1);
const [result, slots] = await Promise.all([fetchBlogs({ page, pageSize: 12 }), fetchStaticImageSlots("blog")]);
const hero = overlaySlotImages(
pickSlot(slots, "blog-hero"),
[{ id: "blog-hero", image: "/images/samples/production-line.avif", title: "وبلاگ" }],
"blog-hero",
);
const usingApi = result.items.length > 0;
const posts = usingApi ? result.items : page === 1 ? getLocalBlogPosts() : [];
const pageCount = usingApi
? Math.max(1, Math.ceil((result.total || result.items.length) / (result.pageSize || 12)))
: 1;
return (
<>
<section className="page-hero">
<SlotImage src={hero.items[0]?.image || "/images/samples/production-line.avif"} alt={hero.items[0]?.title || "وبلاگ کابل کمان"} fill />
<div className="container">
<h1>وبلاگ</h1>
<p className="en">Blog</p>
</div>
</section>
<section className="section">
<div className="container">
{posts.length === 0 ? (
<p className="comment-empty">مقاله‌ای برای نمایش وجود ندارد.</p>
) : (
<div className="blog-grid">
{posts.map((post) => (
<article key={post.id} className="blog-card">
<div className="blog-card-media">
<SlotLink href={blogHref(post)} className="blog-card-hit">
<SlotImage src={blogImage(post)} alt={post.title} fill />
</SlotLink>
</div>
<div className="blog-card-body">
{blogDate(post) ? <p className="blog-date">{blogDate(post)}</p> : null}
<h2>
<SlotLink href={blogHref(post)}>{post.title}</SlotLink>
</h2>
{post.abstract ? <p className="blog-excerpt">{post.abstract}</p> : null}
<SlotLink href={blogHref(post)} className="blog-more">
ادامه مطلب
</SlotLink>
</div>
</article>
))}
</div>
)}
{pageCount > 1 ? (
<nav className="pagination" aria-label="صفحه‌بندی وبلاگ">
{Array.from({ length: pageCount }, (_, index) => {
const number = index + 1;
if (pageCount > 12 && Math.abs(number - page) > 3 && number !== 1 && number !== pageCount) {
return number === 2 || number === pageCount - 1 ? <span key={number}>…</span> : null;
}
return (
<Link
key={number}
href={number === 1 ? "/blog" : `/blog?page=${number}`}
className={number === page ? "active" : undefined}
>
{number}
</Link>
);
})}
</nav>
) : null}
</div>
</section>
</>
);
}