From 3e314a9b9a047a930795194cf31b914d1ce03219 Mon Sep 17 00:00:00 2001 From: Jose Selesan Date: Tue, 2 Jun 2026 16:26:47 -0300 Subject: [PATCH] feat(public-booking): refactor court selection and available slots components for improved usability --- .../public-booking/public-booking-page.tsx | 162 +++++++++++++----- 1 file changed, 115 insertions(+), 47 deletions(-) diff --git a/apps/frontend/src/features/public-booking/public-booking-page.tsx b/apps/frontend/src/features/public-booking/public-booking-page.tsx index db49798..8ff7e62 100644 --- a/apps/frontend/src/features/public-booking/public-booking-page.tsx +++ b/apps/frontend/src/features/public-booking/public-booking-page.tsx @@ -2,13 +2,6 @@ import PlayzerIcon from '@/assets/playzer-favicon-512-transparent.png'; import { Button } from '@/components/ui/button'; import { Field, FieldError, FieldLabel } from '@/components/ui/field'; import { Input } from '@/components/ui/input'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@/components/ui/select'; import { Stepper, StepperIndicator, @@ -716,15 +709,10 @@ function PublicBookingMobile(props: BookingShellProps) { /> )} {props.courts.length > 0 ? ( - ({ - value: court.courtId, - label: court.courtName, - }))} + ) : ( !props.isLoading && ( @@ -772,16 +760,12 @@ function PublicBookingMobile(props: BookingShellProps) {
-
- -
-
- +
@@ -890,34 +874,118 @@ function MobileSportSelector({ ); } -function MobileSelect({ - label, - value, - placeholder, - options, - onValueChange, +function MobileCourtPicker({ + courts, + selectedCourtId, + onSelectCourt, }: { - label: string; - value: string; - placeholder: string; - options: { value: string; label: string }[]; - onValueChange: (value: string) => void; + courts: PublicAvailabilityCourt[]; + selectedCourtId?: string; + onSelectCourt: (courtId: string) => void; }) { return ( -
- {label} - +
+
+ {courts.map((court) => { + const isSelected = selectedCourtId === court.courtId; + + return ( + + ); + })} +
+
+ ); +} + +function MobileAvailableSlots({ + court, + selectedSlot, + onSelectSlot, +}: { + court: PublicAvailabilityCourt; + selectedSlot: SelectedSlot | null; + onSelectSlot: (slot: SelectedSlot) => void; +}) { + const slots = court.availableSlots; + + return ( +
+
+
+

Horarios disponibles

+

+ Turnos de {court.slotDurationMinutes} minutos +

+
+ + {slots.length} {slots.length === 1 ? 'turno' : 'turnos'} + +
+ + {slots.length > 0 ? ( +
+ {slots.map((slot) => { + const selected = isSlotSelected(slot, court.courtId, selectedSlot); + + return ( + + ); + })} +
+ ) : ( +

+ No hay horarios disponibles para esta cancha. +

+ )}
); }