From d6e32f3e84b18249884da5a357c567b7e118cebd Mon Sep 17 00:00:00 2001 From: Jose Selesan Date: Fri, 24 Apr 2026 15:44:46 -0300 Subject: [PATCH] feat: implement booking cancellation feature in HomePage --- .../20260424183828_add_price/migration.sql | 2 + apps/frontend/src/features/home/home-page.tsx | 59 +++++++++++++++++-- .../src/features/layout/root-layout.tsx | 1 - .../public-booking-confirmation-page.tsx | 2 +- .../public-booking/public-booking-page.tsx | 2 +- 5 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 apps/backend/prisma/migrations/20260424183828_add_price/migration.sql diff --git a/apps/backend/prisma/migrations/20260424183828_add_price/migration.sql b/apps/backend/prisma/migrations/20260424183828_add_price/migration.sql new file mode 100644 index 0000000..97d83af --- /dev/null +++ b/apps/backend/prisma/migrations/20260424183828_add_price/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "court_bookings" ADD COLUMN "price" DECIMAL(19,2); diff --git a/apps/frontend/src/features/home/home-page.tsx b/apps/frontend/src/features/home/home-page.tsx index 17b7e6e..7e3cb16 100644 --- a/apps/frontend/src/features/home/home-page.tsx +++ b/apps/frontend/src/features/home/home-page.tsx @@ -129,6 +129,7 @@ export function HomePage() { const [selectedStartTime, setSelectedStartTime] = useState(''); const [isManualBookingOpen, setIsManualBookingOpen] = useState(false); const [urlCopied, setUrlCopied] = useState(false); + const [bookingToCancel, setBookingToCancel] = useState(null); const currentComplexQuery = useQuery({ queryKey: ['current-complex'], @@ -361,6 +362,7 @@ export function HomePage() { mutationFn: (payload: { bookingId: string; status: 'CANCELLED' | 'COMPLETED' }) => apiClient.adminBookings.updateStatus(payload.bookingId, { status: payload.status }), onSuccess: () => { + setBookingToCancel(null); void queryClient.invalidateQueries({ queryKey: ['admin-bookings', selectedComplex?.id] }); void queryClient.invalidateQueries({ queryKey: ['manual-booking-availability', selectedComplex?.complexSlug], @@ -368,6 +370,18 @@ export function HomePage() { }, }); + function handleCancelBooking(booking: AdminBooking) { + setBookingToCancel(booking); + } + + function confirmCancelBooking() { + if (!bookingToCancel) return; + updateStatusMutation.mutate({ + bookingId: bookingToCancel.id, + status: 'CANCELLED', + }); + } + const { register, handleSubmit, @@ -817,10 +831,7 @@ export function HomePage() { variant="destructive" disabled={isMutating} onClick={() => { - updateStatusMutation.mutate({ - bookingId: booking.id, - status: 'CANCELLED', - }); + handleCancelBooking(booking); }} > Cancelar @@ -874,6 +885,46 @@ export function HomePage() { + + {bookingToCancel && ( + setBookingToCancel(null)} + > + + + Cancelar reserva + + ¿Estás seguro de que quieres cancelar esta reserva? Esta acción no se puede + deshacer. + + +
+

+ {bookingToCancel.startTime} - {bookingToCancel.endTime} ·{' '} + {bookingToCancel.courtName} +

+

+ {bookingToCancel.customerName} ({bookingToCancel.customerPhone}) +

+
+ + + + + + +
+
+ )} ); } diff --git a/apps/frontend/src/features/layout/root-layout.tsx b/apps/frontend/src/features/layout/root-layout.tsx index 23513e1..31945fe 100644 --- a/apps/frontend/src/features/layout/root-layout.tsx +++ b/apps/frontend/src/features/layout/root-layout.tsx @@ -142,7 +142,6 @@ export function RootLayout() {
- {!isAuthenticated && ( diff --git a/apps/frontend/src/features/public-booking/public-booking-confirmation-page.tsx b/apps/frontend/src/features/public-booking/public-booking-confirmation-page.tsx index e6c643c..f71b50c 100644 --- a/apps/frontend/src/features/public-booking/public-booking-confirmation-page.tsx +++ b/apps/frontend/src/features/public-booking/public-booking-confirmation-page.tsx @@ -93,7 +93,7 @@ export function PublicBookingConfirmationPage({ {confirmationQuery.data.price > 0 && ( <>

Precio

-

+

${confirmationQuery.data.price.toLocaleString('es-AR')}

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 b327b6a..53830cb 100644 --- a/apps/frontend/src/features/public-booking/public-booking-page.tsx +++ b/apps/frontend/src/features/public-booking/public-booking-page.tsx @@ -737,7 +737,7 @@ export function PublicBookingPage({ complexSlug }: PublicBookingPageProps) {

Precio

-

+

${selectedSlot.price.min.toLocaleString('es-AR')} {selectedSlot.price.min !== selectedSlot.price.max && ` - $${selectedSlot.price.max.toLocaleString('es-AR')}`}