99 lines
3.3 KiB
TypeScript
99 lines
3.3 KiB
TypeScript
import type { Metadata } from "next";
|
|
import Link from "next/link";
|
|
|
|
import CatalogCard from "@/components/CatalogCard";
|
|
import PageHero from "@/components/PageHero";
|
|
import { categoryHref, categoryTitle, fetchCategories } from "@/lib/categories";
|
|
import { fetchProducts } from "@/lib/products";
|
|
import { pageMetadata } from "@/lib/seo";
|
|
|
|
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: "کاتالوگ پنجره UPVC، شیشه دوجداره و محصولات پنجره فرخ.",
|
|
path: page > 1 ? `/products?page=${page}` : "/products",
|
|
});
|
|
}
|
|
|
|
export default async function ProductsPage({
|
|
searchParams,
|
|
}: {
|
|
searchParams: Promise<{ page?: string }>;
|
|
}) {
|
|
const { page: pageParam } = await searchParams;
|
|
const page = Math.max(1, Number(pageParam) || 1);
|
|
const [result, categories] = await Promise.all([
|
|
fetchProducts({ page, pageSize: 12 }),
|
|
fetchCategories("product"),
|
|
]);
|
|
const pageCount = Math.max(1, Math.ceil((result.total || result.items.length) / (result.pageSize || 12)));
|
|
const topCategories = categories.filter((item) => !item.parentId);
|
|
|
|
return (
|
|
<>
|
|
<PageHero
|
|
title="محصولات"
|
|
en="PRODUCTS"
|
|
crumbs={[
|
|
{ href: "/", label: "خانه" },
|
|
{ href: "/products", label: "محصولات" },
|
|
]}
|
|
/>
|
|
|
|
<section className="section">
|
|
<div className="container">
|
|
{topCategories.length > 0 ? (
|
|
<div className="category-pills">
|
|
{topCategories.map((item) => (
|
|
<Link key={item.id} href={categoryHref(item)}>
|
|
{categoryTitle(item)}
|
|
</Link>
|
|
))}
|
|
</div>
|
|
) : null}
|
|
|
|
{result.items.length === 0 ? (
|
|
<p className="comment-empty">محصولی برای نمایش وجود ندارد.</p>
|
|
) : (
|
|
<div className="catalog-grid">
|
|
{result.items.map((product) => (
|
|
<CatalogCard key={product.id} product={product} />
|
|
))}
|
|
</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 ? "/products" : `/products?page=${number}`}
|
|
className={number === page ? "active" : undefined}
|
|
>
|
|
{number}
|
|
</Link>
|
|
);
|
|
})}
|
|
</nav>
|
|
) : null}
|
|
</div>
|
|
</section>
|
|
</>
|
|
);
|
|
}
|