// Petzone — shared components (icons, logo, nav, footer, mobile bar, book sheet)
const { useState, useEffect, useRef, useMemo } = React;
// ============== ICONS (simple stroke set) ==============
const Icon = ({ name, size = 22, stroke = 1.6, className = "" }) => {
const common = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: stroke, strokeLinecap: "round", strokeLinejoin: "round", className };
const paths = {
stethoscope: <>>,
shield: <>>,
scalpel: <>>,
tooth: <>>,
flask: <>>,
scan: <>>,
pill: <>>,
bowl: <>>,
phone: <>>,
whatsapp: <>>,
pin: <>>,
clock: <>>,
mail: <>>,
arrow: <>>,
arrowLeft: <>>,
check: <>>,
star: <>>,
paw: <>>,
menu: <>>,
close: <>>,
globe: <>>,
heart: <>>,
chevron: <>>,
sparkles: <>>,
};
return ;
};
// ============== LOGO (clean SVG redraw — original mark) ==============
const PetzoneLogo = ({ size = 36, mono = false }) => {
const c = mono ? "currentColor" : "var(--teal)";
return (
Petzone
Veterinary · Dubai
);
};
// ============== NAV ==============
const Nav = ({ page, go, openBook }) => {
const [scrolled, setScrolled] = useState(false);
const [open, setOpen] = useState(false);
const [servicesOpen, setServicesOpen] = useState(false);
useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 8);
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, []);
const link = (key, label) => (
);
return (
{open && (
{[["home","Home"],["services","Services"],["vets","Our vets"],["about","About"],["contact","Contact"]].map(([k,l]) => (
))}
)}
);
};
// ============== FOOTER ==============
const Footer = ({ go, openBook }) => {
const c = window.PZ_DATA.clinic;
return (
);
};
// ============== MOBILE BOTTOM BAR ==============
const MobileBar = ({ openBook }) => (
);
// ============== BOOK SHEET (multi-step) ==============
const BookSheet = ({ open, onClose, prefill }) => {
const [step, setStep] = useState(1);
const [form, setForm] = useState({
petType: "Dog",
petName: "",
service: prefill?.service || "Consultation & Wellness",
ownerName: "",
phone: "",
email: "",
date: "",
time: "",
notes: "",
});
useEffect(() => {
if (open) { setStep(1); setForm(f => ({ ...f, service: prefill?.service || f.service })); }
}, [open, prefill]);
if (!open) return null;
const update = (k, v) => setForm(f => ({ ...f, [k]: v }));
const canNext1 = !!form.petType && !!form.service;
const canNext2 = !!form.ownerName && !!form.phone;
const submitted = step === 4;
return (
{submitted ? "We've got it" : "Book an appointment"}
{!submitted &&
Step {step} of 3 · about 60 seconds
}
{!submitted && (
)}
{step === 1 && (
{["Dog","Cat","Bird","Small mammal"].map(t => (
))}
update("petName", e.target.value)} />
)}
{step === 2 && (
)}
{step === 3 && (
Summary
{form.petName || form.petType} · {form.service}
{form.ownerName} · {form.phone}{form.date && <> · {form.date}{form.time && <> ({form.time})>}>}
)}
{step === 4 && (
Thanks{form.ownerName ? `, ${form.ownerName.split(" ")[0]}` : ""}.
We'll call {form.phone || "you"} within one working hour to confirm your slot. Need us sooner? Tap the WhatsApp or call buttons below.
)}
{!submitted && (
)}
);
};
// ============== EYEBROW / SECTION HEAD ==============
const Eyebrow = ({ children }) => (
{children}
);
const SectionHead = ({ eyebrow, title, lede, align = "left" }) => (
{eyebrow &&
{eyebrow}
}
{title}
{lede &&
{lede}
}
);
// ============== EXPORTS ==============
Object.assign(window, { Icon, PetzoneLogo, Nav, Footer, MobileBar, BookSheet, Eyebrow, SectionHead });