/* global React */ const { useState, useEffect, useRef, useCallback } = React; // ============================================================ // Router (hash-based, single-file SPA) // ============================================================ const useHashRoute = () => { const get = () => { const h = window.location.hash.replace(/^#\/?/, "") || window.__BYTESGLUE_SHOWCASE_ROUTE || ""; const [path, ...rest] = h.split("/"); return { path: path || "home", sub: rest.join("/") }; }; const [route, setRoute] = useState(get()); useEffect(() => { const onHash = () => { setRoute(get()); window.scrollTo({ top: 0, behavior: "instant" }); }; window.addEventListener("hashchange", onHash); return () => window.removeEventListener("hashchange", onHash); }, []); return route; }; const navigate = (path) => { window.location.hash = path.startsWith("#") ? path : `#/${path}`; }; // ============================================================ // Top Nav — sticky, with treatment dropdown // ============================================================ const NAV = [ { label: "Treatments", path: "treatments", hasDropdown: true }, { label: "About", path: "about" }, { label: "Reviews", path: "reviews" }, { label: "Pricing", path: "pricing" }, { label: "Contact", path: "contact" }, ]; const TopNav = ({ currentPath }) => { const [scrolled, setScrolled] = useState(false); const [open, setOpen] = useState(false); const [mobile, setMobile] = useState(false); useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 24); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); return ( <> {/* Announcement bar */}
Free 15-minute consultation — book online, by phone or via WhatsApp · +971 58 195 5350
+971 58 195 5350 Book Consultation
{/* Mobile toggle */}
{/* Mobile drawer */} {mobile && (
{NAV.map(item => ( setMobile(false)} style={{ display: "block", padding: "12px 0", borderBottom: "1px solid var(--line)", fontSize: 16, fontFamily: "var(--f-display)", color: "var(--espresso)", }}>{item.label} ))} setMobile(false)} className="btn btn--primary" style={{ marginTop: 18, width: "100%" }}>Book Consultation
)}
); }; // ============================================================ // WhatsApp Floating Action Button // ============================================================ const WhatsAppFAB = () => { const [open, setOpen] = useState(false); return (
{open && (
Hi, can we help?
Message us on WhatsApp. We typically reply within minutes during clinic hours.
Start chat
)}
); }; // ============================================================ // Fresha trust badge // ============================================================ const FreshaBadge = ({ compact = false }) => ( { e.currentTarget.style.borderColor = "var(--gold)"; e.currentTarget.style.transform = "translateY(-1px)"; }} onMouseLeave={e => { e.currentTarget.style.borderColor = "var(--line)"; e.currentTarget.style.transform = "translateY(0)"; }} >
4.5 · 129 reviews verified on Fresha
); // ============================================================ // Footer // ============================================================ const Footer = () => ( ); // ============================================================ // Hero image with graceful fallback to placeholder // ============================================================ const HeroImage = ({ src, alt, label, style = {}, fit = "cover" }) => { const [errored, setErrored] = useState(false); if (errored || !src) { return (
{label || "image placeholder"}
); } return ( {alt setErrored(true)} style={{ width: "100%", height: "100%", objectFit: fit, display: "block", borderRadius: "inherit", ...style, }} /> ); }; Object.assign(window, { useHashRoute, navigate, TopNav, WhatsAppFAB, FreshaBadge, Footer, HeroImage, });