From 2f769a8b8cd4f51f3471aefe3cfe478dcfed07c9 Mon Sep 17 00:00:00 2001
From: Anirban Singha <143536290+SinghaAnirban005@users.noreply.github.com>
Date: Mon, 13 Apr 2026 09:38:19 +0000
Subject: [PATCH] feat: show previous booking time in rescheduled email
---
packages/emails/src/components/WhenInfo.tsx | 43 +++++++++++++++----
.../bookings/lib/BookingEmailSmsHandler.ts | 13 ++++++
packages/types/Calendar.d.ts | 2 +
3 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/packages/emails/src/components/WhenInfo.tsx b/packages/emails/src/components/WhenInfo.tsx
index 801df21731167d..197e3763b14c10 100644
--- a/packages/emails/src/components/WhenInfo.tsx
+++ b/packages/emails/src/components/WhenInfo.tsx
@@ -6,8 +6,7 @@ import dayjs from "@calcom/dayjs";
import "@calcom/dayjs/locales";
import { getEveryFreqFor } from "@calcom/lib/recurringStrings";
import type { TimeFormat } from "@calcom/lib/timeFormat";
-import type { CalendarEvent, Person } from "@calcom/types/Calendar";
-import type { RecurringEvent } from "@calcom/types/Calendar";
+import type { CalendarEvent, Person, RecurringEvent } from "@calcom/types/Calendar";
import { Info } from "./Info";
@@ -40,10 +39,22 @@ export function WhenInfo(props: {
}) {
const { timeZone, t, calEvent: { recurringEvent } = {}, locale, timeFormat } = props;
+ function getPreviousRecipientStart(format: string): string | null {
+ if(!props.calEvent.previousStartTime) return null
+ return dayjs(props.calEvent.previousStartTime).tz(timeZone).locale(locale).format(format)
+ }
+
+ function getPreviousRecipientEnd(format: string): string | null {
+ if(!props.calEvent.previousEndTime) return null
+ return dayjs(props.calEvent.previousEndTime).tz(timeZone).locale(locale).format(format)
+ }
+
function getRecipientStart(format: string) {
return dayjs(props.calEvent.startTime).tz(timeZone).locale(locale).format(format);
}
+ const hasPreviousTime = !!(props.calEvent.previousStartTime && props.calEvent.previousEndTime);
+
function getRecipientEnd(format: string) {
return dayjs(props.calEvent.endTime).tz(timeZone).locale(locale).format(format);
}
@@ -56,16 +67,30 @@ export function WhenInfo(props: {
return (
- {recurringEvent?.count ? `${t("starting")} ` : ""}
- {getRecipientStart(`dddd, LL | ${timeFormat}`)} - {getRecipientEnd(timeFormat)}{" "}
- ({timeZone})
-
+
+ {hasPreviousTime && (
+
+ {recurringEvent?.count ? `${t("starting")} ` : ""}
+ {getPreviousRecipientStart(`dddd, LL | ${timeFormat}`)} -{" "}
+ {getPreviousRecipientEnd(timeFormat)}{" "}
+ ({timeZone})
+
+ )}
+
+ {recurringEvent?.count ? `${t("starting")} ` : ""}
+ {getRecipientStart(`dddd, LL | ${timeFormat}`)} -{" "}
+ {getRecipientEnd(timeFormat)}{" "}
+ ({timeZone})
+
+
}
withSpacer
/>
diff --git a/packages/features/bookings/lib/BookingEmailSmsHandler.ts b/packages/features/bookings/lib/BookingEmailSmsHandler.ts
index 95da16025fc5d3..36be8446be9481 100644
--- a/packages/features/bookings/lib/BookingEmailSmsHandler.ts
+++ b/packages/features/bookings/lib/BookingEmailSmsHandler.ts
@@ -117,6 +117,7 @@ export class BookingEmailSmsHandler {
private async _handleRescheduled(data: RescheduleEmailAndSmsPayload) {
const {
evt,
+ originalRescheduledBooking,
eventType: { metadata },
rescheduleReason,
additionalNotes,
@@ -127,6 +128,12 @@ export class BookingEmailSmsHandler {
await sendRescheduledEmailsAndSMS(
{
...evt,
+ previousStartTime: originalRescheduledBooking?.startTime
+ ? dayjs(originalRescheduledBooking.startTime).utc().format()
+ : undefined,
+ previousEndTime: originalRescheduledBooking?.endTime
+ ? dayjs(originalRescheduledBooking.endTime).utc().format()
+ : undefined,
additionalInformation,
additionalNotes,
cancellationReason: `$RCH$${rescheduleReason || ""}`,
@@ -157,6 +164,12 @@ export class BookingEmailSmsHandler {
additionalInformation,
additionalNotes,
cancellationReason: `$RCH$${rescheduleReason || ""}`,
+ previousStartTime: originalRescheduledBooking?.startTime
+ ? dayjs(originalRescheduledBooking.startTime).utc().format()
+ : undefined,
+ previousEndTime: originalRescheduledBooking?.endTime
+ ? dayjs(originalRescheduledBooking.endTime).utc().format()
+ : undefined,
};
const cancelledRRHostEvt = cloneDeep(copyEventAdditionalInfo);
this.log.debug("Emails: Sending rescheduled emails for booking confirmation");
diff --git a/packages/types/Calendar.d.ts b/packages/types/Calendar.d.ts
index eb9ac6db1bea5b..1cc2d554eb87b4 100644
--- a/packages/types/Calendar.d.ts
+++ b/packages/types/Calendar.d.ts
@@ -219,6 +219,8 @@ export interface CalendarEvent {
platformRescheduleUrl?: string | null;
platformCancelUrl?: string | null;
platformBookingUrl?: string | null;
+ previousStartTime?: string;
+ previousEndTime?: string;
hideBranding?: boolean;
oneTimePassword?: string | null;
delegationCredentialId?: string | null;