/* ───────────────────────────────────────────────── Furnishfy — Home page (English, LTR) Sections: 1. Hero Banner 2. Categories Slider (circular, named) 3. Best Sellers slider 4. Per-Category product rows ───────────────────────────────────────────────── */ /* ── ProductCardSlide ── */ function ProductCardSlide({ p, go }) { const hasImg = p.thumbnail && !p.thumbnail.includes('no-product'); return (
go('product', p.id)} style={{ cursor: 'pointer', flexShrink: 0, width: 220 }} >
{hasImg ? {p.en} : } {p.badge && {p.badge.en}}
{p.en}
{money(p.price)} {p.old && ( {money(p.old)} )}
); } /* ── CategorySlider ── */ function CategorySlider({ categories, go, lang }) { const trackRef = useRef(null); const [canPrev, setCanPrev] = useState(false); const [canNext, setCanNext] = useState(true); const ITEM_W = 130; // approx width of each item + gap const scroll = (dir) => { if (!trackRef.current) return; trackRef.current.scrollBy({ left: dir * ITEM_W * 2, behavior: 'smooth' }); }; useEffect(() => { const el = trackRef.current; if (!el) return; const update = () => { setCanPrev(el.scrollLeft > 4); setCanNext(el.scrollLeft + el.clientWidth < el.scrollWidth - 4); }; el.addEventListener('scroll', update, { passive: true }); update(); return () => el.removeEventListener('scroll', update); }, []); const hues = [28, 95, 55, 75, 18, 40, 65, 85, 50, 30, 60, 20]; return (
{canPrev && ( )} {canNext && ( )} {/* scrollable track */}
{categories.map((c, i) => (
go('shop', null, c.id)} className="cat-item" > {/* circle */}
{c.image ? {c.en} : }
{/* name — always visible below the circle */} {lang === "ar" ? c.ar : c.en}
))}
); } /* ── CategoryProductRow ── */ function CategoryProductRow({ section, go, lang }) { const CARD_W = 220; const GAP = 20; const VIS = 4; const [offset, setOffset] = useState(0); const maxOff = Math.max(0, section.products.length - VIS); return (
{/* row header */}

{lang === "ar" ? section.ar : section.en}

{/* slider */}
{section.products.map((p) => ( ))}
); } /* ══════════════════════════════════════════════════ Main Home Component ══════════════════════════════════════════════════ */ function Home({ go, lang }) { useReveal(); const { PRODUCTS, CATEGORIES, BANNERS, BEST_SELLERS, PRODUCTS_BY_CATEGORY, } = window.FURN; /* Best sellers fallback */ const bestSellers = (BEST_SELLERS && BEST_SELLERS.length > 0) ? BEST_SELLERS : PRODUCTS.slice(0, 8); /* Per-category fallback */ const productsByCategory = (PRODUCTS_BY_CATEGORY && PRODUCTS_BY_CATEGORY.length > 0) ? PRODUCTS_BY_CATEGORY : CATEGORIES.filter(c => !c.parent).map(c => ({ id: c.id, en: c.en, ar: c.ar, products: PRODUCTS.filter(p => p.cat === c.id || CATEGORIES.find(sub => sub.id === p.cat)?.parent === c.id), })).filter(g => g.products.length > 0); /* ── Hero banner ── */ const bannersToUse = (BANNERS && BANNERS.length > 0) ? BANNERS : [ { title_en: 'The 2026 Collection', subtitle_en: 'Furniture that outlives the trend.', image: '', link: '#', }, ]; const [slide, setSlide] = useState(0); useEffect(() => { if (bannersToUse.length <= 1) return; const t = setInterval(() => setSlide(s => (s + 1) % bannersToUse.length), 5000); return () => clearInterval(t); }, [bannersToUse.length]); const activeBanner = bannersToUse[slide]; /* ── Best sellers slider offset ── */ const BS_W = 220; const BS_GAP = 20; const BS_VIS = 4; const [bsOff, setBsOff] = useState(0); const bsMax = Math.max(0, bestSellers.length - BS_VIS); return (
{/* ══ 1. HERO BANNER ══ */}
{bannersToUse.map((banner, i) => (
{(!banner.image || banner.image.endsWith('null')) && ( )}
))} {/* gradient overlay */}
{/* copy */}
The 2026 Collection — Limited Release

{activeBanner.title_en}

{activeBanner.subtitle_en}

{/* dots */} {bannersToUse.length > 1 && (
{bannersToUse.map((_, i) => (
)}
Scroll
{/* ══ 2. CATEGORIES SLIDER ══ */}
Shop by category

Featured Categories

!c.parent).filter(c => { const childIds = CATEGORIES.filter(sub => sub.parent === c.id).map(sub => sub.id); const count = PRODUCTS.filter(p => p.cat === c.id || childIds.includes(p.cat)).length; return count > 0; })} go={go} lang={lang} />
{/* ══ 3. BEST SELLERS ══ */}
Top picks

Best Sellers

{bsOff > 0 && ( )} {bsOff < bsMax && ( )}
{bestSellers.map((p) => ( ))}
{/* ══ 4. PRODUCTS BY CATEGORY ══ */}
Browse the collection

Shop by Category

{productsByCategory.map((section) => ( ))}
{/* ══ STYLES ══ */}
); } Object.assign(window, { Home });