feat: optymalizacja GlobalSearch, nawigacji oraz filtrów w sklepie

This commit is contained in:
MichalC
2026-06-27 21:12:23 +02:00
parent 0c59086a6b
commit c4294a81cf
43 changed files with 1623 additions and 192 deletions
+36 -7
View File
@@ -1,20 +1,40 @@
"use client";
import { useState, useRef, useEffect } from "react";
import { useState, useRef, useEffect, useMemo } from "react";
import { Search } from "lucide-react";
import { getProducts } from "@/content/products";
import Link from "next/link";
import Image from "next/image";
import { formatCurrency } from "@/lib/utils";
import { useRouter } from "next/navigation";
const allProducts = getProducts();
export function GlobalSearch() {
const [query, setQuery] = useState("");
const [isOpen, setIsOpen] = useState(false);
const router = useRouter();
const products = getProducts();
const results = query.length > 1
? products.filter(p => p.name.toLowerCase().includes(query.toLowerCase()) || p.brand.toLowerCase().includes(query.toLowerCase()) || p.category.toLowerCase().includes(query.toLowerCase()))
: [];
const results = useMemo(() => {
if (query.length < 2) return [];
const q = query.toLowerCase();
return allProducts
.filter(p =>
p.name.toLowerCase().includes(q) ||
p.brand.toLowerCase().includes(q) ||
p.category.toLowerCase().includes(q) ||
(p.sku && p.sku.toLowerCase().includes(q))
)
.slice(0, 20);
}, [query]);
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter' && query.length > 1) {
router.push(`/sklep?search=${encodeURIComponent(query)}`);
setIsOpen(false);
setQuery('');
}
};
return (
<>
@@ -29,7 +49,15 @@ export function GlobalSearch() {
<dialog className={`modal ${isOpen ? "modal-open" : ""}`}>
<div className="modal-box p-0 max-w-2xl bg-white rounded-2xl overflow-hidden mt-[-20vh]">
<div className="flex items-center border-b border-border px-4 py-3 bg-slate-50">
<Search className="size-5 text-accent mr-3 shrink-0" />
<button aria-label="Szukaj" onClick={() => {
if (query.length > 1) {
router.push(`/sklep?search=${encodeURIComponent(query)}`);
setIsOpen(false);
setQuery('');
}
}}>
<Search className="size-5 text-accent mr-3 shrink-0 hover:text-primary transition-colors cursor-pointer" />
</button>
<input
autoFocus
type="text"
@@ -37,8 +65,9 @@ export function GlobalSearch() {
className="flex-1 outline-none text-base placeholder:text-text-muted/50 bg-transparent py-2 text-primary font-medium"
value={query}
onChange={(e) => setQuery(e.target.value)}
onKeyDown={handleKeyDown}
/>
<button onClick={() => setIsOpen(false)} className="text-xs font-semibold text-text-muted hover:text-primary transition-colors bg-white px-2 py-1 rounded border border-border shadow-sm">
<button type="button" onClick={() => setIsOpen(false)} className="text-xs font-semibold text-text-muted hover:text-primary transition-colors bg-white px-2 py-1 rounded border border-border shadow-sm">
ESC
</button>
</div>
+25 -7
View File
@@ -76,20 +76,33 @@ export function Header() {
},
],
},
];
const miastaSections = [
{
title: "Montaż w Twoim mieście",
title: "Dolny Śląsk — centrum",
items: [
{ label: "Klimatyzacja Wrocław", href: "/klimatyzacja/wroclaw", description: "Montaż i serwis we Wrocławiu" },
{ label: "Klimatyzacja Legnica", href: "/klimatyzacja/legnica", description: "Obsługujemy Legnicę i okolice" },
{ label: "Klimatyzacja Wałbrzych", href: "/klimatyzacja/walbrzych", description: "Montaż w Wałbrzychu" },
{ label: "Klimatyzacja Jelenia Góra", href: "/klimatyzacja/jelenia-gora", description: "Dolny Śląsk — południe" },
{ label: "→ Wszystkie miasta", href: "/klimatyzacja#miasta", description: "Cały Dolny Śląsk" },
{ label: "Klimatyzacja Oława", href: "/klimatyzacja/olawa", description: "25 km od Wrocławia" },
{ label: "Klimatyzacja Oleśnica", href: "/klimatyzacja/olesnica", description: "30 km od Wrocławia" },
{ label: "Klimatyzacja Środa Śląska", href: "/klimatyzacja/sroda-slaska", description: "35 km od Wrocławia" },
{ label: "Klimatyzacja Trzebnica", href: "/klimatyzacja/trzebnica", description: "25 km od Wrocławia" },
{ label: "Klimatyzacja Siechnice", href: "/klimatyzacja/siechnice", description: "15 km od Wrocławia" },
],
},
{
title: "Dolny Śląsk — regiony",
items: [
{ label: "Klimatyzacja Legnica", href: "/klimatyzacja/legnica", description: "Legnica i okolice" },
{ label: "Klimatyzacja Wałbrzych", href: "/klimatyzacja/walbrzych", description: "Wałbrzych i Kotlina" },
{ label: "Klimatyzacja Jelenia Góra", href: "/klimatyzacja/jelenia-gora", description: "Karkonosze i okolice" },
{ label: "Klimatyzacja Lubin", href: "/klimatyzacja/lubin", description: "Zagłębie Miedziowe" },
{ label: "Klimatyzacja Głogów", href: "/klimatyzacja/glogow", description: "Głogów i powiat" },
{ label: "Klimatyzacja Świdnica", href: "/klimatyzacja/swidnica", description: "Świdnica i okolice" },
],
},
];
return (
<>
{/* ----------------- DESKTOP: TOP BAR ----------------- */}
@@ -156,6 +169,11 @@ export function Header() {
sections={acSections}
align="left"
/>
<NavDropdown
label="Miasta"
sections={miastaSections}
align="left"
/>
<Link
href="/pompy-ciepla"
className="text-sm font-medium text-primary hover:text-accent transition-colors"
+36
View File
@@ -100,6 +100,42 @@ export function MobileMenu({ isOpen, onClose }: MobileMenuProps) {
</div>
</details>
{/* Nowa sekcja: Miasta */}
<div className="border-b border-border py-3">
<details className="collapse collapse-arrow rounded-none">
<summary className="collapse-title text-sm font-medium text-primary hover:text-accent py-0 px-0 min-h-0">
Montaż w miastach
</summary>
<div className="collapse-content px-0 pb-2">
<ul className="flex flex-col gap-2 pl-4 pb-2 mt-2">
{[
{ label: "Klimatyzacja Wrocław", href: "/klimatyzacja/wroclaw" },
{ label: "Klimatyzacja Legnica", href: "/klimatyzacja/legnica" },
{ label: "Klimatyzacja Wałbrzych", href: "/klimatyzacja/walbrzych" },
{ label: "Klimatyzacja Jelenia Góra", href: "/klimatyzacja/jelenia-gora" },
{ label: "Klimatyzacja Lubin", href: "/klimatyzacja/lubin" },
{ label: "Klimatyzacja Głogów", href: "/klimatyzacja/glogow" },
{ label: "Klimatyzacja Świdnica", href: "/klimatyzacja/swidnica" },
{ label: "Klimatyzacja Oława", href: "/klimatyzacja/olawa" },
{ label: "Klimatyzacja Oleśnica", href: "/klimatyzacja/olesnica" },
{ label: "→ Wszystkie miasta", href: "/klimatyzacja#miasta" },
].map((item, idx) => (
<li key={idx}>
<Link
href={item.href}
onClick={onClose}
className="text-sm text-text-muted hover:text-accent transition-colors flex items-center justify-between py-1"
>
<span>{item.label}</span>
<ChevronRight className="size-3.5 opacity-60" />
</Link>
</li>
))}
</ul>
</div>
</details>
</div>
{/* 2. Pompy Ciepła */}
<div className="border-b border-border py-3">
<Link