feat: implement booking cancellation feature in HomePage
This commit is contained in:
@@ -129,6 +129,7 @@ export function HomePage() {
|
||||
const [selectedStartTime, setSelectedStartTime] = useState<string>('');
|
||||
const [isManualBookingOpen, setIsManualBookingOpen] = useState(false);
|
||||
const [urlCopied, setUrlCopied] = useState(false);
|
||||
const [bookingToCancel, setBookingToCancel] = useState<AdminBooking | null>(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() {
|
||||
</section>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
{bookingToCancel && (
|
||||
<ResponsiveDialog
|
||||
open={Boolean(bookingToCancel)}
|
||||
onOpenChange={() => setBookingToCancel(null)}
|
||||
>
|
||||
<ResponsiveDialogContent>
|
||||
<ResponsiveDialogHeader>
|
||||
<ResponsiveDialogTitle>Cancelar reserva</ResponsiveDialogTitle>
|
||||
<ResponsiveDialogDescription>
|
||||
¿Estás seguro de que quieres cancelar esta reserva? Esta acción no se puede
|
||||
deshacer.
|
||||
</ResponsiveDialogDescription>
|
||||
</ResponsiveDialogHeader>
|
||||
<div className="mt-4 rounded-2xl border border-border/70 bg-background p-4">
|
||||
<p className="font-medium">
|
||||
{bookingToCancel.startTime} - {bookingToCancel.endTime} ·{' '}
|
||||
{bookingToCancel.courtName}
|
||||
</p>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
{bookingToCancel.customerName} ({bookingToCancel.customerPhone})
|
||||
</p>
|
||||
</div>
|
||||
<ResponsiveDialogFooter>
|
||||
<ResponsiveDialogClose asChild>
|
||||
<Button variant="outline" disabled={updateStatusMutation.isPending}>
|
||||
Mantener
|
||||
</Button>
|
||||
</ResponsiveDialogClose>
|
||||
<Button
|
||||
variant="destructive"
|
||||
onClick={confirmCancelBooking}
|
||||
disabled={updateStatusMutation.isPending}
|
||||
>
|
||||
{updateStatusMutation.isPending ? 'Cancelando...' : 'Sí, cancelar reserva'}
|
||||
</Button>
|
||||
</ResponsiveDialogFooter>
|
||||
</ResponsiveDialogContent>
|
||||
</ResponsiveDialog>
|
||||
)}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -142,7 +142,6 @@ export function RootLayout() {
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
<ThemeSwitcher />
|
||||
|
||||
{!isAuthenticated && (
|
||||
|
||||
@@ -93,7 +93,7 @@ export function PublicBookingConfirmationPage({
|
||||
{confirmationQuery.data.price > 0 && (
|
||||
<>
|
||||
<p className="mt-4 text-sm text-muted-foreground">Precio</p>
|
||||
<p className="mt-1 text-base font-medium sm:text-lg">
|
||||
<p className="mt-1 text-xl font-bold sm:text-2xl">
|
||||
${confirmationQuery.data.price.toLocaleString('es-AR')}
|
||||
</p>
|
||||
</>
|
||||
|
||||
@@ -737,7 +737,7 @@ export function PublicBookingPage({ complexSlug }: PublicBookingPageProps) {
|
||||
<p className="text-xs uppercase tracking-[0.24em] text-muted-foreground">
|
||||
Precio
|
||||
</p>
|
||||
<p className="mt-1 text-sm font-medium text-foreground">
|
||||
<p className="mt-1 text-base font-bold text-foreground">
|
||||
${selectedSlot.price.min.toLocaleString('es-AR')}
|
||||
{selectedSlot.price.min !== selectedSlot.price.max &&
|
||||
` - $${selectedSlot.price.max.toLocaleString('es-AR')}`}
|
||||
|
||||
Reference in New Issue
Block a user