feat: Allow cancellation & reschedule on past bookings (#16118)

* option to cancel/reschedule in past bookings

* allows reschedule and cancellation on past bookings

* make headline checks readable

* --

* --

* review feedback
This commit is contained in:
Syed Ali Shahbaz
2024-08-08 10:59:57 +00:00
committed by GitHub
parent 46acac5dd8
commit f92a95dc2e
3 changed files with 36 additions and 37 deletions
@@ -515,7 +515,7 @@ function BookingListItem(booking: BookingItemProps) {
</div>
</Link>
</td>
<td className="flex w-full justify-end py-4 pl-4 text-right text-sm font-medium ltr:pr-4 rtl:pl-4 sm:pl-0">
<td className="flex w-full flex-col flex-wrap items-end justify-end space-x-2 space-y-2 py-4 pl-4 text-right text-sm font-medium ltr:pr-4 rtl:pl-4 sm:flex-row sm:flex-nowrap sm:items-start sm:space-y-0 sm:pl-0">
{isUpcoming && !isCancelled ? (
<>
{isPending && (userId === booking.user?.id || booking.isUserTeamAdminOrOwner) && (
@@ -526,6 +526,7 @@ function BookingListItem(booking: BookingItemProps) {
</>
) : null}
{isBookingInPast && isPending && !isConfirmed ? <TableActions actions={bookedActions} /> : null}
{isBookingInPast && isConfirmed ? <TableActions actions={bookedActions} /> : null}
{(showViewRecordingsButton || showCheckRecordingButton) && (
<TableActions actions={showRecordingActions} />
)}
@@ -310,7 +310,7 @@ export default function Success(props: PageProps) {
function getTitle(): string {
const titleSuffix = props.recurringBookings ? "_recurring" : "";
const titlePrefix = isRoundRobin ? "round_robin_" : "";
if (isCancelled || isBookingInPast) {
if (isCancelled) {
return "";
}
if (needsConfirmation) {
@@ -355,7 +355,7 @@ export default function Success(props: PageProps) {
const providerName = guessEventLocationType(location)?.label;
const rescheduleProviderName = guessEventLocationType(rescheduleLocation)?.label;
const isBookingInPast = new Date(bookingInfo.endTime) < new Date();
const isReschedulable = !isCancelled && !isBookingInPast;
const isReschedulable = !isCancelled;
const bookingCancelledEventProps = {
booking: bookingInfo,
@@ -367,6 +367,32 @@ export default function Success(props: PageProps) {
eventType,
};
const isRecurringBooking = props.recurringBookings;
const needsConfirmationAndReschedulable = needsConfirmation && isReschedulable;
const isNotAttendingSeatedEvent = isCancelled && seatReferenceUid;
const isEventCancelled = isCancelled && !seatReferenceUid;
const isPastBooking = isBookingInPast;
const successPageHeadline = (() => {
if (needsConfirmationAndReschedulable) {
return isRecurringBooking ? t("booking_submitted_recurring") : t("booking_submitted");
}
if (isNotAttendingSeatedEvent) {
return t("no_longer_attending");
}
if (isEventCancelled) {
return t("event_cancelled");
}
if (isPastBooking) {
return t("event_is_in_the_past");
}
return isRecurringBooking ? t("meeting_is_scheduled_recurring") : t("meeting_is_scheduled");
})();
return (
<div className={isEmbed ? "" : "h-screen"} data-testid="success-page">
{!isEmbed && !isFeedbackMode && (
@@ -439,7 +465,7 @@ export default function Success(props: PageProps) {
"border-cal-bg dark:border-cal-bg-muted absolute bottom-0 right-0 z-10 h-12 w-12 border-8",
!giphyImage && isReschedulable && !needsConfirmation ? "bg-success" : "",
!giphyImage && isReschedulable && needsConfirmation ? "bg-subtle" : "",
isCancelled || isBookingInPast ? "bg-error" : ""
isCancelled ? "bg-error" : ""
)}>
{!giphyImage && !needsConfirmation && isReschedulable && (
<Icon name="check" className="h-5 w-5 text-green-600 dark:text-green-400" />
@@ -447,9 +473,7 @@ export default function Success(props: PageProps) {
{needsConfirmation && isReschedulable && (
<Icon name="calendar" className="text-emphasis h-5 w-5" />
)}
{(isCancelled || isBookingInPast) && (
<Icon name="x" className="h-5 w-5 text-red-600 dark:text-red-200" />
)}
{isCancelled && <Icon name="x" className="h-5 w-5 text-red-600 dark:text-red-200" />}
</div>
</div>
<div className="mb-8 mt-6 text-center last:mb-0">
@@ -457,19 +481,7 @@ export default function Success(props: PageProps) {
className="text-emphasis text-2xl font-semibold leading-6"
data-testid={isCancelled ? "cancelled-headline" : ""}
id="modal-headline">
{needsConfirmation && isReschedulable
? props.recurringBookings
? t("booking_submitted_recurring")
: t("booking_submitted")
: isCancelled
? seatReferenceUid
? t("no_longer_attending")
: t("event_cancelled")
: isBookingInPast
? t("event_expired")
: props.recurringBookings
? t("meeting_is_scheduled_recurring")
: t("meeting_is_scheduled")}
{successPageHeadline}
</h3>
<div className="mt-3">
<p className="text-default">{getTitle()}</p>
+3 -17
View File
@@ -129,16 +129,6 @@ const NoAvailabilityOverlay = ({
);
};
const ReschedulingNotPossibleOverlay = () => {
const { t } = useLocale();
return (
<div className="bg-muted border-subtle absolute left-1/2 top-40 -mt-10 w-2/3 -translate-x-1/2 -translate-y-1/2 transform break-all rounded-md border p-8 shadow-sm">
<h4 className="text-emphasis font-medium">{t("rescheduling_not_possible")}</h4>
</div>
);
};
const Days = ({
minDate,
excludedDates = [],
@@ -291,8 +281,6 @@ const Days = ({
</div>
))}
{isBookingInPast && <ReschedulingNotPossibleOverlay />}
{!props.isPending && !isBookingInPast && includedDates && includedDates?.length === 0 && (
<NoAvailabilityOverlay month={month} nextMonthButton={nextMonthButton} />
)}
@@ -374,13 +362,11 @@ const DatePicker = ({
<Button
className={classNames(
`group p-1 opacity-70 transition hover:opacity-100 rtl:rotate-180`,
isBookingInPast && `disabled:text-bookinglighter hover:bg-background hover:opacity-70`,
`${customClassNames?.datePickerToggle}`
)}
onClick={() => changeMonth(+1)}
data-testid="incrementMonth"
color="minimal"
disabled={isBookingInPast}
variant="icon"
StartIcon="chevron-right"
/>
@@ -406,13 +392,13 @@ const DatePicker = ({
datePickerDateActive: customClassNames?.datePickerDatesActive,
}}
weekStart={weekStart}
selected={!isBookingInPast ? selected : null}
selected={selected}
{...passThroughProps}
browsingDate={browsingDate}
month={month}
nextMonthButton={() => changeMonth(+1)}
slots={!isBookingInPast ? slots : {}}
includedDates={!isBookingInPast ? includedDates : []}
slots={slots}
includedDates={includedDates}
isBookingInPast={isBookingInPast}
/>
</div>