95 lines
4.4 KiB
TypeScript
95 lines
4.4 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useRef, useEffect } 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";
|
|
|
|
export function GlobalSearch() {
|
|
const [query, setQuery] = useState("");
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
|
|
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()))
|
|
: [];
|
|
|
|
return (
|
|
<>
|
|
<button
|
|
onClick={() => setIsOpen(true)}
|
|
className="p-2 text-primary hover:text-accent hover:bg-background rounded-lg transition-colors outline-none cursor-pointer"
|
|
aria-label="Szukaj na stronie"
|
|
>
|
|
<Search className="size-5" />
|
|
</button>
|
|
|
|
<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" />
|
|
<input
|
|
autoFocus
|
|
type="text"
|
|
placeholder="Wpisz nazwę klimatyzatora (np. Rotenso, Pular)..."
|
|
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)}
|
|
/>
|
|
<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>
|
|
|
|
{query.length > 1 ? (
|
|
<div className="max-h-[60vh] overflow-y-auto p-2 bg-white">
|
|
{results.length > 0 ? (
|
|
<div className="flex flex-col gap-1">
|
|
{results.map((product) => (
|
|
<Link
|
|
key={product.slug}
|
|
href={`/sklep/${product.slug}`}
|
|
onClick={() => setIsOpen(false)}
|
|
className="flex items-center gap-4 p-3 hover:bg-slate-50 rounded-lg transition-colors group border border-transparent hover:border-border"
|
|
>
|
|
<div className="w-16 h-16 bg-white border border-border rounded-md overflow-hidden relative shrink-0">
|
|
<Image
|
|
src={product.image || 'https://images.unsplash.com/photo-1621905251189-08b45d6a269e?w=800&q=80'}
|
|
alt={product.name}
|
|
fill
|
|
className="object-contain p-1 mix-blend-multiply"
|
|
/>
|
|
</div>
|
|
<div className="flex-1 flex flex-col">
|
|
<span className="text-[10px] font-bold text-text-muted uppercase tracking-wider">{product.brand}</span>
|
|
<span className="text-sm font-semibold text-primary group-hover:text-accent transition-colors">{product.name}</span>
|
|
<span className="text-xs text-text-muted mt-0.5">{product.specs?.['Moc chłodnicza'] ? `${product.specs['Moc chłodnicza']} kW • ` : ''}{product.category}</span>
|
|
</div>
|
|
<div className="text-right">
|
|
<span className="text-sm font-bold text-primary block">{product.price !== null ? formatCurrency(product.price) : 'Zapytaj o cenę'}</span>
|
|
</div>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
) : (
|
|
<div className="p-8 text-center text-text-muted">
|
|
Brak wyników dla <span className="font-semibold">"{query}"</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
) : (
|
|
<div className="p-8 text-center text-text-muted/50 text-sm bg-white">
|
|
Wpisz co najmniej 2 znaki, aby rozpocząć wyszukiwanie w sklepie
|
|
</div>
|
|
)}
|
|
</div>
|
|
<form method="dialog" className="modal-backdrop">
|
|
<button onClick={() => setIsOpen(false)}>close</button>
|
|
</form>
|
|
</dialog>
|
|
</>
|
|
);
|
|
}
|