function Shop({ go, initialCat }) { const { PRODUCTS, CATEGORIES } = window.FURN; const [cat, setCat] = useState(initialCat || "all"); const [sort, setSort] = useState("featured"); const [openFilter, setOpenFilter] = useState(false); useEffect(() => { setCat(initialCat || "all"); }, [initialCat]); useReveal(); const prices = PRODUCTS.map((p) => p.price); const minLimit = prices.length > 0 ? Math.min(...prices) : 0; const maxLimit = prices.length > 0 ? Math.max(...prices) : 10000; const [minPrice, setMinPrice] = useState(minLimit); const [maxPrice, setMaxPrice] = useState(maxLimit); const [inStock, setInStock] = useState(false); const [onSale, setOnSale] = useState(false); const [searchQuery, setSearchQuery] = useState(""); // Sync price limits if PRODUCTS changes useEffect(() => { setMinPrice(minLimit); setMaxPrice(maxLimit); }, [minLimit, maxLimit]); const childSlugs = CATEGORIES.filter((c) => c.parent === cat).map((c) => c.id); let list = PRODUCTS.filter((p) => { const matchesCat = cat === "all" || p.cat === cat || childSlugs.includes(p.cat); const matchesPrice = p.price >= minPrice && p.price <= maxPrice; const matchesStock = !inStock || p.in_stock; const matchesSale = !onSale || (p.old !== null && p.old > p.price); const matchesSearch = !searchQuery.trim() || p.en.toLowerCase().includes(searchQuery.toLowerCase()) || p.ar.includes(searchQuery); return matchesCat && matchesPrice && matchesStock && matchesSale && matchesSearch; }); if (sort === "low") list = [...list].sort((a, b) => a.price - b.price); else if (sort === "high") list = [...list].sort((a, b) => b.price - a.price); else if (sort === "new") list = [...list].sort((a, b) => (b.badge?.en === "New") - (a.badge?.en === "New")); const sorts = [ { id: "featured", label: "Featured" }, { id: "low", label: "Price ↑" }, { id: "high", label: "Price ↓" }, { id: "new", label: "Newest" }, ]; const parents = CATEGORIES.filter((c) => !c.parent); const getCatCount = (catId) => { const childIds = CATEGORIES.filter((c) => c.parent === catId).map((c) => c.id); return PRODUCTS.filter((p) => p.cat === catId || childIds.includes(p.cat)).length; }; const getSubCatCount = (subId) => PRODUCTS.filter((p) => p.cat === subId).length; const activeParent = cat !== "all" ? (CATEGORIES.find((c) => c.id === cat && !c.parent) || CATEGORIES.find((c) => c.id === (CATEGORIES.find((x) => x.id === cat)?.parent))) : null; const FilterPanel = () => (
{/* Search Filter */}

Search Collection

setSearchQuery(e.target.value)} style={{ width: "100%", padding: "10px 12px", paddingRight: 36, background: "var(--surface)", border: "1px solid var(--line)", color: "var(--ink)", borderRadius: 4, fontSize: 14 }} /> {searchQuery && ( )}
{/* Category Hierarchy */}

Category

{/* Dynamic Price Range */}

Price Range

setMinPrice(Math.max(minLimit, Math.min(maxPrice, +e.target.value)))} style={{ width: "100%", padding: "6px 8px", background: "var(--surface)", border: "1px solid var(--line)", color: "var(--ink)", borderRadius: 3, fontSize: 13 }} />
setMaxPrice(Math.min(maxLimit, Math.max(minPrice, +e.target.value)))} style={{ width: "100%", padding: "6px 8px", background: "var(--surface)", border: "1px solid var(--line)", color: "var(--ink)", borderRadius: 3, fontSize: 13 }} />
setMaxPrice(+e.target.value)} className="range" style={{ width: "100%" }} />
{money(minLimit)} {money(maxLimit)}
{/* Availability & Sale */}

Availability & Offers

{/* Sort Options */}

Sort

{sorts.map((s) => ( ))}
{/* Reset Filter Button */} {(cat !== "all" || minPrice !== minLimit || maxPrice !== maxLimit || inStock || onSale || searchQuery) && ( )}
); return (
{/* header band */}
The full collection

{cat === "all" ? "Every piece" : (CATEGORIES.find((c) => c.id === cat)?.en || "Collection")}

{/* sidebar */} {/* grid */}
{list.length} {list.length === 1 ? "piece" : "pieces"}
{list.length === 0 ? (

No pieces match this filter.

) : (
{list.map((p, i) => )}
)}
{/* mobile filter drawer */}
setOpenFilter(false)} style={{ position: "fixed", inset: 0, zIndex: 70, background: "oklch(0 0 0 /.5)", opacity: openFilter ? 1 : 0, pointerEvents: openFilter ? "auto" : "none", transition: "opacity .35s" }} />
); } Object.assign(window, { Shop });