import { useState, useEffect } from 'preact/hooks'; import { fetchDoctors, fetchSlots, submitBooking } from './api'; import type { Doctor, TimeSlot } from './types'; type Step = 'department' | 'doctor' | 'datetime' | 'details' | 'success'; export const Booking = () => { const [step, setStep] = useState('department'); const [doctors, setDoctors] = useState([]); const [departments, setDepartments] = useState([]); const [selectedDept, setSelectedDept] = useState(''); const [selectedDoctor, setSelectedDoctor] = useState(null); const [selectedDate, setSelectedDate] = useState(''); const [slots, setSlots] = useState([]); const [selectedSlot, setSelectedSlot] = useState(''); const [name, setName] = useState(''); const [phone, setPhone] = useState(''); const [complaint, setComplaint] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const [reference, setReference] = useState(''); useEffect(() => { fetchDoctors().then(docs => { setDoctors(docs); setDepartments([...new Set(docs.map(d => d.department).filter(Boolean))]); }).catch(() => setError('Failed to load doctors')); }, []); const filteredDoctors = selectedDept ? doctors.filter(d => d.department === selectedDept) : []; const handleDoctorSelect = (doc: Doctor) => { setSelectedDoctor(doc); setSelectedDate(new Date().toISOString().split('T')[0]); setStep('datetime'); }; useEffect(() => { if (selectedDoctor && selectedDate) { fetchSlots(selectedDoctor.id, selectedDate).then(setSlots).catch(() => {}); } }, [selectedDoctor, selectedDate]); const handleBook = async () => { if (!selectedDoctor || !selectedSlot || !name || !phone) return; setLoading(true); setError(''); try { const scheduledAt = `${selectedDate}T${selectedSlot}:00`; const result = await submitBooking({ departmentId: selectedDept, doctorId: selectedDoctor.id, scheduledAt, patientName: name, patientPhone: phone, chiefComplaint: complaint, captchaToken: 'dev-bypass', }); setReference(result.reference); setStep('success'); } catch { setError('Booking failed. Please try again.'); } finally { setLoading(false); } }; const stepIndex = { department: 0, doctor: 1, datetime: 2, details: 3, success: 4 }; const currentStep = stepIndex[step]; return (
{step !== 'success' && (
{[0, 1, 2, 3].map(i => (
))}
)} {error &&
{error}
} {step === 'department' && (
Select Department
{departments.map(dept => ( ))}
)} {step === 'doctor' && (
Select Doctor — {selectedDept.replace(/_/g, ' ')}
{filteredDoctors.map(doc => ( ))}
)} {step === 'datetime' && (
{selectedDoctor?.name} — Pick Date & Time
{ setSelectedDate(e.target.value); setSelectedSlot(''); }} />
{slots.length > 0 && (
{slots.map(s => ( ))}
)}
)} {step === 'details' && (
Your Details
setName(e.target.value)} />
setPhone(e.target.value)} />