Zastosowanie wszystkich poprawek UI i logiki kalkulatora
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import { Metadata } from 'next';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { getProductBySlug, getProducts } from '@/content/products';
|
||||
import { companyDetails } from '@/content/company';
|
||||
import { ProductPageClient } from '@/components/shop/ProductPageClient';
|
||||
import { getProductVariants } from '@/content/product-variants';
|
||||
import { JsonLd } from '@/components/ui/JsonLd';
|
||||
|
||||
interface Props {
|
||||
params: Promise<{ slug: string }>;
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return getProducts().map(p => ({ slug: p.slug }));
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const product = getProductBySlug(slug);
|
||||
if (!product) return { title: 'Produkt nie znaleziony' };
|
||||
return {
|
||||
title: `${product.brand} ${product.name}`,
|
||||
description: product.shortDescription || `Klimatyzator ${product.name} — sprawdź specyfikację i cenę. Profesjonalny montaż na Dolnym Śląsku.`,
|
||||
alternates: { canonical: `/sklep/${product.slug}` },
|
||||
};
|
||||
}
|
||||
|
||||
export default async function ProductPage({ params }: Props) {
|
||||
const { slug } = await params;
|
||||
const product = getProductBySlug(slug);
|
||||
if (!product) notFound();
|
||||
|
||||
// Pobierz wszystkie produkty serii dla wariantów
|
||||
const variants = getProductVariants(slug);
|
||||
const allProducts = getProducts();
|
||||
const seriesProducts = variants
|
||||
? allProducts.filter(p => getProductVariants(p.slug)?.series === variants.series)
|
||||
: [product];
|
||||
|
||||
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || 'https://thermcool.pl';
|
||||
|
||||
const productJsonLd = product.price ? {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Product",
|
||||
"name": product.name,
|
||||
"description": product.shortDescription,
|
||||
"sku": product.sku,
|
||||
"brand": { "@type": "Brand", "name": product.brand },
|
||||
"image": product.image.startsWith('http') ? product.image : `${baseUrl}${product.image}`,
|
||||
"offers": {
|
||||
"@type": "Offer",
|
||||
"url": `${baseUrl}/sklep/${product.slug}`,
|
||||
"priceCurrency": "PLN",
|
||||
"price": product.price,
|
||||
"seller": { "@type": "Organization", "name": "ThermCool" },
|
||||
},
|
||||
} : null;
|
||||
|
||||
return (
|
||||
<>
|
||||
{productJsonLd && <JsonLd data={productJsonLd} />}
|
||||
<ProductPageClient
|
||||
product={product}
|
||||
seriesProducts={seriesProducts}
|
||||
companyPhone={companyDetails.phone}
|
||||
companyPhoneRaw={companyDetails.phoneRaw}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Metadata } from 'next';
|
||||
import { getProducts, getBrands } from '@/content/products';
|
||||
import { ProductsGrid } from '@/components/shop/ProductsGrid';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Sklep z klimatyzatorami',
|
||||
description: 'Klimatyzatory split i multisplit — Gree, Rotenso, Haier, Daikin, LG, Samsung i inne. Szeroki wybór, konkurencyjne ceny, profesjonalny montaż.',
|
||||
alternates: { canonical: '/sklep' },
|
||||
};
|
||||
|
||||
export default function ShopPage() {
|
||||
const products = getProducts();
|
||||
const brands = getBrands();
|
||||
const splitCount = products.filter(p => p.category === 'scienne').length;
|
||||
const multiCount = products.filter(p => p.category === 'multisplit').length;
|
||||
|
||||
return (
|
||||
<main>
|
||||
<HeroSection
|
||||
eyebrow="Sklep ThermCool"
|
||||
title="Klimatyzatory split i multisplit"
|
||||
subtitle={`${splitCount} klimatyzatorów split i ${multiCount} jednostek multisplit. Gree, Rotenso, Haier, Daikin, LG, Samsung i inne marki. Z montażem lub bez.`}
|
||||
ctaText="Zapytaj o montaż"
|
||||
ctaLink="/kontakt"
|
||||
secondaryCtaText=""
|
||||
secondaryCtaLink=""
|
||||
backgroundImage="/images/hero/shop-section-image.webp"
|
||||
/>
|
||||
<ProductsGrid products={products} brands={brands} />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user