const { useState, useEffect } = React; const fetchApi = async (url) => { const res = await fetch(url); return res.json(); }; function Navbar({ setView, activeBrandFilter, setActiveBrandFilter }) { const [menuData, setMenuData] = useState({ brands: [] }); const [isMenuOpen, setIsMenuOpen] = useState(false); const [isBrandsDropdownOpen, setIsBrandsDropdownOpen] = useState(false); const [isSearchOpen, setIsSearchOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(''); useEffect(() => { fetchApi('api/menu.php').then(res => { if (res.success) setMenuData(res.data); }); }, []); const handleSearch = (e) => { e.preventDefault(); if (searchQuery.trim()) { setView('shop', null, '', { q: searchQuery }); setIsSearchOpen(false); setIsMenuOpen(false); } }; const handleBrandSelect = (brandSlug) => { setView('shop', null, '', { brands: [brandSlug] }); setIsBrandsDropdownOpen(false); setIsMenuOpen(false); }; return ( <> {/* Search Modal Overlay */} {isSearchOpen && (

Search our fragrance house

setSearchQuery(e.target.value)} placeholder="Search by brand, note, title..." className="w-full text-2xl lg:text-4xl py-4 border-b border-[#EBE5DF] bg-transparent text-[#221C1E] outline-none focus:border-[#540B24] transition-colors font-serif placeholder-neutral-400" autoFocus />
)} {/* Mobile Sidebar Navigation */}
setIsMenuOpen(false)}>
e.stopPropagation()}>
{ setView('home'); setIsMenuOpen(false); }} className="text-xl font-serif font-bold tracking-wider text-[#221C1E] cursor-pointer"> ZAAFA

Store Nav

