// 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 && (
)}
{step === 6 && (
Hizmet{data.service?.name}
Uzman{data.expert?.name}
Tarih{fmtDate(data.date)}
Saat{data.time}
Ad Soyad{data.name}
Telefon{data.phone}
{data.email &&
E-posta{data.email}
}
{data.note &&
Not"{data.note}"
}
)}
)}
{!done && (
Adım {step} / 6
)}
Randevu Özeti
Hizmet{data.service?.name || '—'}
Uzman{data.expert?.name || '—'}
Tarih{fmtDate(data.date)}
Saat{data.time || '—'}
Tutar{data.service ? `${data.service.from}'den itibaren` : '—'}
WhatsApp'tan Hızlı Randevu
+90 535 469 19 08
İptal & Değişiklik
Randevunuzu en geç 24 saat öncesinden iptal edebilir veya yeniden planlayabilirsiniz.
);
}
window.BookingSection = BookingSection;