Add the FarrokhWin Next.js site for Meshkee hosting.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
import { notFound, redirect } from "next/navigation";
|
||||
|
||||
import SlotImage from "@/components/SlotImage";
|
||||
import { plainText, sanitizeHtml } from "@/lib/format";
|
||||
import {
|
||||
fetchPortfolioById,
|
||||
portfolioHref,
|
||||
portfolioImage,
|
||||
portfolioTitle,
|
||||
} from "@/lib/portfolios";
|
||||
import { pageMetadata } from "@/lib/seo";
|
||||
import { slugifyForUrl } from "@/lib/slug";
|
||||
|
||||
export const revalidate = 60;
|
||||
|
||||
type Params = { id: string; slug: string };
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<Params>;
|
||||
}): Promise<Metadata> {
|
||||
const { id } = await params;
|
||||
const item = await fetchPortfolioById(id);
|
||||
if (!item) {
|
||||
return {
|
||||
title: "نمونه کار یافت نشد",
|
||||
description: "این نمونه کار در گالری پنجره فرخ موجود نیست.",
|
||||
robots: { index: false },
|
||||
};
|
||||
}
|
||||
const title = portfolioTitle(item);
|
||||
return pageMetadata({
|
||||
title,
|
||||
description: item.abstract?.trim() || plainText(item.mainTextHtml).slice(0, 160) || `${title} | نمونه کارهای پنجره فرخ`,
|
||||
path: portfolioHref(item),
|
||||
image: portfolioImage(item),
|
||||
});
|
||||
}
|
||||
|
||||
export default async function PortfolioDetailPage({ params }: { params: Promise<Params> }) {
|
||||
const { id, slug } = await params;
|
||||
const item = await fetchPortfolioById(id);
|
||||
if (!item) notFound();
|
||||
|
||||
const title = portfolioTitle(item);
|
||||
if (decodeURIComponent(slug) !== slugifyForUrl(title)) {
|
||||
redirect(portfolioHref(item));
|
||||
}
|
||||
|
||||
const html = sanitizeHtml(item.mainTextHtml);
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className="page-hero">
|
||||
<div className="container page-hero-inner">
|
||||
<div className="page-hero-en">
|
||||
<span>PORTFOLIO</span>
|
||||
<i />
|
||||
</div>
|
||||
<div className="page-hero-fa">
|
||||
<nav className="crumbs">
|
||||
<Link href="/">خانه</Link>
|
||||
{" > "}
|
||||
<Link href="/portfolio">نمونه کارها</Link>
|
||||
{" > "}
|
||||
<span>{title}</span>
|
||||
</nav>
|
||||
<h1>{title}</h1>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="section">
|
||||
<div className="container detail-article">
|
||||
<div className="article-cover">
|
||||
<SlotImage src={portfolioImage(item)} alt={title} />
|
||||
</div>
|
||||
{item.abstract ? <p className="detail-lead">{item.abstract}</p> : null}
|
||||
{html ? <div className="rich-text" dangerouslySetInnerHTML={{ __html: html }} /> : null}
|
||||
|
||||
<Link href="/portfolio" className="text-link">
|
||||
بازگشت به نمونه کارها
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user