/* global React */ // ============================================================ // BOOKING — multi-step form (treatment → date/time → details → confirm) // ============================================================ const BookPage = ({ initialTreatment }) => { const [step, setStep] = React.useState(0); const [data, setData] = React.useState({ treatment: initialTreatment || "", practitioner: "any", date: "", time: "", name: "", phone: "", email: "", notes: "", consent: false, channel: "form", }); const [errors, setErrors] = React.useState({}); const [confetti, setConfetti] = React.useState(false); const [reference, setReference] = React.useState(""); const setField = (k, v) => { setData(d => ({ ...d, [k]: v })); setErrors(e => ({ ...e, [k]: undefined })); }; const steps = [ { label: "Treatment", short: "01" }, { label: "Date & time", short: "02" }, { label: "Your details", short: "03" }, { label: "Confirm", short: "04" }, ]; const validate = (s) => { const e = {}; if (s === 0) { if (!data.treatment) e.treatment = "Choose a treatment, or “Not sure yet”."; } if (s === 1) { if (!data.date) e.date = "Pick a date."; if (!data.time) e.time = "Pick a time."; } if (s === 2) { if (!data.name.trim()) e.name = "Full name please."; if (!/^[+\d\s]{8,}$/.test(data.phone)) e.phone = "A reachable number, please."; if (data.email && !/^\S+@\S+\.\S+$/.test(data.email)) e.email = "That email doesn't look right."; if (!data.consent) e.consent = "We need your consent to contact you."; } setErrors(e); return Object.keys(e).length === 0; }; const next = () => { if (!validate(step)) return; if (step === steps.length - 1) { // Submit const ref = "CC-" + Math.random().toString(36).slice(2, 7).toUpperCase(); setReference(ref); setConfetti(true); setStep(step + 1); window.scrollTo({ top: 0, behavior: "smooth" }); return; } setStep(step + 1); }; const back = () => setStep(Math.max(0, step - 1)); // Date options: next 14 days const dateOptions = React.useMemo(() => { const out = []; const now = new Date(); for (let i = 1; i <= 14; i++) { const d = new Date(now); d.setDate(now.getDate() + i); out.push({ value: d.toISOString().slice(0, 10), day: d.toLocaleDateString("en-GB", { weekday: "short" }), dd: d.toLocaleDateString("en-GB", { day: "2-digit" }), mon: d.toLocaleDateString("en-GB", { month: "short" }), sunday: d.getDay() === 0, }); } return out; }, []); const times = ["10:00", "11:00", "12:00", "14:00", "15:00", "16:00", "17:00", "18:00", "19:00", "20:00"]; const treatmentOptions = [ { value: "", label: "Not sure yet — recommend for me" }, ...window.TREATMENTS.map(t => ({ value: t.slug, label: t.title })), ]; const treatmentLabel = treatmentOptions.find(t => t.value === data.treatment)?.label || "Not sure yet"; // Final success screen if (step === steps.length) { return (
{confetti && }

Consultation requested.

Thank you, {data.name.split(" ")[0]}. We'll WhatsApp you on {data.phone} within the next clinic hour to confirm your slot.

Your reference {reference}
Back to home Continue on WhatsApp
); } return (
Book a consultation

Free 15-minute consultation.

No payment now. We'll confirm your slot by WhatsApp.

{/* Stepper */}
{steps.map((s, i) => { const active = i === step; const done = i < step; return (
{done ? : s.short} {s.label}
); })}
{step === 0 && ( )} {step === 1 && ( )} {step === 2 && ( )} {step === 3 && ( )}
{/* Side option */}
Prefer not to fill a form? Book by WhatsApp · Call +971 58 195 5350
); }; // ============================================================ // Step 1: treatment // ============================================================ const StepTreatment = ({ data, setField, errors, options }) => (

What brings you in?

Choose a treatment category, or pick "Not sure yet" and we'll match you with the right doctor.

{options.map(opt => { const selected = data.treatment === opt.value; return ( ); })}

Preferred practitioner

{[{ value: "any", label: "First available" }, ...window.PRACTITIONERS.map(p => ({ value: p.name, label: p.name }))].map(p => { const selected = data.practitioner === p.value; return ( ); })}
); // ============================================================ // Step 2: date & time // ============================================================ const StepDate = ({ data, setField, errors, dateOptions, times }) => (

When works for you?

Pick a date and a rough time — we'll confirm an exact slot when we WhatsApp you back.

Date

{dateOptions.map(d => { const selected = data.date === d.value; return ( ); })}
{errors.date &&
{errors.date}
}

Time

{times.map(t => { const selected = data.time === t; return ( ); })}
{errors.time &&
{errors.time}
}
); // ============================================================ // Step 3: details // ============================================================ const StepDetails = ({ data, setField, errors }) => (

Your details

Just enough so we can confirm your slot. Nothing else.

setField("name", e.target.value)} placeholder="e.g. Mia De Mansa"/> {errors.name && {errors.name}}
setField("phone", e.target.value)} placeholder="+971 58 ..."/> {errors.phone && {errors.phone}}
setField("email", e.target.value)} placeholder="you@email.com"/> {errors.email && {errors.email}}