canina/frontend/application/app/shop/[slug]/page.tsx
parsa aghaei 8d1b786a24
All checks were successful
Deploy Canina / deploy (push) Successful in 1m50s
chore(brand): rename all Persian occurrences of کانینا to کنینا across the project
2026-08-16 16:40:08 +03:30

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>
</>
);
}