// Booking flow — multi-step, full state, validation, animated transitions const { useState: useStateB, useMemo: useMemoB, useEffect: useEffectB } = React; const EXPERTS = [ { id: "sevgi", name: "Sevgi Taşan", role: "Kurucu · Cilt Bakımı & Kalıcı Makyaj", years: 12 }, { id: "elif", name: "Elif Yılmaz", role: "Medikal Estetisyen", years: 8 }, { id: "duru", name: "Duru Aksoy", role: "Lash & Brow Uzmanı", years: 6 }, { id: "naz", name: "Naz Kaya", role: "Makyaj & Saç Stilisti", years: 5 }, ]; const TIME_SLOTS = ["10:00","10:30","11:00","11:30","12:00","13:00","13:30","14:00","14:30","15:00","15:30","16:00","16:30","17:00","17:30","18:00"]; function TR_MONTHS() { return ["Ocak","Şubat","Mart","Nisan","Mayıs","Haziran","Temmuz","Ağustos","Eylül","Ekim","Kasım","Aralık"]; } function TR_DAYS() { return ["Pzt","Sal","Çar","Per","Cum","Cmt","Paz"]; } function StepDots({ step, total }) { return (
{Array.from({ length: total }).map((_, i) => (
{String(i+1).padStart(2,'0')} {["Hizmet","Uzman","Tarih","Saat","Bilgiler","Onay"][i]}
))}
); } function Calendar({ value, onChange }) { const today = new Date(); today.setHours(0,0,0,0); const [view, setView] = useStateB(() => ({ y: today.getFullYear(), m: today.getMonth() })); const months = TR_MONTHS(); const first = new Date(view.y, view.m, 1); const startDay = (first.getDay() + 6) % 7; // Mon=0 const daysInMonth = new Date(view.y, view.m+1, 0).getDate(); const cells = []; for (let i=0;i { let m = view.m + delta, y = view.y; if (m < 0) { m = 11; y -= 1; } if (m > 11) { m = 0; y += 1; } setView({ y, m }); }; return (
{months[view.m]} {view.y}
{TR_DAYS().map(d =>
{d}
)} {cells.map((d, i) => { if (!d) return
; const past = d < today; const isSel = value && d.toDateString() === value.toDateString(); const isWeekend = d.getDay() === 0; return ( ); })}
Müsait Seçili Kapalı
); } function BookingSection() { const [step, setStep] = useStateB(1); const [data, setData] = useStateB({ service: null, expert: null, date: null, time: null, name: "", phone: "", email: "", note: "", }); const [errors, setErrors] = useStateB({}); const [done, setDone] = useStateB(false); const update = (k, v) => setData(d => ({ ...d, [k]: v })); const canNext = useMemoB(() => { if (step === 1) return !!data.service; if (step === 2) return !!data.expert; if (step === 3) return !!data.date; if (step === 4) return !!data.time; if (step === 5) { const e = {}; if (!data.name || data.name.trim().length < 2) e.name = "Lütfen ad soyad girin."; if (!data.phone || data.phone.replace(/\D/g,'').length < 10) e.phone = "Geçerli bir telefon numarası girin."; if (data.email && !/^\S+@\S+\.\S+$/.test(data.email)) e.email = "Geçerli bir e-posta girin."; return Object.keys(e).length === 0; } return true; }, [step, data]); const next = () => { if (step === 5) { const e = {}; if (!data.name || data.name.trim().length < 2) e.name = "Lütfen ad soyad girin."; if (!data.phone || data.phone.replace(/\D/g,'').length < 10) e.phone = "Geçerli bir telefon numarası girin."; if (data.email && !/^\S+@\S+\.\S+$/.test(data.email)) e.email = "Geçerli bir e-posta girin."; setErrors(e); if (Object.keys(e).length) return; } if (step < 6) setStep(step + 1); else { setDone(true); } }; const prev = () => step > 1 && setStep(step - 1); const fmtDate = (d) => d ? `${String(d.getDate()).padStart(2,'0')} ${TR_MONTHS()[d.getMonth()]} ${d.getFullYear()}` : '—'; return (
— Online Randevu

Hemen randevu
oluşturun

Altı kısa adımda, atelyemizdeki yerinizi ayırtın. Ekibimiz randevunuzu en kısa sürede onaylayacaktır.
{!done && } {done ? (

Randevu talebiniz alındı.

Randevu talebiniz başarıyla alınmıştır. Ekibimiz en kısa sürede sizinle iletişime geçecektir.

REF · STBS-{Math.floor(100000 + Math.random()*899999)}
Bize Ulaşın
) : (
{step === 1 && (
{SERVICES.map(s => ( ))}
)} {step === 2 && (
{EXPERTS.map(e => ( ))}
)} {step === 3 && (
update('date', d)} />
)} {step === 4 && (
{TIME_SLOTS.map(t => ( ))}
)} {step === 5 && (
update('name', e.target.value)} placeholder="Örn. Ayşe Yılmaz" /> {errors.name && {errors.name}}
update('phone', e.target.value)} placeholder="+90 5__ ___ __ __" /> {errors.phone && {errors.phone}}
update('email', e.target.value)} placeholder="ornek@eposta.com" /> {errors.email && {errors.email}}