Zastosowanie wszystkich poprawek UI i logiki kalkulatora

This commit is contained in:
AI Assistant
2026-08-10 23:26:52 +02:00
commit 7324a6f800
218 changed files with 33628 additions and 0 deletions
+70
View File
@@ -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}
/>
</>
);
}
+33
View File
@@ -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>
);
}