/* 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
{/* Mobile toggle */}
{/* Mobile drawer */}
{mobile && (
)}
>
);
};
// ============================================================
// 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 (
setErrored(true)}
style={{
width: "100%", height: "100%", objectFit: fit,
display: "block", borderRadius: "inherit",
...style,
}}
/>
);
};
Object.assign(window, {
useHashRoute, navigate,
TopNav, WhatsAppFAB, FreshaBadge, Footer, HeroImage,
});