Host Iran Yekan/Montserrat locally, link login to customer.havaran.com with a logged-in dropdown, submit contact forms to Meshkee, and publish sitemap-config with canonical id/slug detail URLs. Co-authored-by: Cursor <cursoragent@cursor.com>
68 lines
2.0 KiB
TypeScript
68 lines
2.0 KiB
TypeScript
import { notFound, permanentRedirect } from "next/navigation";
|
|
import { Footer } from "@/components/Footer";
|
|
import { Header } from "@/components/Header";
|
|
import { PageHero } from "@/components/PageShared";
|
|
import { PortfolioDetailView } from "@/components/PortfolioDetail";
|
|
import { getPortfolioById } from "@/lib/meshkee";
|
|
import { pageMetadata } from "@/lib/seo";
|
|
import { portfolioPath, portfolioTitleSlug } from "@/lib/urls";
|
|
|
|
type PageProps = {
|
|
params: Promise<{ id: string; slug: string }>;
|
|
};
|
|
|
|
export async function generateMetadata({ params }: PageProps) {
|
|
const { id } = await params;
|
|
const { item } = await getPortfolioById(id);
|
|
if (!item) {
|
|
return pageMetadata({
|
|
title: "پروژه",
|
|
description: "پروژه مورد نظر یافت نشد.",
|
|
path: `/portfolios/${id}`,
|
|
noIndex: true,
|
|
});
|
|
}
|
|
|
|
const description =
|
|
item.description?.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim() ||
|
|
`نمونه کار ${item.title} — شرکت رسام تجارت هواران`;
|
|
|
|
return pageMetadata({
|
|
title: item.title,
|
|
description: description.slice(0, 160),
|
|
path: portfolioPath(item),
|
|
image: item.coverImage || item.image || undefined,
|
|
});
|
|
}
|
|
|
|
export default async function PortfolioDetailPage({ params }: PageProps) {
|
|
const { id, slug: slugParam } = await params;
|
|
const slug = decodeURIComponent(slugParam);
|
|
const { item } = await getPortfolioById(id);
|
|
if (!item) notFound();
|
|
|
|
const canonicalSlug = portfolioTitleSlug(item);
|
|
if (slug !== canonicalSlug) {
|
|
permanentRedirect(portfolioPath(item));
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Header />
|
|
<main>
|
|
<PageHero
|
|
title={item.title}
|
|
titleEn={item.titleEn || "PROJECT DETAILS"}
|
|
breadcrumb={[
|
|
{ label: "صفحه اصلی", href: "/" },
|
|
{ label: "پروژه ها", href: "/portfolios" },
|
|
{ label: item.title, href: portfolioPath(item) },
|
|
]}
|
|
/>
|
|
<PortfolioDetailView item={item} />
|
|
</main>
|
|
<Footer />
|
|
</>
|
|
);
|
|
}
|