140 lines
4.3 KiB
TypeScript
140 lines
4.3 KiB
TypeScript
import ProductPage from "../../../components/ProductPage";
|
|
import { productService } from "../../../lib/services/productService";
|
|
import type { Metadata } from 'next';
|
|
import { Suspense } from 'react';
|
|
|
|
export async function generateMetadata(
|
|
{ params }: { params: Promise<{ slug: string }> }
|
|
): Promise<Metadata> {
|
|
const resolvedParams = await params;
|
|
const product = await productService.getProductBySlug(resolvedParams.slug);
|
|
|
|
if (!product) {
|
|
return {
|
|
title: 'خرید مکمل درمانی پت | کنینا ایران',
|
|
};
|
|
}
|
|
|
|
const nameFa = product.nameFa || product.name;
|
|
const nameEn = product.nameEn || "";
|
|
const title = nameFa.includes("Canina") ? nameFa : `${nameFa} (${nameEn}) | برند کنینا آلمان`;
|
|
const description = (product.shortDescription || product.description || '').substring(0, 150).trim();
|
|
const rawKeywords = (product as unknown as Record<string, unknown>).keywords;
|
|
const keywords = typeof rawKeywords === 'string' ? rawKeywords.split(',') : product.main_ingredients;
|
|
|
|
return {
|
|
title,
|
|
description,
|
|
keywords,
|
|
openGraph: {
|
|
title,
|
|
description,
|
|
images: [product.image],
|
|
url: `/shop/${resolvedParams.slug}`,
|
|
siteName: "کنینا ایران",
|
|
type: "website",
|
|
},
|
|
alternates: {
|
|
canonical: `/shop/${resolvedParams.slug}`,
|
|
}
|
|
};
|
|
}
|
|
|
|
export default async function ShopProductPage({ params }: { params: Promise<{ slug: string }> }) {
|
|
const resolvedParams = await params;
|
|
const product = await productService.getProductBySlug(resolvedParams.slug);
|
|
|
|
if (!product) {
|
|
return <ProductPage productSlug={resolvedParams.slug} />;
|
|
}
|
|
|
|
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://canina-iran.com';
|
|
const productUrl = `${siteUrl}/shop/${resolvedParams.slug}`;
|
|
const priceInRial = product.priceValue * 10;
|
|
|
|
const productJsonLd = {
|
|
'@context': 'https://schema.org',
|
|
'@type': 'Product',
|
|
name: product.nameFa || product.name,
|
|
image: product.image,
|
|
description: product.shortDescription || product.description,
|
|
sku: product.artNo,
|
|
mpn: product.artNo,
|
|
brand: {
|
|
'@type': 'Brand',
|
|
name: 'Canina pharma GmbH'
|
|
},
|
|
category: product.category,
|
|
offers: {
|
|
'@type': 'Offer',
|
|
url: productUrl,
|
|
priceCurrency: 'IRR',
|
|
price: priceInRial,
|
|
availability: 'https://schema.org/InStock',
|
|
itemCondition: 'https://schema.org/NewCondition',
|
|
seller: {
|
|
'@type': 'Organization',
|
|
name: 'کنینا ایران'
|
|
}
|
|
}
|
|
};
|
|
|
|
const breadcrumbJsonLd = {
|
|
'@context': 'https://schema.org',
|
|
'@type': 'BreadcrumbList',
|
|
itemListElement: [
|
|
{
|
|
'@type': 'ListItem',
|
|
position: 1,
|
|
name: 'صفحه اصلی',
|
|
item: siteUrl
|
|
},
|
|
{
|
|
'@type': 'ListItem',
|
|
position: 2,
|
|
name: 'فروشگاه مکملها',
|
|
item: `${siteUrl}/shop`
|
|
},
|
|
{
|
|
'@type': 'ListItem',
|
|
position: 3,
|
|
name: product.nameFa || product.name,
|
|
item: productUrl
|
|
}
|
|
]
|
|
};
|
|
|
|
const safeProductJsonLd = JSON.stringify(productJsonLd).replace(/</g, '\\u003c');
|
|
const safeBreadcrumbJsonLd = JSON.stringify(breadcrumbJsonLd).replace(/</g, '\\u003c');
|
|
|
|
return (
|
|
<>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: safeProductJsonLd }}
|
|
/>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: safeBreadcrumbJsonLd }}
|
|
/>
|
|
<Suspense fallback={
|
|
<div className="min-h-screen bg-medical-gray-50 p-6 max-w-7xl mx-auto font-vazir" dir="rtl">
|
|
<div className="animate-pulse space-y-6">
|
|
<div className="h-8 bg-medical-gray-200 rounded-2xl w-48" />
|
|
<div className="grid md:grid-cols-12 gap-8">
|
|
<div className="md:col-span-5 h-80 bg-white border border-medical-gray-200 rounded-[2.5rem]" />
|
|
<div className="md:col-span-7 space-y-4">
|
|
<div className="h-10 bg-medical-gray-200 rounded-2xl w-3/4" />
|
|
<div className="h-6 bg-medical-gray-100 rounded-xl w-1/2" />
|
|
<div className="h-24 bg-medical-gray-100 rounded-2xl w-full" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}>
|
|
<ProductPage productSlug={resolvedParams.slug} />
|
|
</Suspense>
|
|
</>
|
|
);
|
|
}
|