wip
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
import { notFound } from 'next/navigation';
|
||||
import { MDXRemote } from 'next-mdx-remote/rsc';
|
||||
import { getProductBySlug } from '@/lib/mdx';
|
||||
import { getProductBySlug, getAllProducts } from '@/lib/mdx';
|
||||
import ProductTechnicalData from '@/components/ProductTechnicalData';
|
||||
import Image from 'next/image';
|
||||
import ProductTabs from '@/components/ProductTabs';
|
||||
import RequestQuoteForm from '@/components/RequestQuoteForm';
|
||||
import RelatedProducts from '@/components/RelatedProducts';
|
||||
import Link from 'next/link';
|
||||
|
||||
interface ProductPageProps {
|
||||
params: {
|
||||
@@ -13,12 +16,64 @@ interface ProductPageProps {
|
||||
|
||||
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]; // Use the last segment as the slug
|
||||
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);
|
||||
|
||||
@@ -41,42 +96,46 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
||||
<div className="lg:col-span-2">
|
||||
<div className="prose max-w-none mb-8">
|
||||
<MDXRemote source={product.content} components={components} />
|
||||
{/* 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">
|
||||
{product.frontmatter.images && product.frontmatter.images.length > 0 && (
|
||||
<div className="sticky top-4">
|
||||
<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">
|
||||
{/* Note: Images from WC might be external URLs. Next/Image requires configuration for external domains. */}
|
||||
{/* For now using standard img tag if domain not configured, or configure domains. */}
|
||||
<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>
|
||||
<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">
|
||||
<img src={img} alt="" className="w-full h-full object-cover" />
|
||||
</div>
|
||||
))}
|
||||
</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>
|
||||
|
||||
<div className="mt-6 bg-primary-light p-6 rounded-lg">
|
||||
<h3 className="text-lg font-semibold text-primary-dark mb-2">Contact Us</h3>
|
||||
<p className="text-text-secondary mb-4">Need more information about {product.frontmatter.title}?</p>
|
||||
<button className="w-full bg-primary text-white py-2 px-4 rounded hover:bg-primary-dark transition-colors">
|
||||
Request Quote
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
|
||||
{/* Request Quote Form */}
|
||||
<RequestQuoteForm productName={product.frontmatter.title} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user