diff --git a/web/src/pages/Booking.tsx b/web/src/pages/Booking.tsx index bda3253..1afcefe 100644 --- a/web/src/pages/Booking.tsx +++ b/web/src/pages/Booking.tsx @@ -29,16 +29,24 @@ export default function Booking() { const [barberId, setBarber] = useState(''); const [date, setDate] = useState(''); const [slot, setSlot] = useState(''); + const [step, setStep] = useState(searchParams.get('service') ? 2 : 1); // Sincroniza o serviceId se o parâmetro mudar (ex: navegação interna) useEffect(() => { const s = searchParams.get('service'); - if (s) setService(s); + if (s) { + setService(s); + setStep(2); + } }, [searchParams]); const selectedService = shop?.services.find((s) => s.id === serviceId); const selectedBarber = shop?.barbers.find((b) => b.id === barberId); + // Avanço automático por efeito colateral (opcional, mas vamos fazer por clique para ser mais explícito) + const nextStep = () => setStep((s) => Math.min(s + 1, 4)); + const prevStep = () => setStep((s) => Math.max(s - 1, 1)); + /** * Função para gerar horários padrão se não houver horários específicos predefinidos * pelo barbeiro na Base de Dados. @@ -111,173 +119,234 @@ export default function Booking() { }; const steps = [ - { id: 1, label: 'Serviço', icon: Scissors, completed: !!serviceId }, - { id: 2, label: 'Barbeiro', icon: User, completed: !!barberId }, - { id: 3, label: 'Data', icon: Calendar, completed: !!date }, - { id: 4, label: 'Horário', icon: Clock, completed: !!slot }, + { id: 1, label: 'Serviço', icon: Scissors, completed: !!serviceId, active: step === 1 }, + { id: 2, label: 'Barbeiro', icon: User, completed: !!barberId, active: step === 2 }, + { id: 3, label: 'Data', icon: Calendar, completed: !!date, active: step === 3 }, + { id: 4, label: 'Horário', icon: Clock, completed: !!slot, active: step === 4 }, ]; return (
-
-

Agendar em {shop.name}

-

{shop.address}

+
+
+

Agendar em {shop.name}

+

{shop.address}

+
+ {step > 1 && ( + + )}
{/* Progress Steps */} -
- {steps.map((step, idx) => ( -
+
+ {steps.map((s, idx) => ( +
-
{ + if (s.completed || s.id < step) setStep(s.id); + }} + disabled={!s.completed && s.id > step} + className={`w-10 h-10 rounded-full flex items-center justify-center border-2 transition-all ${s.active + ? 'bg-amber-600 border-amber-600 text-white shadow-lg ring-4 ring-amber-100' + : s.completed + ? 'bg-amber-500 border-amber-500 text-white' + : 'bg-white border-slate-200 text-slate-400' }`} > - {step.completed ? : } -
- - {step.label} + {s.completed && !s.active ? : } + + + {s.label}
{idx < steps.length - 1 && ( -
+
)}
))}
- - {/* Step 1: Service */} -
-
- -

1. Escolha o serviço

-
-
- {shop.services.map((s) => ( - - ))} -
-
- - {/* Step 2: Barber */} -
-
- -

2. Escolha o barbeiro

-
-
- {shop.barbers.map((b) => ( - - ))} -
-
- - {/* Step 3 & 4: Date & Time */} -
-
-
- -

3. Escolha a data

+ + {/* Step Info Summary (Show what was already selected) */} + {step > 1 && selectedService && ( +
+
+
+ +
+
+

Serviço Selecionado

+

{selectedService.name}

+
- setDate(e.target.value)} - min={new Date().toISOString().split('T')[0]} - /> -
-
-
- -

4. Escolha o horário

-
-
- {!barberId || !date ? ( -

Escolha primeiro o barbeiro e a data.

- ) : availableSlots.length > 0 ? ( - availableSlots.map((h) => ( - - )) - ) : ( -

Nenhum horário disponível para esta data.

- )} -
-
-
- - {/* Summary */} - {canSubmit && selectedService && ( -
-

Resumo do agendamento

-
-
- Serviço: - {selectedService.name} -
-
- Barbeiro: - {selectedBarber?.name} -
-
- Data e hora: - - {new Date(date).toLocaleDateString('pt-BR')} às {slot} - -
-
- Total: - {currency(selectedService.price)} -
+
+

{currency(selectedService.price)}

)} - + {step > 2 && selectedBarber && ( +
+
+ +
+
+

Barbeiro

+

{selectedBarber.name}

+
+
+ )} + + {/* Dynamic Step Content */} +
+ {step === 1 && ( +
+
+
1
+

Escolha o serviço

+
+
+ {shop.services.map((s) => ( + + ))} +
+
+ )} + + {step === 2 && ( +
+
+
2
+

Escolha o barbeiro

+
+
+ {shop.barbers.map((b) => ( + + ))} +
+
+ )} + + {step === 3 && ( +
+
+
3
+

Escolha a data

+
+
+ { + setDate(e.target.value); + if (e.target.value) setStep(4); + }} + min={new Date().toISOString().split('T')[0]} + className="text-lg py-6" + /> +
+
+ )} + + {step === 4 && ( +
+
+
4
+

Escolha o horário

+
+ +
+
+ + {new Date(date).toLocaleDateString('pt-PT', { day: 'numeric', month: 'long', year: 'numeric' })} +
+ +
+ +
+ {availableSlots.length > 0 ? ( + availableSlots.map((h) => ( + + )) + ) : ( +
+

Infelizmente não há horários livres para este dia.

+
+ )} +
+ + {/* Final Summary & Confirmation */} + {canSubmit && ( +
+
+
+

Total a pagar

+

{currency(selectedService?.price || 0)}

+
+ +
+
+ )} +
+ )} +
); } - - - - -