feat: Link to rescheduled booking from the old one (#15211)
* feat: Link to rescheduled booking from the old one * add original comment * use fromReschedule * fix: type check * review updates * Update common.json * change booking page text * Delete packages/features/bookings/lib/getRescheduledToBooking.tsx --------- Co-authored-by: Somay Chauhan <somaychauhan98@gmail.com>
This commit is contained in:
co-authored by
Somay Chauhan
parent
01dead9a1d
commit
010f5349f6
@@ -7,6 +7,7 @@ import getBookingInfo from "@calcom/features/bookings/lib/getBookingInfo";
|
||||
import { parseRecurringEvent } from "@calcom/lib";
|
||||
import { getDefaultEvent } from "@calcom/lib/defaultEvents";
|
||||
import { maybeGetBookingUidFromSeat } from "@calcom/lib/server/maybeGetBookingUidFromSeat";
|
||||
import { BookingRepository } from "@calcom/lib/server/repository/booking";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { customInputSchema, EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
|
||||
|
||||
@@ -72,6 +73,14 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||
} as const;
|
||||
}
|
||||
|
||||
let rescheduledToUid: string | null = null;
|
||||
if (bookingInfo.rescheduled) {
|
||||
const rescheduledTo = await BookingRepository.findFirstBookingByReschedule({
|
||||
originalBookingUid: bookingInfo.uid,
|
||||
});
|
||||
rescheduledToUid = rescheduledTo?.uid ?? null;
|
||||
}
|
||||
|
||||
const eventTypeRaw = !bookingInfoRaw.eventTypeId
|
||||
? getDefaultEvent(eventTypeSlug || "")
|
||||
: await getEventTypesFromDB(bookingInfoRaw.eventTypeId);
|
||||
@@ -176,6 +185,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||
...(tz && { tz }),
|
||||
userTimeFormat,
|
||||
requiresLoginToUpdate,
|
||||
rescheduledToUid,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -76,6 +76,8 @@ function mockedSuccessComponentProps(props: Partial<React.ComponentProps<typeof
|
||||
responses: {
|
||||
name: "John",
|
||||
},
|
||||
rescheduled: false,
|
||||
fromReschedule: null,
|
||||
},
|
||||
orgSlug: null,
|
||||
userTimeFormat: 12,
|
||||
@@ -89,6 +91,7 @@ function mockedSuccessComponentProps(props: Partial<React.ComponentProps<typeof
|
||||
},
|
||||
dynamicEventName: "Event Title",
|
||||
paymentStatus: null,
|
||||
rescheduledToUid: null,
|
||||
...props,
|
||||
} satisfies React.ComponentProps<typeof Success>;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ export default function Success(props: PageProps) {
|
||||
const routerQuery = useRouterQuery();
|
||||
const pathname = usePathname();
|
||||
const searchParams = useCompatSearchParams();
|
||||
const { eventType, bookingInfo, requiresLoginToUpdate, orgSlug } = props;
|
||||
const { eventType, bookingInfo, requiresLoginToUpdate, orgSlug, rescheduledToUid } = props;
|
||||
|
||||
const {
|
||||
allRemainingBookings,
|
||||
@@ -585,6 +585,9 @@ export default function Success(props: PageProps) {
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{rescheduledToUid ? <RescheduledToLink rescheduledToUid={rescheduledToUid} /> : null}
|
||||
|
||||
{bookingInfo?.description && (
|
||||
<>
|
||||
<div className="mt-9 font-medium">{t("additional_notes")}</div>
|
||||
@@ -995,6 +998,25 @@ export default function Success(props: PageProps) {
|
||||
);
|
||||
}
|
||||
|
||||
const RescheduledToLink = ({ rescheduledToUid }: { rescheduledToUid: string }) => {
|
||||
const { t } = useLocale();
|
||||
return (
|
||||
<>
|
||||
<div className="mt-3 font-medium">{t("rescheduled")}</div>
|
||||
<div className="col-span-2 mb-2 mt-3">
|
||||
<span className="underline">
|
||||
<Link href={`/booking/${rescheduledToUid}`}>
|
||||
<div className="flex items-center gap-1">
|
||||
{t("view_booking")}
|
||||
<Icon name="external-link" className="h-4 w-4" />
|
||||
</div>
|
||||
</Link>
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const DisplayLocation = ({
|
||||
locationToDisplay,
|
||||
providerName,
|
||||
|
||||
@@ -1491,6 +1491,7 @@
|
||||
"team_disable_cal_branding_description": "Removes any {{appName}} related brandings, i.e. 'Powered by {{appName}}'",
|
||||
"invited_by_team": "{{teamName}} has invited you to join their team as a {{role}}",
|
||||
"token_invalid_expired": "Token is either invalid or expired.",
|
||||
"view_booking": "View Booking",
|
||||
"exchange_add": "Connect to Microsoft Exchange",
|
||||
"exchange_authentication": "Authentication method",
|
||||
"exchange_authentication_standard": "Basic authentication",
|
||||
|
||||
@@ -22,6 +22,8 @@ const getUserBooking = async (uid: string) => {
|
||||
responses: true,
|
||||
rejectionReason: true,
|
||||
userPrimaryEmail: true,
|
||||
fromReschedule: true,
|
||||
rescheduled: true,
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
export class BookingRepository {
|
||||
static async findFirstBookingByReschedule({ originalBookingUid }: { originalBookingUid: string }) {
|
||||
return await prisma.booking.findFirst({
|
||||
where: {
|
||||
fromReschedule: originalBookingUid,
|
||||
},
|
||||
select: {
|
||||
uid: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user