/* global React, Reveal, PhiMark, ArchPattern, TREATMENT_DATA */
// =======================================================================
// CONTACT PAGE
// =======================================================================
function ContactPage({ locale, onBook }) {
const ar = locale === 'ar';
return (
φ {ar ? 'تواصل' : 'Contact'}
{ar ? <>إبدأ بمحادثة هادئة .> : <>Begin with a conversation .>}
{[
['Telephone', '+971 4 456 2024', 'tel:+97144562024'],
['WhatsApp', '+971 58 685 8562', 'https://wa.me/971586858562'],
['Email', 'dubai@ouronyx.com', 'mailto:dubai@ouronyx.com'],
['Address', 'Unit C201, The Opus, Business Bay', null],
].map(([k, v, href]) => (
{k}
{href ? (
{v}
) : (
{v}
)}
))}
{/* Inline form */}
{ar ? 'نموذج سريع' : 'Quick enquiry'}
{ar ? <>أو ابعث برسالة قصیرة .> : <>Or send a short message .>}
{ar
? 'لا نطلب أي بیانات طبیة في هذه المرحلة. سنرد خلال یوم عمل واحد لترتیب استشارة مع طبیب.'
: 'We do not ask for medical detail at this stage. We will reply within one working day to arrange a doctor-led consultation.'}
{ar ? 'حجز خطوة بخطوة' : 'Use the guided flow'} →
);
}
function QuickForm({ ar }) {
const [sent, setSent] = React.useState(false);
if (sent) {
return (
{ar ? 'شكراً' : 'Thank you'}
{ar ? 'سنتواصل خلال یوم عمل واحد.' : 'We will reply within one working day.'}
);
}
return (
);
}
// =======================================================================
// BOOKING MODAL — multi-step consultation flow
// =======================================================================
function BookingModal({ open, onClose, locale }) {
const ar = locale === 'ar';
const [step, setStep] = React.useState(0);
const [data, setData] = React.useState({
pillar: null, treatment: null, date: null, time: null, name: '', email: '', phone: '', country: 'United Arab Emirates', notes: '',
});
const [submitting, setSubmitting] = React.useState(false);
const [done, setDone] = React.useState(false);
React.useEffect(() => {
if (!open) {
// reset after close
const t = setTimeout(() => { setStep(0); setDone(false); setData({ pillar: null, treatment: null, date: null, time: null, name: '', email: '', phone: '', country: 'United Arab Emirates', notes: '' }); }, 400);
return () => clearTimeout(t);
}
}, [open]);
const next = () => setStep((s) => Math.min(s + 1, 4));
const back = () => setStep((s) => Math.max(s - 1, 0));
const submit = () => {
setSubmitting(true);
setTimeout(() => { setSubmitting(false); setDone(true); }, 1100);
};
const stepLabels = [
ar ? 'الركيزة' : 'Pillar',
ar ? 'العلاج' : 'Focus',
ar ? 'الوقت' : 'When',
ar ? 'التفاصيل' : 'Details',
ar ? 'التأكيد' : 'Confirm',
];
return (
e.stopPropagation()}>
{/* Left rail — context */}
OURONYX DUBAI · CONSULTATION
{done ? (ar ? 'شكراً.' : <>Thank you .>) : (ar ? <>إبدأ بمحادثة هادئة.> : <>A quiet, doctor-led conversation .>)}
{done
? (ar ? 'سنرد علیك من العیادة خلال یوم عمل واحد.' : 'A member of the Dubai team will be in touch within one working day.')
: (ar ? 'لن نطلب أي معلومات طبیة في هذه المرحلة. سنرد لترتیب موعد مع طبیب.' : 'We won’t ask for any medical detail here. We’ll reach out to arrange a time with one of our doctors.')}
STEP
{done ? '✓' : `0${step + 1}`} / 05
{stepLabels[step]}
{/* Right pane — flow */}
×
{done ? (
) : (
{/* Progress dots */}
{[0,1,2,3,4].map((i) => (
))}
{step === 0 &&
}
{step === 1 &&
}
{step === 2 &&
}
{step === 3 &&
}
{step === 4 &&
}
)}
);
}
// === STEP COMPONENTS ===
function StepPillar({ ar, data, setData, next }) {
const pillars = Object.entries(TREATMENT_DATA);
return (
<>
{ar ? 'مَا الذي تودین التركیز علیه؟' : 'Where would you like to focus?'}
{ar ? 'یمكنك تغییر هذا في الاستشارة.' : 'You can change this in the consultation.'}
{pillars.map(([k, p]) => (
{ setData({ ...data, pillar: k }); setTimeout(next, 250); }} style={{
background: data.pillar === k ? 'var(--ink)' : 'transparent',
color: data.pillar === k ? 'var(--bone)' : 'var(--ink)',
border: '1px solid ' + (data.pillar === k ? 'var(--ink)' : 'var(--line)'),
padding: '20px 22px', textAlign: 'left', cursor: 'pointer',
display: 'flex', justifyContent: 'space-between', alignItems: 'center', transition: 'all 0.25s',
}}>
{ar ? p.nameAr : p.name}
{ar ? p.blurbAr : p.blurb.slice(0, 70) + '…'}
{p.no}
))}
{ setData({ ...data, pillar: 'unsure' }); setTimeout(next, 250); }} style={{
background: data.pillar === 'unsure' ? 'var(--olive)' : 'transparent',
color: data.pillar === 'unsure' ? 'var(--bone)' : 'var(--ink-soft)',
border: '1px solid ' + (data.pillar === 'unsure' ? 'var(--olive)' : 'var(--line)'),
padding: '16px 22px', textAlign: 'left', cursor: 'pointer', fontStyle: 'italic',
fontFamily: 'var(--serif)', fontSize: '1.1rem',
}}>
{ar ? 'لست متأكدة — انصحوني' : 'I’m not sure — please advise'}
>
);
}
function StepFocus({ ar, data, setData, next, back }) {
const opts = data.pillar && data.pillar !== 'unsure' ? TREATMENT_DATA[data.pillar].devices : ['Skin assessment', 'Treatment plan review', 'Hair-loss assessment', 'General consultation'];
return (
<>
{ar ? 'ما الذي تفكرین فیه؟' : 'What did you have in mind?'}
{ar ? 'اختیار واحد — وسیشكل نقطة البدایة لیس أكثر.' : 'Pick one. It only shapes the starting point of the conversation.'}
{opts.map((o) => (
setData({ ...data, treatment: o })} style={{
background: data.treatment === o ? 'var(--olive)' : 'transparent',
color: data.treatment === o ? 'var(--bone)' : 'var(--ink)',
border: '1px solid ' + (data.treatment === o ? 'var(--olive)' : 'var(--line)'),
padding: '14px 18px', textAlign: 'left', cursor: 'pointer', fontSize: '0.92rem',
transition: 'all 0.2s',
}}>{o}
))}
>
);
}
function StepWhen({ ar, data, setData, next, back }) {
// Build calendar for next 21 days
const today = new Date(2026, 4, 25);
const days = Array.from({ length: 21 }, (_, i) => {
const d = new Date(today);
d.setDate(today.getDate() + i);
return d;
});
const times = ['10:00', '11:00', '12:00', '14:00', '15:00', '16:00', '17:00'];
const fmtDay = (d) => d.toLocaleDateString('en-GB', { weekday: 'short' });
const fmtDate = (d) => d.toLocaleDateString('en-GB', { day: '2-digit', month: 'short' });
return (
<>
{ar ? 'متى یناسبك؟' : 'When suits you?'}
{ar ? 'سنؤكد التوقیت — هذه تفضیلاتك فقط.' : 'These are just preferences. We’ll confirm with you.'}
{ar ? 'یوم' : 'Day'}
{days.map((d, i) => {
const key = d.toISOString();
const selected = data.date === key;
return (
setData({ ...data, date: key })} style={{
background: selected ? 'var(--ink)' : 'transparent',
color: selected ? 'var(--bone)' : 'var(--ink)',
border: '1px solid ' + (selected ? 'var(--ink)' : 'var(--line)'),
padding: '12px 14px', cursor: 'pointer', flexShrink: 0,
display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
minWidth: 64,
}}>
{fmtDay(d)}
{fmtDate(d)}
);
})}
{ar ? 'وقت' : 'Time (GST)'}
{times.map((t) => {
const selected = data.time === t;
return (
setData({ ...data, time: t })} style={{
background: selected ? 'var(--olive)' : 'transparent',
color: selected ? 'var(--bone)' : 'var(--ink)',
border: '1px solid ' + (selected ? 'var(--olive)' : 'var(--line)'),
padding: '12px 14px', cursor: 'pointer',
fontFamily: 'var(--serif)', fontSize: '1.05rem', fontStyle: 'italic',
}}>{t}
);
})}
>
);
}
function StepDetails({ ar, data, setData, next, back }) {
const canNext = data.name && data.email && data.phone;
return (
<>
{ar ? 'كیف نتواصل معك؟' : 'How shall we reach you?'}
{ar ? 'لا معلومات طبیة في هذه المرحلة.' : 'No medical detail at this stage.'}
>
);
}
function StepConfirm({ ar, data, submit, back, submitting }) {
const pillarName = data.pillar === 'unsure' ? 'Unsure — advise me' : TREATMENT_DATA[data.pillar]?.name;
const dateStr = data.date ? new Date(data.date).toLocaleDateString('en-GB', { weekday: 'long', day: 'numeric', month: 'long' }) : '';
return (
<>
{ar ? 'مراجعة' : 'A final review.'}
{ar ? 'ستتم تأكید الموعد من قبل العیادة.' : 'The clinic will confirm your appointment by phone or WhatsApp.'}
{[
['Pillar', pillarName],
['Focus', data.treatment],
['Preferred', `${dateStr} · ${data.time}`],
['Name', data.name],
['Contact', `${data.email} · ${data.phone}`],
['Country', data.country],
data.notes ? ['Notes', data.notes] : null,
].filter(Boolean).map(([k, v]) => (
{k}
{v}
))}
{ar
? 'بإرسال هذا النموذج، توافقین على التواصل من فریق العیادة. لا یتم جمع أي بیانات طبیة في هذه المرحلة.'
: 'By submitting, you consent to the clinic contacting you regarding this enquiry. No medical detail has been collected at this stage. This enquiry does not constitute a booking until confirmed by the clinic.'}
{ar ? 'رجوع' : 'Back'}
{submitting ? <> > : (ar ? 'تأكید الطلب' : 'Confirm enquiry')}
>
);
}
function NavButtons({ ar, back, next, canNext }) {
return (
{ar ? 'رجوع' : 'Back'}
{ar ? 'متابعة' : 'Continue'} →
);
}
function DoneState({ ar, data }) {
return (
{ar ? 'تم استلام طلبك.' : <>Your enquiry is in .>}
{ar
? `سنتواصل معك على ${data.email} أو ${data.phone} لتأكید موعدك.`
: <>We’ll reach out at {data.email} or {data.phone} within one working day to confirm.>}
);
}
Object.assign(window, { ContactPage, BookingModal });