wip
This commit is contained in:
@@ -1,31 +1,22 @@
|
||||
import { notFound } from 'next/navigation'
|
||||
import { getAllCategories, getProductsByCategory } from '@/lib/data'
|
||||
import { getAllCategories, getProductsByCategorySlugWithExcel } from '@/lib/data'
|
||||
import { ProductList } from '@/components/ProductList'
|
||||
import { Metadata } from 'next'
|
||||
import { ContentRenderer } from '@/components/content/ContentRenderer'
|
||||
|
||||
interface PageProps {
|
||||
params: {
|
||||
locale: string
|
||||
slug: string
|
||||
}
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const categories = getAllCategories()
|
||||
return categories.map((category) => ({
|
||||
locale: 'de', // Default locale
|
||||
slug: category.slug
|
||||
}))
|
||||
slug: string;
|
||||
locale: string;
|
||||
};
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
|
||||
const categories = getAllCategories()
|
||||
const category = categories.find((cat) => cat.slug === params.slug)
|
||||
|
||||
const category = categories.find(c => c.slug === params.slug && c.locale === params.locale)
|
||||
|
||||
if (!category) {
|
||||
return {
|
||||
title: 'Category Not Found'
|
||||
title: 'Category not found',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,26 +28,24 @@ export async function generateMetadata({ params }: PageProps): Promise<Metadata>
|
||||
|
||||
export default async function ProductCategoryPage({ params }: PageProps) {
|
||||
const categories = getAllCategories()
|
||||
const category = categories.find((cat) => cat.slug === params.slug)
|
||||
const category = categories.find(c => c.slug === params.slug && c.locale === params.locale)
|
||||
|
||||
if (!category) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
const products = getProductsByCategory(category.id, params.locale)
|
||||
const products = getProductsByCategorySlugWithExcel(params.slug, params.locale)
|
||||
|
||||
return (
|
||||
<div className="container mx-auto px-4 py-8">
|
||||
<h1 className="text-4xl font-bold mb-6">{category.name}</h1>
|
||||
{category.description && (
|
||||
<ContentRenderer
|
||||
content={category.description}
|
||||
className="mb-8 prose max-w-none"
|
||||
/>
|
||||
)}
|
||||
<h1 className="text-4xl font-bold mb-8">{category.name}</h1>
|
||||
|
||||
{category.description && (
|
||||
<p className="text-gray-600 mb-8 text-lg">{category.description}</p>
|
||||
)}
|
||||
|
||||
{products.length > 0 ? (
|
||||
<ProductList products={products} />
|
||||
<ProductList products={products} locale={params.locale as 'en' | 'de'} />
|
||||
) : (
|
||||
<p className="text-gray-500">No products found in this category.</p>
|
||||
)}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { getProductBySlug, getAllProducts, getCategoriesByLocale } from '@/lib/data';
|
||||
import { getProductBySlugWithExcel, getAllProducts, getCategoriesByLocale } from '@/lib/data';
|
||||
import { getSiteInfo, t, getLocaleFromPath, getLocalizedPath } from '@/lib/i18n';
|
||||
import { SEO } from '@/components/SEO';
|
||||
import { LocaleSwitcher } from '@/components/LocaleSwitcher';
|
||||
@@ -16,7 +16,7 @@ interface PageProps {
|
||||
|
||||
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
|
||||
const locale = (params.locale as string) || 'en';
|
||||
const product = getProductBySlug(params.slug, locale as 'en' | 'de');
|
||||
const product = getProductBySlugWithExcel(params.slug, locale as 'en' | 'de');
|
||||
|
||||
if (!product) {
|
||||
return {
|
||||
@@ -67,7 +67,7 @@ export async function generateStaticParams() {
|
||||
|
||||
export default async function ProductDetailPage({ params }: PageProps) {
|
||||
const locale = (params.locale as string) || 'en';
|
||||
const product = getProductBySlug(params.slug, locale as 'en' | 'de');
|
||||
const product = getProductBySlugWithExcel(params.slug, locale as 'en' | 'de');
|
||||
|
||||
if (!product) {
|
||||
notFound();
|
||||
@@ -87,6 +87,10 @@ export default async function ProductDetailPage({ params }: PageProps) {
|
||||
)
|
||||
.slice(0, 4);
|
||||
|
||||
// Prepare technical data for display
|
||||
const hasExcelData = product.excelConfigurations && product.excelConfigurations.length > 0;
|
||||
const hasExcelAttributes = product.excelAttributes && product.excelAttributes.length > 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
<SEO
|
||||
@@ -184,6 +188,53 @@ export default async function ProductDetailPage({ params }: PageProps) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Excel Technical Data Section */}
|
||||
{(hasExcelData || hasExcelAttributes) && (
|
||||
<div className="border-t border-gray-200 pt-6 mb-8">
|
||||
<h3 className="text-sm font-medium text-gray-900 mb-3">
|
||||
{locale === 'de' ? 'Technische Daten' : 'Technical Data'}
|
||||
</h3>
|
||||
|
||||
{/* Configurations */}
|
||||
{hasExcelData && (
|
||||
<div className="mb-4">
|
||||
<h4 className="text-xs font-semibold text-gray-600 mb-2">
|
||||
{locale === 'de' ? 'Konfigurationen' : 'Configurations'}
|
||||
</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{product.excelConfigurations!.map((config: string, index: number) => (
|
||||
<span
|
||||
key={index}
|
||||
className="inline-flex items-center px-2 py-1 rounded-md bg-gray-100 text-sm text-gray-700"
|
||||
>
|
||||
{config}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Excel Attributes */}
|
||||
{hasExcelAttributes && (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
{product.excelAttributes!.map((attr: any, index: number) => (
|
||||
<div key={index} className="bg-gray-50 rounded-lg p-3">
|
||||
<div className="text-xs font-semibold text-gray-700 mb-1">
|
||||
{attr.name}
|
||||
</div>
|
||||
<div className="text-sm text-gray-600">
|
||||
{attr.options.length === 1
|
||||
? attr.options[0]
|
||||
: attr.options.slice(0, 3).join(' / ') + (attr.options.length > 3 ? ' / ...' : '')
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Product Description */}
|
||||
{processedDescription && (
|
||||
<div className="border-t border-gray-200 pt-6 mb-8">
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import { Metadata } from 'next'
|
||||
import { t } from '@/lib/i18n'
|
||||
import { ProductList } from '@/components/ProductList'
|
||||
import { getAllProducts } from '@/lib/data'
|
||||
import { getProductsForLocaleWithExcel } from '@/lib/data'
|
||||
import { Locale } from '@/lib/i18n'
|
||||
import Link from 'next/link'
|
||||
|
||||
interface PageProps {
|
||||
params: {
|
||||
locale: Locale
|
||||
}
|
||||
locale: Locale;
|
||||
};
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
|
||||
export function generateMetadata({ params }: PageProps) {
|
||||
return {
|
||||
title: t('products.title', params.locale),
|
||||
description: t('products.description', params.locale),
|
||||
@@ -19,40 +17,39 @@ export async function generateMetadata({ params }: PageProps): Promise<Metadata>
|
||||
}
|
||||
|
||||
export default async function ProductsPage({ params }: PageProps) {
|
||||
const products = getAllProducts()
|
||||
const products = getProductsForLocaleWithExcel(params.locale)
|
||||
|
||||
// Get unique categories for this locale
|
||||
// Get unique categories
|
||||
const categories = Array.from(
|
||||
new Set(products
|
||||
.filter(p => p.locale === params.locale)
|
||||
.flatMap(p => p.categories || [])
|
||||
.map(c => c.slug)
|
||||
.flatMap(p => p.categories.map(c => c.slug))
|
||||
)
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="container mx-auto px-4 py-8">
|
||||
<h1 className="text-4xl font-bold mb-8">{t('products.title', params.locale)}</h1>
|
||||
|
||||
|
||||
{categories.length > 0 && (
|
||||
<div className="mb-8">
|
||||
<h2 className="text-xl font-semibold mb-4">{t('products.categories', params.locale)}</h2>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{categories.map((category) => (
|
||||
<Link
|
||||
<a
|
||||
key={category}
|
||||
href={`/${params.locale}/product-category/${category}`}
|
||||
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors"
|
||||
>
|
||||
{category}
|
||||
</Link>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{products.filter(p => p.locale === params.locale).length > 0 ? (
|
||||
<ProductList products={products.filter(p => p.locale === params.locale)} />
|
||||
<ProductList products={products.filter(p => p.locale === params.locale)} locale={params.locale} />
|
||||
) : (
|
||||
<p className="text-gray-600">{t('products.noProducts', params.locale)}</p>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user