144 lines
5.5 KiB
TypeScript
144 lines
5.5 KiB
TypeScript
import { notFound } from 'next/navigation';
|
|
import { MDXRemote } from 'next-mdx-remote/rsc';
|
|
import { getProductBySlug, getAllProducts } from '@/lib/mdx';
|
|
import ProductTechnicalData from '@/components/ProductTechnicalData';
|
|
import ProductTabs from '@/components/ProductTabs';
|
|
import RequestQuoteForm from '@/components/RequestQuoteForm';
|
|
import RelatedProducts from '@/components/RelatedProducts';
|
|
import Link from 'next/link';
|
|
|
|
interface ProductPageProps {
|
|
params: {
|
|
locale: string;
|
|
slug: string[];
|
|
};
|
|
}
|
|
|
|
const components = {
|
|
ProductTechnicalData,
|
|
ProductTabs,
|
|
p: (props: any) => <div {...props} className="mb-4" />,
|
|
table: (props: any) => (
|
|
<div className="overflow-x-auto my-8">
|
|
<table {...props} className="min-w-full divide-y divide-neutral-dark border border-neutral-dark" />
|
|
</div>
|
|
),
|
|
};
|
|
|
|
export default async function ProductPage({ params }: ProductPageProps) {
|
|
const { locale, slug } = params;
|
|
const productSlug = slug[slug.length - 1];
|
|
|
|
// Check if it's a category page
|
|
const categories = ['low-voltage-cables', 'medium-voltage-cables', 'high-voltage-cables', 'solar-cables'];
|
|
if (categories.includes(productSlug)) {
|
|
const allProducts = await getAllProducts(locale);
|
|
const categoryTitle = productSlug.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
|
|
|
// Filter products for this category
|
|
// Note: MDX categories are like "Low Voltage Cables"
|
|
const filteredProducts = allProducts.filter(p =>
|
|
p.frontmatter.categories.some(cat => cat.toLowerCase().replace(/\s+/g, '-') === productSlug)
|
|
);
|
|
|
|
return (
|
|
<div className="container mx-auto px-4 py-12">
|
|
<h1 className="text-4xl font-bold text-primary mb-8">{categoryTitle}</h1>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
{filteredProducts.map((product) => (
|
|
<Link
|
|
key={product.slug}
|
|
href={`/${locale}/products/${productSlug}/${product.slug}`}
|
|
className="group block bg-white rounded-lg overflow-hidden shadow-sm hover:shadow-md transition-all border border-neutral-dark"
|
|
>
|
|
<div className="aspect-[4/3] relative bg-neutral-light">
|
|
{product.frontmatter.images?.[0] && (
|
|
<img
|
|
src={product.frontmatter.images[0]}
|
|
alt={product.frontmatter.title}
|
|
className="w-full h-full object-contain p-4 group-hover:scale-105 transition-transform duration-300"
|
|
/>
|
|
)}
|
|
</div>
|
|
<div className="p-6">
|
|
<h2 className="text-xl font-bold text-text-primary group-hover:text-primary transition-colors">
|
|
{product.frontmatter.title}
|
|
</h2>
|
|
<p className="text-text-secondary mt-2 line-clamp-2 text-sm">
|
|
{product.frontmatter.description}
|
|
</p>
|
|
</div>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const product = await getProductBySlug(productSlug, locale);
|
|
|
|
if (!product) {
|
|
notFound();
|
|
}
|
|
|
|
return (
|
|
<div className="container mx-auto px-4 py-8">
|
|
<div className="mb-8">
|
|
<h1 className="text-4xl font-bold text-primary mb-4">{product.frontmatter.title}</h1>
|
|
<div className="flex flex-wrap gap-2 mb-4">
|
|
{product.frontmatter.categories.map((cat, idx) => (
|
|
<span key={idx} className="bg-neutral-dark text-text-secondary px-2 py-1 rounded text-sm">
|
|
{cat}
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
<div className="lg:col-span-2">
|
|
{/* Main Content Area */}
|
|
<div className="bg-white p-6 rounded-lg shadow-sm border border-neutral-dark">
|
|
<MDXRemote source={product.content} components={components} />
|
|
</div>
|
|
|
|
{/* Related Products */}
|
|
<RelatedProducts
|
|
currentSlug={productSlug}
|
|
categories={product.frontmatter.categories}
|
|
locale={locale}
|
|
/>
|
|
</div>
|
|
|
|
<div className="lg:col-span-1">
|
|
<div className="sticky top-4 space-y-6">
|
|
{/* Image Gallery */}
|
|
{product.frontmatter.images && product.frontmatter.images.length > 0 && (
|
|
<div className="bg-white p-4 rounded-lg shadow-sm border border-neutral-dark">
|
|
<div className="relative aspect-square mb-4 bg-neutral-light rounded overflow-hidden">
|
|
<img
|
|
src={product.frontmatter.images[0]}
|
|
alt={product.frontmatter.title}
|
|
className="w-full h-full object-contain"
|
|
/>
|
|
</div>
|
|
{product.frontmatter.images.length > 1 && (
|
|
<div className="grid grid-cols-4 gap-2">
|
|
{product.frontmatter.images.slice(1, 5).map((img, idx) => (
|
|
<div key={idx} className="relative aspect-square border border-neutral-dark rounded overflow-hidden bg-neutral-light">
|
|
<img src={img} alt="" className="w-full h-full object-cover" />
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
|
|
{/* Request Quote Form */}
|
|
<RequestQuoteForm productName={product.frontmatter.title} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|