/* ============================================================ WorkStay — Booking Flow (multi-step) exports: BookingFlow ============================================================ */ const { useState: useStateBk } = React; const STEPS = ['Dates', 'Work needs', 'Details', 'Confirm']; function BookingFlow({ go, params = {} }) { const { PROPERTIES, OPERATORS } = window.WS_DATA; const p = PROPERTIES.find(x => x.id === params.id) || PROPERTIES[0]; const op = OPERATORS[p.operator]; const [step, setStep] = useStateBk(0); const [months, setMonths] = useStateBk(3); const [needs, setNeeds] = useStateBk(['Wired desk', 'Quiet after 8pm']); const [done, setDone] = useStateBk(false); const total = p.price * months + 240; const next = () => { if (step < 3) setStep(step + 1); else setDone(true); }; const back = () => { if (step > 0) setStep(step - 1); else go('property', { id: p.id }); }; const toggleNeed = n => setNeeds(prev => prev.includes(n) ? prev.filter(x => x !== n) : [...prev, n]); if (done) return ; return (
{/* left: form */}
{/* mobile-only compact summary */}
{p.collection}
{p.name}
{p.city}
Total
${total.toLocaleString()}
{/* progress */}
{STEPS.map((s, i) => (
{i < step ? : i + 1} {s}
{i < STEPS.length - 1 && }
))}
{step === 0 && } {step === 1 && } {step === 2 && } {step === 3 && }
{step === 0 ? 'Back to stay' : 'Back'} {step === 3 ? 'Confirm & reserve' : 'Continue'}
{/* right: cinematic summary rail */}
); } function StepHead({ eyebrow, title }) { return
{eyebrow}

{title}

; } function StepDates({ p, months, setMonths }) { return (
{[['Move in', 'Apr 12, 2026'], ['Move out', `Jul 12, 2026`]].map(([l, v]) => (
{l}
{v}
))}
Duration {months} months
setMonths(+e.target.value)} className="ws-range" style={{ width: '100%' }} />
1 moLong-stay 12 mo
{months >= 3 &&
Long-stay rate applied — 12% off monthly
}
); } function StepNeeds({ needs, toggleNeed }) { const opts = [ { n: 'Wired desk', i: 'desk' }, { n: 'Quiet after 8pm', i: 'quiet' }, { n: 'Video-call room', i: 'video' }, { n: '1 Gbps fiber', i: 'wifi' }, { n: 'Standing desk', i: 'ergo' }, { n: 'Power backup', i: 'power' }, { n: 'Great light', i: 'light' }, { n: 'Espresso bar', i: 'coffee' }, ]; return (

We’ll match the setup and flag anything the Operator should prep before you arrive.

{opts.map(o => { const on = needs.includes(o.n); return ( ); })}
); } function Field({ label, placeholder, span }) { return ( ); } function StepDetails() { return (
Payment
Encrypted · you won’t be charged until the Operator confirms.
); } function StepConfirm({ p, op, months, needs, total }) { return (
Total due at confirmation ${total.toLocaleString()}
); } function SummaryRow({ label, value }) { return (
{label} {value}
); } function BookingConfirmed({ p, op, months, total, go }) { return (

You’re in.

{op.name} is preparing {p.name} for your {months}-month stay. You’ll get a confirmation and workspace checklist by email.

Confirmation
WS-{p.id.slice(0, 3).toUpperCase()}-2026
Total
${total.toLocaleString()}
go('home')}>Back to home go('explore')}>Explore more stays
); } Object.assign(window, { BookingFlow });