163 lines
6.0 KiB
TypeScript
163 lines
6.0 KiB
TypeScript
'use client';
|
|
|
|
import Link from 'next/link';
|
|
import Image from 'next/image';
|
|
import { ShoppingCart, GitCompare, Phone, Check } from 'lucide-react';
|
|
import { Product } from '@/content/products';
|
|
import { useCartStore } from '@/lib/cart-store';
|
|
import { useCompareStore } from '@/lib/compare-store';
|
|
import { useState } from 'react';
|
|
|
|
interface ProductCardProps {
|
|
product: Product;
|
|
}
|
|
|
|
export function ProductCard({ product }: ProductCardProps) {
|
|
const addItem = useCartStore((s) => s.addItem);
|
|
const { addItem: addCompare, removeItem: removeCompare, isAdded, items: compareItems } = useCompareStore();
|
|
const [added, setAdded] = useState(false);
|
|
|
|
const handleAddToCart = (e: React.MouseEvent) => {
|
|
e.preventDefault();
|
|
if (!product.price) return;
|
|
addItem({
|
|
slug: product.slug,
|
|
name: product.name,
|
|
brand: product.brand,
|
|
image: product.image,
|
|
price: product.price,
|
|
});
|
|
setAdded(true);
|
|
setTimeout(() => setAdded(false), 1500);
|
|
};
|
|
|
|
const handleCompare = (e: React.MouseEvent) => {
|
|
e.preventDefault();
|
|
if (isAdded(product.slug)) {
|
|
removeCompare(product.slug);
|
|
} else {
|
|
addCompare({
|
|
slug: product.slug,
|
|
name: product.name,
|
|
brand: product.brand,
|
|
price: product.price,
|
|
image: product.image,
|
|
specs: product.specs,
|
|
});
|
|
}
|
|
};
|
|
|
|
const inCompare = isAdded(product.slug);
|
|
const compareDisabled = compareItems.length >= 3 && !inCompare;
|
|
|
|
return (
|
|
<div className="group relative bg-white rounded-xl border border-border hover:border-accent hover:shadow-md transition-all duration-200 overflow-hidden flex flex-col">
|
|
{/* Zdjęcie */}
|
|
<Link href={`/sklep/${product.slug}`} className="block relative aspect-[4/3] bg-slate-50 overflow-hidden">
|
|
<Image
|
|
src={product.image}
|
|
alt={product.name}
|
|
fill
|
|
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
|
|
className="object-contain p-6 group-hover:scale-105 transition-transform duration-300"
|
|
unoptimized={product.image.startsWith('http')}
|
|
/>
|
|
|
|
{/* Badge marka */}
|
|
<span className="absolute top-2 left-2 px-2 py-1 bg-white/95 rounded-md text-xs font-semibold text-primary border border-border shadow-sm">
|
|
{product.brand}
|
|
</span>
|
|
|
|
{/* Badge multisplit */}
|
|
{product.category === 'multisplit' && (
|
|
<span className="absolute top-2 right-2 px-2 py-1 bg-accent/10 rounded-md text-xs font-semibold text-accent border border-accent/20">
|
|
Multisplit
|
|
</span>
|
|
)}
|
|
|
|
{/* Porównywarka - pojawia się na hover */}
|
|
<button
|
|
onClick={handleCompare}
|
|
disabled={compareDisabled}
|
|
title={inCompare ? 'Usuń z porównywarki' : compareDisabled ? 'Max 3 produkty' : 'Dodaj do porównania'}
|
|
className={`absolute bottom-2 right-2 p-1.5 rounded-lg border transition-all ${
|
|
inCompare
|
|
? 'bg-accent text-white border-accent opacity-100'
|
|
: 'bg-white/90 text-text-muted border-border opacity-0 group-hover:opacity-100 hover:border-accent hover:text-accent'
|
|
} ${compareDisabled ? 'opacity-30 cursor-not-allowed' : ''}`}
|
|
>
|
|
<GitCompare className="size-3.5" />
|
|
</button>
|
|
</Link>
|
|
|
|
{/* Treść */}
|
|
<div className="p-4 flex flex-col flex-1 gap-2">
|
|
<Link href={`/sklep/${product.slug}`}>
|
|
<h3 className="text-sm font-semibold text-primary font-heading leading-snug line-clamp-2 hover:text-accent transition-colors">
|
|
{product.name}
|
|
</h3>
|
|
</Link>
|
|
|
|
{/* Kluczowe specs */}
|
|
<div className="flex flex-wrap gap-1.5">
|
|
{product.specs['Moc chłodnicza'] && (
|
|
<span className="px-2 py-0.5 bg-slate-50 rounded text-xs text-text-muted border border-border">
|
|
{product.specs['Moc chłodnicza']} kW
|
|
</span>
|
|
)}
|
|
{product.specs['Klasa energetyczna'] && (
|
|
<span className="px-2 py-0.5 bg-green-50 rounded text-xs text-green-700 border border-green-100 font-medium">
|
|
{product.specs['Klasa energetyczna']}
|
|
</span>
|
|
)}
|
|
{product.specs['Czynnik chłodniczy'] && (
|
|
<span className="px-2 py-0.5 bg-slate-50 rounded text-xs text-text-muted border border-border">
|
|
{product.specs['Czynnik chłodniczy']}
|
|
</span>
|
|
)}
|
|
</div>
|
|
|
|
{/* Cena + CTA */}
|
|
<div className="mt-auto pt-2 flex items-end justify-between gap-2">
|
|
{product.price !== null ? (
|
|
<div>
|
|
<p className="text-lg font-bold text-primary font-heading leading-none">
|
|
{product.price.toLocaleString('pl-PL')} zł
|
|
</p>
|
|
<p className="text-xs text-text-muted mt-0.5">brutto</p>
|
|
</div>
|
|
) : (
|
|
<div className="flex items-center gap-1 text-accent">
|
|
<Phone className="size-3.5" />
|
|
<span className="text-sm font-semibold">Zapytaj o cenę</span>
|
|
</div>
|
|
)}
|
|
|
|
{product.price !== null ? (
|
|
<button
|
|
onClick={handleAddToCart}
|
|
className={`flex items-center gap-1.5 px-3 py-2 rounded-lg text-xs font-bold transition-all shrink-0 ${
|
|
added
|
|
? 'bg-green-500 text-white'
|
|
: 'bg-accent text-white hover:bg-accent/90'
|
|
}`}
|
|
>
|
|
{added ? (
|
|
<><Check className="size-3.5" /> Dodano</>
|
|
) : (
|
|
<><ShoppingCart className="size-3.5" /> Do koszyka</>
|
|
)}
|
|
</button>
|
|
) : (
|
|
<Link href="/kontakt">
|
|
<button className="flex items-center gap-1.5 px-3 py-2 rounded-lg text-xs font-bold bg-primary text-white hover:bg-primary/90 transition-colors shrink-0">
|
|
Zapytaj
|
|
</button>
|
|
</Link>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|