- Fix seed-products.ts TS error (implicit any) and BOM handling - Re-run full seed to restore correct Persian encoding in DB - Fix productService query→search param mismatch - Fix IngredientWiki hardcoded port 4000→use settingsStore - Restore seed-products-data.json from git after accidental corruption
79 lines
2.3 KiB
TypeScript
79 lines
2.3 KiB
TypeScript
import ProductPage from "../../../components/ProductPage";
|
|
import { productService } from "../../../lib/services/productService";
|
|
import type { Metadata, ResolvingMetadata } from 'next';
|
|
|
|
export async function generateMetadata(
|
|
{ params }: { params: Promise<{ slug: string }> },
|
|
parent: ResolvingMetadata
|
|
): Promise<Metadata> {
|
|
const resolvedParams = await params;
|
|
const product = await productService.getProductBySlug(resolvedParams.slug);
|
|
|
|
if (!product) {
|
|
return {
|
|
title: 'محصول یافت نشد',
|
|
};
|
|
}
|
|
|
|
// Get raw data for custom fields if we added them (like metaTitle)
|
|
// Since we don't have local access to raw DB object without modifying productService,
|
|
// we can just use the mapped product fields for now.
|
|
const title = (product as any).metaTitle || product.name;
|
|
const description = (product as any).metaDescription || product.description;
|
|
const keywords = (product as any).keywords ? (product as any).keywords.split(',') : product.main_ingredients;
|
|
|
|
return {
|
|
title,
|
|
description,
|
|
keywords,
|
|
openGraph: {
|
|
title,
|
|
description,
|
|
images: [product.image],
|
|
},
|
|
alternates: {
|
|
canonical: (product as any).canonicalUrl || `/shop/${product.id}`,
|
|
}
|
|
};
|
|
}
|
|
|
|
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 jsonLd = {
|
|
'@context': 'https://schema.org',
|
|
'@type': 'Product',
|
|
name: product.name,
|
|
image: product.image,
|
|
description: (product as any).metaDescription || product.description,
|
|
sku: product.artNo,
|
|
brand: {
|
|
'@type': 'Brand',
|
|
name: 'Canina'
|
|
},
|
|
offers: {
|
|
'@type': 'Offer',
|
|
url: `https://canino-iran.com/shop/${product.id}`,
|
|
priceCurrency: 'IRR',
|
|
price: product.priceValue * 10, // Assuming priceValue is in Toman, converting to Rial
|
|
availability: 'https://schema.org/InStock',
|
|
itemCondition: 'https://schema.org/NewCondition'
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
|
/>
|
|
<ProductPage productSlug={resolvedParams.slug} />
|
|
</>
|
|
);
|
|
}
|