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
)}
{/* 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
>
);
}
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) => (
))}
{/* 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 */}
{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 ? (

) : (
)}
{/* 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 ? (

) : (
)}
{/* 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 (
);
}
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'}`}>
))}
{images[activeImage] ? (

) : (
)}
{/* 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 (
DISCOVER PREMIUM LUXURY SCENTS | FREE DELIVERY ACROSS UAE FOR 2 PIECES PACKAGES
{view === 'home' && }
{view === 'shop' && }
{view === 'product' && }
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render();