Expand HOM studio site with portfolio, blog, auth, and details video frame.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-10-12 22:52:38 +03:30
co-authored by Cursor
parent 73971bf6d9
commit 55dd94d2e4
45 changed files with 6056 additions and 651 deletions
+88
View File
@@ -0,0 +1,88 @@
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>
</>
);
}