feat: implement compare functionality, checkout flow, and add 30 blog posts
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
'use client';
|
||||
|
||||
import { useCompareStore } from '@/lib/compare-store';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { X, ShoppingCart } from 'lucide-react';
|
||||
import { useCartStore } from '@/lib/cart-store';
|
||||
|
||||
export default function PorownajPage() {
|
||||
const { items, removeItem } = useCompareStore();
|
||||
const addToCart = useCartStore((s) => s.addItem);
|
||||
|
||||
if (items.length === 0) {
|
||||
return (
|
||||
<main className="min-h-screen bg-slate-50 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<p className="text-text-muted mb-4">Nie masz żadnych produktów do porównania.</p>
|
||||
<Link href="/sklep">
|
||||
<button className="btn btn-primary text-white font-bold">Wróć do sklepu</button>
|
||||
</Link>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
const allSpecKeys = [...new Set(items.flatMap((i) => Object.keys(i.specs)))];
|
||||
|
||||
return (
|
||||
<main className="bg-slate-50 min-h-screen py-8">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex items-center justify-between mb-8">
|
||||
<h1 className="text-2xl font-bold text-primary font-heading">Porównanie produktów</h1>
|
||||
<Link href="/sklep" className="text-sm text-accent hover:underline">← Wróć do sklepu</Link>
|
||||
</div>
|
||||
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full bg-white rounded-xl border border-border overflow-hidden">
|
||||
<thead>
|
||||
<tr className="border-b border-border">
|
||||
<td className="p-4 w-36 bg-slate-50" />
|
||||
{items.map((item) => (
|
||||
<td key={item.slug} className="p-4 text-center align-top border-l border-border">
|
||||
<div className="relative mx-auto size-24 mb-3">
|
||||
<Image
|
||||
src={item.image}
|
||||
alt={item.name}
|
||||
fill
|
||||
className="object-contain"
|
||||
unoptimized={item.image.startsWith('http')}
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs text-accent font-semibold uppercase mb-1">{item.brand}</p>
|
||||
<p className="text-sm font-bold text-primary font-heading leading-snug">{item.name}</p>
|
||||
{item.price && (
|
||||
<p className="text-lg font-bold text-primary mt-2">
|
||||
{item.price.toLocaleString('pl-PL')} zł
|
||||
</p>
|
||||
)}
|
||||
<div className="flex gap-2 mt-3 justify-center">
|
||||
{item.price && (
|
||||
<button
|
||||
onClick={() => addToCart({
|
||||
slug: item.slug,
|
||||
name: item.name,
|
||||
brand: item.brand,
|
||||
image: item.image,
|
||||
price: item.price!,
|
||||
})}
|
||||
className="flex items-center gap-1 px-3 py-1.5 bg-accent text-white rounded-lg text-xs font-bold hover:bg-accent/90 transition-colors"
|
||||
>
|
||||
<ShoppingCart className="size-3" /> Do koszyka
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={() => removeItem(item.slug)}
|
||||
className="p-1.5 text-text-muted hover:text-primary border border-border rounded-lg transition-colors"
|
||||
>
|
||||
<X className="size-3.5" />
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{allSpecKeys.map((key, idx) => (
|
||||
<tr key={key} className={`border-b border-border ${idx % 2 === 0 ? 'bg-white' : 'bg-slate-50'}`}>
|
||||
<td className="p-3 text-xs font-medium text-text-muted bg-slate-50 border-r border-border">
|
||||
{key}
|
||||
</td>
|
||||
{items.map((item) => (
|
||||
<td key={item.slug} className="p-3 text-sm text-primary text-center border-l border-border">
|
||||
{item.specs[key] || <span className="text-border">—</span>}
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user