From a6101b3da98838f673805ec71a67d27361822378 Mon Sep 17 00:00:00 2001
From: Husni Abad <67166177+husniabad@users.noreply.github.com>
Date: Wed, 3 Sep 2025 15:59:07 +0300
Subject: [PATCH] fix: Disable cancel button for past bookings (#22667)
* fix: Remove cancel button for past bookings
* fix types and few improvements
* add proper tests for backend changes
* chore
* Update [bookingUid].tsx
* Update bookings-single-view.tsx
* remove comment
* Update tests
---------
Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
---
.../components/booking/bookingActions.test.ts | 28 ++++++++
apps/web/components/booking/bookingActions.ts | 2 +-
.../bookings/views/bookings-single-view.tsx | 4 +-
apps/web/playwright/booking-pages.e2e.ts | 28 ++++++++
.../bookings/lib/handleCancelBooking.ts | 7 ++
.../test/handleCancelBooking.test.ts | 69 +++++++++++++++++++
6 files changed, 135 insertions(+), 3 deletions(-)
diff --git a/apps/web/components/booking/bookingActions.test.ts b/apps/web/components/booking/bookingActions.test.ts
index 14981596e7..a0ee856bc2 100644
--- a/apps/web/components/booking/bookingActions.test.ts
+++ b/apps/web/components/booking/bookingActions.test.ts
@@ -475,6 +475,34 @@ describe("Booking Actions", () => {
expect(isActionDisabled("cancel", context)).toBe(true);
});
+ it("should disable cancelling all past bookings", () => {
+ const pastConfirmedContext = createMockContext({
+ isBookingInPast: true,
+ isPending: false,
+ isConfirmed: true,
+ });
+
+ const pastPendingContext = createMockContext({
+ isBookingInPast: true,
+ isPending: true,
+ isConfirmed: false,
+ });
+
+ // Current implementation blocks ALL past bookings
+ expect(isActionDisabled("cancel", pastConfirmedContext)).toBe(true);
+ expect(isActionDisabled("cancel", pastPendingContext)).toBe(true);
+ });
+
+ it("should allow cancelling future bookings when cancelling is not disabled", () => {
+ const futureContext = createMockContext({
+ isBookingInPast: false,
+ isPending: true,
+ isConfirmed: false,
+ });
+
+ expect(isActionDisabled("cancel", futureContext)).toBe(false);
+ });
+
it("should disable video actions for non-past bookings", () => {
const context = createMockContext({ isBookingInPast: false });
diff --git a/apps/web/components/booking/bookingActions.ts b/apps/web/components/booking/bookingActions.ts
index f28647c17d..cdc6982717 100644
--- a/apps/web/components/booking/bookingActions.ts
+++ b/apps/web/components/booking/bookingActions.ts
@@ -210,7 +210,7 @@ export function isActionDisabled(actionId: string, context: BookingActionContext
case "reschedule_request":
return (isBookingInPast && !booking.eventType.allowReschedulingPastBookings) || isDisabledRescheduling;
case "cancel":
- return isDisabledCancelling || (isBookingInPast && isPending && !isConfirmed);
+ return isDisabledCancelling || isBookingInPast;
case "view_recordings":
return !(isBookingInPast && booking.status === BookingStatus.ACCEPTED && context.isCalVideoLocation);
case "meeting_session_details":
diff --git a/apps/web/modules/bookings/views/bookings-single-view.tsx b/apps/web/modules/bookings/views/bookings-single-view.tsx
index 4f55f9e2a9..573a786c16 100644
--- a/apps/web/modules/bookings/views/bookings-single-view.tsx
+++ b/apps/web/modules/bookings/views/bookings-single-view.tsx
@@ -839,13 +839,13 @@ export default function Success(props: PageProps) {
{t("reschedule")}
- {canCancelAndReschedule && (
+ {!isBookingInPast && canCancel && (
{t("or_lowercase")}
)}
)}
- {canCancel && (
+ {!isBookingInPast && canCancel && (