fix: Provide event rescheduling option before the event end time (#15150)

* feat: Provide event rescheduling option

* update

* update

* add checker function

* refactor and update

* update

* fix type error

* Update bookings-single-view.tsx

---------

Co-authored-by: Somay Chauhan <somaychauhan98@gmail.com>
This commit is contained in:
Anik Dhabal BabuandSomay Chauhan authored and GitHub committed 2024-06-28 19:09:33 +05:30
1 parent ececef96e5
commit 3807e339ce
3 files changed
+43 -14

No files matched your search

@@ -296,7 +296,7 @@ export default function Success(props: PageProps) {
function getTitle(): string {
const titleSuffix = props.recurringBookings ? "_recurring" : "";
const titlePrefix = isRoundRobin ? "round_robin_" : "";
if (isCancelled) {
if (isCancelled || isBookingInPast) {
return "";
}
if (needsConfirmation) {
@@ -340,6 +340,8 @@ 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 bookingCancelledEventProps = {
booking: bookingInfo,
@@ -412,7 +414,7 @@ export default function Success(props: PageProps) {
imageSrc={`${bookingInfo.user.avatarUrl}`}
/>
)}
{giphyImage && !needsConfirmation && !isCancelled && (
{giphyImage && !needsConfirmation && isReschedulable && (
// eslint-disable-next-line @next/next/no-img-element
<img src={giphyImage} className="w-full rounded-lg" alt="Gif from Giphy" />
)}
@@ -421,17 +423,19 @@ export default function Success(props: PageProps) {
"mx-auto flex h-12 w-12 items-center justify-center rounded-full",
isRoundRobin &&
"border-cal-bg dark:border-cal-bg-muted absolute bottom-0 right-0 z-10 h-12 w-12 border-8",
!giphyImage && !isCancelled && !needsConfirmation ? "bg-success" : "",
!giphyImage && !isCancelled && needsConfirmation ? "bg-subtle" : "",
isCancelled ? "bg-error" : ""
!giphyImage && isReschedulable && !needsConfirmation ? "bg-success" : "",
!giphyImage && isReschedulable && needsConfirmation ? "bg-subtle" : "",
isCancelled || isBookingInPast ? "bg-error" : ""
)}>
{!giphyImage && !needsConfirmation && !isCancelled && (
{!giphyImage && !needsConfirmation && isReschedulable && (
<Icon name="check" className="h-5 w-5 text-green-600 dark:text-green-400" />
)}
{needsConfirmation && !isCancelled && (
{needsConfirmation && isReschedulable && (
<Icon name="calendar" className="text-emphasis h-5 w-5" />
)}
{isCancelled && <Icon name="x" className="h-5 w-5 text-red-600 dark:text-red-200" />}
{(isCancelled || isBookingInPast) && (
<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">
@@ -439,7 +443,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 && !isCancelled
{needsConfirmation && isReschedulable
? props.recurringBookings
? t("booking_submitted_recurring")
: t("booking_submitted")
@@ -447,6 +451,8 @@ export default function Success(props: PageProps) {
? seatReferenceUid
? t("no_longer_attending")
: t("event_cancelled")
: isBookingInPast
? t("event_expired")
: props.recurringBookings
? t("meeting_is_scheduled_recurring")
: t("meeting_is_scheduled")}
@@ -650,7 +656,7 @@ export default function Success(props: PageProps) {
)}
{!requiresLoginToUpdate &&
(!needsConfirmation || !userIsOwner) &&
!isCancelled &&
isReschedulable &&
(!isCancellationMode ? (
<>
<hr className="border-subtle mb-8" />
@@ -708,7 +714,7 @@ export default function Success(props: PageProps) {
{userIsOwner &&
!needsConfirmation &&
!isCancellationMode &&
!isCancelled &&
isReschedulable &&
!!calculatedDuration && (
<>
<hr className="border-subtle mt-8" />
@@ -2484,5 +2484,7 @@
"USER_PENDING_MEMBER_OF_THE_ORG": "User is a pending member of the organization",
"USER_ALREADY_INVITED_OR_MEMBER": "User is already invited or a member",
"USER_MEMBER_OF_OTHER_ORGANIZATION": "User is member of an organization that this team is not a part of.",
"rescheduling_not_possible": "Rescheduling is not possible as the event has expired",
"event_expired": "This event is expired",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
}
+24 -3
View File
@@ -129,6 +129,16 @@ 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 = [],
@@ -141,6 +151,7 @@ const Days = ({
eventSlug,
slots,
customClassName,
isBookingInPast,
...props
}: Omit<DatePickerProps, "locale" | "className" | "weekStart"> & {
DayComponent?: React.FC<React.ComponentProps<typeof Day>>;
@@ -153,6 +164,7 @@ const Days = ({
datePickerDateActive?: string;
};
scrollToTimeSlots?: () => void;
isBookingInPast: boolean;
}) => {
// Create placeholder elements for empty days in first week
const weekdayOfFirst = browsingDate.date(1).day();
@@ -279,7 +291,9 @@ const Days = ({
</div>
))}
{!props.isPending && includedDates && includedDates?.length === 0 && (
{isBookingInPast && <ReschedulingNotPossibleOverlay />}
{!props.isPending && !isBookingInPast && includedDates && includedDates?.length === 0 && (
<NoAvailabilityOverlay month={month} nextMonthButton={nextMonthButton} />
)}
</>
@@ -294,6 +308,7 @@ const DatePicker = ({
onMonthChange,
slots,
customClassNames,
includedDates,
...passThroughProps
}: DatePickerProps &
Partial<React.ComponentProps<typeof Days>> & {
@@ -308,6 +323,8 @@ const DatePicker = ({
}) => {
const browsingDate = passThroughProps.browsingDate || dayjs().startOf("month");
const { i18n } = useLocale();
const bookingData = useBookerStore((state) => state.bookingData);
const isBookingInPast = bookingData ? new Date(bookingData.endTime) < new Date() : false;
const changeMonth = (newMonth: number) => {
if (onMonthChange) {
@@ -357,11 +374,13 @@ 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"
/>
@@ -387,12 +406,14 @@ const DatePicker = ({
datePickerDateActive: customClassNames?.datePickerDatesActive,
}}
weekStart={weekStart}
selected={selected}
selected={!isBookingInPast ? selected : null}
{...passThroughProps}
browsingDate={browsingDate}
month={month}
nextMonthButton={() => changeMonth(+1)}
slots={slots}
slots={!isBookingInPast ? slots : {}}
includedDates={!isBookingInPast ? includedDates : []}
isBookingInPast={isBookingInPast}
/>
</div>
</div>