feat: dodanie kalkulatora doboru klimatyzacji i zaktualizowanie 996 produktów
This commit is contained in:
@@ -42,7 +42,6 @@ export function ProductCard({ product }: ProductCardProps) {
|
||||
price: product.price,
|
||||
});
|
||||
setAdded(true);
|
||||
setTimeout(() => setAdded(false), 1500);
|
||||
};
|
||||
|
||||
const handleCompare = (e: React.MouseEvent) => {
|
||||
@@ -161,20 +160,22 @@ export function ProductCard({ product }: ProductCardProps) {
|
||||
)}
|
||||
|
||||
{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>
|
||||
added ? (
|
||||
<Link
|
||||
href="/koszyk"
|
||||
className="flex items-center gap-1.5 px-3 py-2 rounded-lg text-xs font-bold bg-green-500 text-white hover:bg-green-600 transition-colors shrink-0"
|
||||
onClick={e => e.stopPropagation()}
|
||||
>
|
||||
<ShoppingCart className="size-3.5" /> Zobacz koszyk
|
||||
</Link>
|
||||
) : (
|
||||
<button
|
||||
onClick={handleAddToCart}
|
||||
className="flex items-center gap-1.5 px-3 py-2 rounded-lg text-xs font-bold bg-accent text-white hover:bg-accent/90 transition-colors shrink-0"
|
||||
>
|
||||
<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">
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useMemo } from 'react';
|
||||
import { useState, useMemo, useEffect } from 'react';
|
||||
import { ChevronDown, ChevronUp, Phone, X } from 'lucide-react';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { Product } from '@/content/products';
|
||||
import { ProductCard } from './ProductCard';
|
||||
@@ -10,8 +11,6 @@ import { companyDetails } from '@/content/company';
|
||||
interface ProductsGridProps {
|
||||
products: Product[];
|
||||
brands: string[];
|
||||
initialSearch?: string;
|
||||
initialBrand?: string;
|
||||
}
|
||||
|
||||
const PER_PAGE = 24;
|
||||
@@ -76,10 +75,17 @@ function Accordion({ title, children, defaultOpen = true }: AccordionProps) {
|
||||
);
|
||||
}
|
||||
|
||||
export function ProductsGrid({ products, brands, initialSearch, initialBrand }: ProductsGridProps) {
|
||||
const [category, setCategory] = useState<'all' | 'scienne' | 'multisplit'>('all');
|
||||
const [selectedBrands, setSelectedBrands] = useState<string[]>(initialBrand ? [initialBrand] : []);
|
||||
const [searchQuery, setSearchQuery] = useState(initialSearch || '');
|
||||
export function ProductsGrid({ products, brands }: ProductsGridProps) {
|
||||
const searchParams = useSearchParams();
|
||||
const urlSearch = searchParams.get('search') || '';
|
||||
const urlBrand = searchParams.get('brand') || '';
|
||||
const urlCategory = searchParams.get('category') || 'all';
|
||||
|
||||
const [category, setCategory] = useState<'all' | 'scienne' | 'multisplit' | 'kasetonowe' | 'kanalowe' | 'konsolowe' | 'podlogowe' | 'jednostka-scienna'>(
|
||||
urlCategory as 'all' | 'scienne' | 'multisplit' | 'kasetonowe' | 'kanalowe' | 'konsolowe' | 'podlogowe' | 'jednostka-scienna'
|
||||
);
|
||||
const [selectedBrands, setSelectedBrands] = useState<string[]>(urlBrand ? [urlBrand] : []);
|
||||
const [searchQuery, setSearchQuery] = useState(urlSearch);
|
||||
const [priceMin, setPriceMin] = useState('');
|
||||
const [priceMax, setPriceMax] = useState('');
|
||||
const [selectedRooms, setSelectedRooms] = useState<string[]>([]);
|
||||
@@ -89,6 +95,17 @@ export function ProductsGrid({ products, brands, initialSearch, initialBrand }:
|
||||
const [page, setPage] = useState(1);
|
||||
const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setSearchQuery(urlSearch);
|
||||
setSelectedBrands(urlBrand ? [urlBrand] : []);
|
||||
if (urlCategory !== 'all') {
|
||||
setCategory(urlCategory as 'scienne' | 'multisplit' | 'kasetonowe' | 'kanalowe' | 'konsolowe' | 'podlogowe' | 'jednostka-scienna');
|
||||
} else {
|
||||
setCategory('all');
|
||||
}
|
||||
setPage(1);
|
||||
}, [urlSearch, urlBrand, urlCategory]);
|
||||
|
||||
const toggleBrand = (b: string) => {
|
||||
setSelectedBrands(prev => prev.includes(b) ? prev.filter(x => x !== b) : [...prev, b]);
|
||||
setPage(1);
|
||||
@@ -207,8 +224,11 @@ export function ProductsGrid({ products, brands, initialSearch, initialBrand }:
|
||||
<ul className="flex flex-col gap-2">
|
||||
{[
|
||||
{ val: 'all', label: 'Wszystkie' },
|
||||
{ val: 'scienne', label: 'Klimatyzacja ścienna' },
|
||||
{ val: 'multisplit', label: 'Klimatyzacja Multisplit' },
|
||||
{ val: 'scienne', label: 'Ścienne split' },
|
||||
{ val: 'multisplit', label: 'Multisplit' },
|
||||
{ val: 'kasetonowe', label: 'Kasetonowe' },
|
||||
{ val: 'konsolowe', label: 'Konsolowe' },
|
||||
{ val: 'kanalowe', label: 'Kanałowe' },
|
||||
].map(opt => (
|
||||
<li key={opt.val}>
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user