Perfume Brands

); } function Footer() { return ( ); } function HeroSlider() { const [current, setCurrent] = useState(0); const slides = [ "img/s1.webp", "img/s2.webp", "img/s3.webp" ]; useEffect(() => { const timer = setInterval(() => { setCurrent(prev => (prev + 1) % slides.length); }, 6000); return () => clearInterval(timer); }, [slides.length]); return (
{/* Structural base image to set height dynamically (100% width, height auto) */} {slides.map((slide, i) => ( {`Slide ))} {/* Navigation Dots */}
{slides.map((_, i) => (
{/* Navigation Arrows */}
); } function Home({ setView }) { const [data, setData] = useState({ products: [], brands: [] }); const [loading, setLoading] = useState(true); useEffect(() => { fetchApi('api/home.php').then(res => { if (res.success) setData(res.data); setLoading(false); setTimeout(() => { const pos = sessionStorage.getItem('scroll_' + (window.location.hash || '#')); if (pos) { window.scrollTo(0, parseInt(pos, 10)); } else { window.scrollTo(0, 0); } }, 50); }); }, []); const goToProduct = (prod) => { sessionStorage.setItem('scroll_' + (window.location.hash || '#'), window.scrollY); const slug = prod.title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, ''); setView('product', prod.id, slug); }; if (loading) { return (

Entering Fragrance House...

); } return (
{/* HERO SLIDER */} {/* BRANDS NAVIGATION BAR */}

Elite Perfume Houses

{data.brands.map(brand => (
setView('shop', null, '', { brands: [brand.slug] })} className="cursor-pointer border border-[#EBE5DF] hover:border-[#540B24]/50 bg-white px-4 py-2 sm:px-6 sm:py-3.5 rounded transition-all hover:scale-105"> {brand.name}
))}
{/* CURATED POPULAR PRODUCTS */}
Curated Selection

Signature Fragrances

{ e.preventDefault(); setView('shop'); }} className="text-[11px] font-bold uppercase tracking-wider text-neutral-500 hover:text-[#540B24] transition-colors border-b border-[#EBE5DF] hover:border-[#540B24] pb-1"> View All Collections
{data.products.map(prod => (
{/* Product Image */}
goToProduct(prod)} className="cursor-pointer bg-[#FAF6F0]/50 aspect-[4/5] flex items-center justify-center overflow-hidden relative border-b border-[#EBE5DF]"> {prod.main_image ? ( {prod.title} ) : ( )}
{/* Product Info */}
goToProduct(prod)} className="cursor-pointer mb-5">

{prod.title}

{/* Double Pricing options */}

1 Piece: AED {parseFloat(prod.price).toFixed(2)}

2 Pieces: AED {parseFloat(prod.price_two).toFixed(2)}

))} {data.products.length === 0 &&

No products found in the boutique.

}
); } function Shop({ setView, initialFilters }) { const [data, setData] = useState({ products: [], brands: [] }); const [loading, setLoading] = useState(true); const [activeBrands, setActiveBrands] = useState([]); useEffect(() => { const { q } = initialFilters; const qStr = q ? `?q=${encodeURIComponent(q)}` : ''; setLoading(true); fetchApi(`api/shop.php${qStr}`).then(res => { if (res.success) { setData(res.data); // Synchronize url filters if (initialFilters.brands && initialFilters.brands.length > 0) { setActiveBrands(initialFilters.brands); } else { setActiveBrands([]); } } setLoading(false); setTimeout(() => { const pos = sessionStorage.getItem('scroll_' + (window.location.hash || '#')); if (pos) { window.scrollTo(0, parseInt(pos, 10)); } else { window.scrollTo(0, 0); } }, 50); }); }, [initialFilters.q, initialFilters.brands]); // Apply client-side brand filters to fetched products let filteredProducts = data.products; if (activeBrands.length > 0) { const brandIdsToKeep = data.brands.filter(b => activeBrands.includes(b.slug)).map(b => parseInt(b.id)); filteredProducts = filteredProducts.filter(p => brandIdsToKeep.includes(parseInt(p.brand_id))); } const toggleBrand = (brandSlug) => { let newBrands = [...activeBrands]; if (newBrands.includes(brandSlug)) { newBrands = newBrands.filter(b => b !== brandSlug); } else { newBrands.push(brandSlug); } setActiveBrands(newBrands); setView('shop', null, '', { q: initialFilters.q, brands: newBrands }); }; const goToProduct = (prod) => { sessionStorage.setItem('scroll_' + (window.location.hash || '#'), window.scrollY); const slug = prod.title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, ''); setView('product', prod.id, slug); }; if (loading) { return (

Filtering Fragrance Database...

); } return (
{/* Search metadata banner if query active */} {initialFilters.q && (

Search Results For: "{initialFilters.q}"

)} {/* Main shop container */}
{/* Header row */}
Maison Catalog

Our Boutique

{filteredProducts.length} fragrances available
{/* Brands filter strip (Horizontal pill selector) */}
Filter Brand:
{data.brands.map(b => { const isSelected = activeBrands.includes(b.slug); return ( ); })}
{/* Product Grid */}
{filteredProducts.map(prod => (
{/* Product Image */}
goToProduct(prod)} className="cursor-pointer bg-[#FAF6F0]/50 aspect-[4/5] flex items-center justify-center overflow-hidden relative border-b border-[#EBE5DF]"> {prod.main_image ? ( {prod.title} ) : ( )}
{/* Product Info */}
goToProduct(prod)} className="cursor-pointer mb-5">

{prod.title}

{/* Double Pricing */}

1 Piece: AED {parseFloat(prod.price).toFixed(2)}

2 Pieces: AED {parseFloat(prod.price_two).toFixed(2)}

))} {filteredProducts.length === 0 && (

No perfumes match your filter choice.

)}
); } function ProductDetail({ productId, setView }) { const [product, setProduct] = useState(null); const [loading, setLoading] = useState(true); const [activeImage, setActiveImage] = useState(0); const [selectedQty, setSelectedQty] = useState('1'); // '1' or '2' pieces useEffect(() => { window.scrollTo(0, 0); fetchApi(`api/product.php?id=${productId}`).then(res => { if (res.success) setProduct(res.data); setLoading(false); }); }, [productId]); if (loading) { return (

Revealing Fragrance...

); } if (!product) return
Product not found.
; const images = product.images || []; const activePrice = selectedQty === '2' ? product.price_two : product.price; const getWhatsAppUrl = () => { const productTitle = product.title; const brandName = product.brand_name || 'Premium Brand'; const qtyLabel = selectedQty === '2' ? '2 Pieces Package' : '1 Piece'; const priceLabel = `AED ${parseFloat(activePrice).toFixed(2)}`; const productUrl = `${window.location.origin}${window.location.pathname}#product/${productId}-${productTitle.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '')}`; const messageText = `Hi ZAAFA, I would like to order: Fragrance: ${productTitle} Brand: ${brandName} Package Offer: ${qtyLabel} Price: ${priceLabel} Link: ${productUrl}`; return `https://wa.me/971551787454?text=${encodeURIComponent(messageText)}`; }; return (
{/* Top Breadcrumb */}
setView('home')}>Home / setView('shop')}>Perfumes / {product.title}
{/* Images Section */}
{images.map((img, i) => (
setActiveImage(i)} className={`w-20 h-24 lg:w-24 lg:h-28 flex-shrink-0 rounded overflow-hidden cursor-pointer border transition-all bg-white flex items-center justify-center p-1 ${activeImage === i ? 'border-[#540B24] opacity-100' : 'border-[#EBE5DF] opacity-50 hover:opacity-100'}`}> Thumb
))}
{images[activeImage] ? ( Main ) : ( )}
{/* Info Section */}
{product.brand_name && ( {product.brand_name} )}

{product.title}

{/* Dual Package Pricing Selector */}

Select Quantity Package

{/* 1 Piece option */}
setSelectedQty('1')} className={`cursor-pointer p-4 rounded border transition-all flex flex-col justify-between min-h-[90px] ${selectedQty === '1' ? 'bg-[#FAF6F0] border-[#540B24]' : 'bg-white border-[#EBE5DF] hover:border-[#FAF6F0]'}`}>
1 Piece
{selectedQty === '1' &&
}

AED {parseFloat(product.price).toFixed(2)}

{/* 2 Pieces option */}
setSelectedQty('2')} className={`cursor-pointer p-4 rounded border transition-all flex flex-col justify-between min-h-[90px] relative ${selectedQty === '2' ? 'bg-[#FAF6F0] border-[#540B24] shadow-md shadow-[#540B24]/5' : 'bg-white border-[#EBE5DF] hover:border-[#FAF6F0]'}`}> Best Value
2 Pieces (Combo)
{selectedQty === '2' &&
}

AED {parseFloat(product.price_two).toFixed(2)}

{/* Description (tinymce HTML) */}
{/* Order details actions */}

Free Delivery in UAE

Enjoy complimentary, reliable delivery to all UAE emirates on every order.

Cash on Delivery

Convenient Cash on Delivery (COD) services available within all UAE emirates.

); } function ScrollToTopButton() { const [isVisible, setIsVisible] = useState(false); useEffect(() => { const toggleVisibility = () => { if (window.pageYOffset > 300) { setIsVisible(true); } else { setIsVisible(false); } }; window.addEventListener("scroll", toggleVisibility); return () => window.removeEventListener("scroll", toggleVisibility); }, []); const scrollToTop = () => { window.scrollTo({ top: 0, behavior: "smooth" }); }; if (!isVisible) return null; return ( ); } function App() { const [view, setView] = useState('home'); const [currentProductId, setCurrentProductId] = useState(null); const [shopFilters, setShopFilters] = useState({ brands: [] }); // Dynamic Hash URL Routing useEffect(() => { const handleHashChange = () => { const hashStr = window.location.hash.replace('#', ''); const [path, qs] = hashStr.split('?'); const params = new URLSearchParams(qs || ''); if (path.startsWith('product/')) { const part = path.replace('product/', ''); const id = part.split('-')[0]; // Extract the ID before the dash setCurrentProductId(id); setView('product'); } else if (path.startsWith('shop')) { const brs = params.get('brands'); const q = params.get('q'); setShopFilters({ brands: brs ? brs.split(',') : [], q: q || '' }); setView('shop'); } else { setView('home'); } }; handleHashChange(); // Execute on initial load window.addEventListener('hashchange', handleHashChange); return () => window.removeEventListener('hashchange', handleHashChange); }, []); // Custom router navigate const navigate = (newView, id = null, slug = '', params = {}) => { let targetHash = ''; if (newView === 'home') { targetHash = ''; } else if (newView === 'product') { targetHash = `product/${id}${slug ? '-' + slug : ''}`; } else if (newView === 'shop') { const urlParams = new URLSearchParams(); if (params.brands && params.brands.length > 0) urlParams.set('brands', params.brands.join(',')); if (params.q) urlParams.set('q', params.q); const qs = urlParams.toString(); targetHash = `shop${qs ? '?' + qs : ''}`; } sessionStorage.removeItem('scroll_#' + targetHash); window.scrollTo(0, 0); window.location.hash = targetHash; }; return (