89 lines
3.0 KiB
TypeScript
89 lines
3.0 KiB
TypeScript
import type { Metadata } from "next";
|
|
import Link from "next/link";
|
|
|
|
import { SectionTitle } from "@/components/SectionTitle";
|
|
import { site } from "@/data/site";
|
|
import {
|
|
fetchPortfolios,
|
|
getLocalPortfolios,
|
|
portfolioCover,
|
|
portfolioHref,
|
|
portfolioTitle,
|
|
} from "@/lib/portfolio";
|
|
|
|
export const revalidate = 300;
|
|
|
|
export const metadata: Metadata = {
|
|
title: "نمونه کارها",
|
|
description: `نمونه کارهای ${site.nameFa} در معماری، طراحی داخلی و طراحی نما.`,
|
|
};
|
|
|
|
export default async function PortfolioPage({
|
|
searchParams,
|
|
}: {
|
|
searchParams: Promise<{ page?: string }>;
|
|
}) {
|
|
const { page: pageRaw } = await searchParams;
|
|
const page = Math.max(1, Number(pageRaw) || 1);
|
|
const pageSize = 12;
|
|
const result = await fetchPortfolios({ page, pageSize });
|
|
const usingApi = result.items.length > 0;
|
|
const items = usingApi ? result.items : page === 1 ? getLocalPortfolios() : [];
|
|
const total = usingApi ? result.total : items.length;
|
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
|
|
return (
|
|
<>
|
|
<section className="page-hero">
|
|
<div className="container">
|
|
<SectionTitle
|
|
en="portfolio"
|
|
title="نمونه کارهای"
|
|
titleMuted="استودیو"
|
|
as="h1"
|
|
className="section-title--inline"
|
|
/>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="section--tight">
|
|
<div className="container">
|
|
{items.length === 0 ? (
|
|
<p className="empty-state">هنوز نمونه کاری منتشر نشده است.</p>
|
|
) : (
|
|
<div className="projects">
|
|
{items.map((item) => {
|
|
const title = portfolioTitle(item);
|
|
return (
|
|
<Link key={item.id} href={portfolioHref(item)} className="project">
|
|
<div className="frame">
|
|
<img src={portfolioCover(item)} alt={title} loading="lazy" decoding="async" />
|
|
</div>
|
|
<div className="project__meta">
|
|
<h3>{title}</h3>
|
|
{item.categoryName || item.abstract ? (
|
|
<span>{item.categoryName || item.abstract}</span>
|
|
) : null}
|
|
</div>
|
|
{item.titleEn ? <p className="project__sub latin">{item.titleEn}</p> : null}
|
|
</Link>
|
|
);
|
|
})}
|
|
</div>
|
|
)}
|
|
|
|
{totalPages > 1 && items.length ? (
|
|
<nav className="pager" aria-label="صفحهبندی">
|
|
{page > 1 ? <Link href={`/portfolio?page=${page - 1}`}>قبلی</Link> : <span />}
|
|
<span className="latin">
|
|
{page} / {totalPages}
|
|
</span>
|
|
{page < totalPages ? <Link href={`/portfolio?page=${page + 1}`}>بعدی</Link> : <span />}
|
|
</nav>
|
|
) : null}
|
|
</div>
|
|
</section>
|
|
</>
|
|
);
|
|
}
|