Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes: #15317 #15382

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion apps/web/components/booking/CancelBooking.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ type Props = {
};
eventType: unknown;
};
rescheduleEmail: string | null;
};

export default function CancelBooking(props: Props) {
const [cancellationReason, setCancellationReason] = useState<string>("");
const { t } = useLocale();
const router = useRouter();
const { booking, allRemainingBookings, seatReferenceUid, bookingCancelledEventProps } = props;
const { booking, allRemainingBookings, seatReferenceUid, bookingCancelledEventProps, rescheduleEmail } =
props;
const [loading, setLoading] = useState(false);
const telemetry = useTelemetry();
const [error, setError] = useState<string | null>(booking ? null : t("booking_already_cancelled"));
Expand Down Expand Up @@ -99,6 +101,7 @@ export default function CancelBooking(props: Props) {
allRemainingBookings,
// @NOTE: very important this shouldn't cancel with number ID use uid instead
seatReferenceUid,
canceledBy: rescheduleEmail,
}),
headers: {
"Content-Type": "application/json",
Expand Down
6 changes: 5 additions & 1 deletion apps/web/modules/bookings/views/bookings-single-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ export default function Success(props: PageProps) {
const [calculatedDuration, setCalculatedDuration] = useState<number | undefined>(undefined);
const [comment, setComment] = useState("");
const parsedRating = rating ? parseInt(rating, 10) : 3;
const userEmail = session?.user?.email ?? searchParams?.get("email");

const defaultRating = isNaN(parsedRating) ? 3 : parsedRating > 5 ? 5 : parsedRating < 1 ? 1 : parsedRating;
const [rateValue, setRateValue] = useState<number>(defaultRating);
Expand Down Expand Up @@ -664,7 +665,9 @@ export default function Success(props: PageProps) {
<span className="text-default inline">
<span className="underline" data-testid="reschedule-link">
<Link
href={`/reschedule/${seatReferenceUid || bookingInfo?.uid}`}
href={`/reschedule/${seatReferenceUid || bookingInfo?.uid} ${
userEmail ? `?email=${userEmail}` : ""
}`}
legacyBehavior>
{t("reschedule")}
</Link>
Expand Down Expand Up @@ -702,6 +705,7 @@ export default function Success(props: PageProps) {
allRemainingBookings={allRemainingBookings}
seatReferenceUid={seatReferenceUid}
bookingCancelledEventProps={bookingCancelledEventProps}
rescheduleEmail={userEmail}
/>
</>
))}
Expand Down
3 changes: 2 additions & 1 deletion apps/web/modules/users/views/users-public-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

const [user] = users; //To be used when we only have a single user, not dynamic group
useTheme(profile.theme);
const { t } = useLocale();

Check warning on line 29 in apps/web/modules/users/views/users-public-view.tsx

View workflow job for this annotation

GitHub Actions / ESLint Report Analysis

apps/web/modules/users/views/users-public-view.tsx#L29

[@typescript-eslint/no-unused-vars] 't' is assigned a value but never used. Allowed unused vars must match /^_/u.

const isBioEmpty = !user.bio || !user.bio.replace("<p><br></p>", "").length;

Expand Down Expand Up @@ -132,8 +132,9 @@
className="text-emphasis absolute right-4 top-4 h-4 w-4 opacity-0 transition-opacity group-hover:opacity-100"
/>
{/* Don't prefetch till the time we drop the amount of javascript in [user][type] page which is impacting score for [user] page */}
<div className="block w-full p-5">
<div className="block w-full">
<Link
className="p-5"
prefetch={false}
href={{
pathname: `/${user.profile.username}/${type.slug}`,
Expand Down
14 changes: 11 additions & 3 deletions apps/web/pages/reschedule/[uid].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,16 @@ export default function Type() {
export async function getServerSideProps(context: GetServerSidePropsContext) {
const session = await getServerSession(context);

const { uid: bookingUid, seatReferenceUid } = z
.object({ uid: z.string(), seatReferenceUid: z.string().optional() })
const {
uid: bookingUid,
seatReferenceUid,
rescheduledBy,
} = z
.object({
uid: z.string(),
seatReferenceUid: z.string().optional(),
rescheduledBy: z.string().optional(),
})
.parse(context.query);

const { uid, seatReferenceUid: maybeSeatReferenceUid } = await maybeGetBookingUidFromSeat(
Expand Down Expand Up @@ -140,7 +148,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
redirect: {
destination: `/${eventPage}?${destinationUrl.toString()}${
eventType.seatsPerTimeSlot ? "&bookingUid=null" : ""
}`,
}${rescheduledBy ? `&rescheduledBy=${rescheduledBy}` : ""}`,
permanent: false,
},
};
Expand Down
9 changes: 8 additions & 1 deletion packages/features/bookings/Booker/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ type StoreInitializeType = {
bookingData?: GetBookingType | null | undefined;
verifiedEmail?: string | null;
rescheduleUid?: string | null;
seatReferenceUid?: string;
seatReferenceUid?: string | null;
reschduledBy?: string | null;
durationConfig?: number[] | null;
org?: string | null;
isInstantMeeting?: boolean;
Expand Down Expand Up @@ -116,6 +117,7 @@ export type BookerStore = {
* object is something that's fetched server side.
*/
rescheduleUid: string | null;
reschduledBy: string | null;
bookingUid: string | null;
bookingData: GetBookingType | null;
setBookingData: (bookingData: GetBookingType | null | undefined) => void;
Expand Down Expand Up @@ -205,6 +207,7 @@ export const useBookerStore = create<BookerStore>((set, get) => ({
username: null,
eventSlug: null,
eventId: null,
reschduledBy: null,
verifiedEmail: null,
setVerifiedEmail: (email: string | null) => {
set({ verifiedEmail: email });
Expand Down Expand Up @@ -240,6 +243,7 @@ export const useBookerStore = create<BookerStore>((set, get) => ({
month,
eventId,
rescheduleUid = null,
reschduledBy = null,
bookingUid = null,
bookingData = null,
layout,
Expand All @@ -257,6 +261,7 @@ export const useBookerStore = create<BookerStore>((set, get) => ({
get().eventId === eventId &&
get().rescheduleUid === rescheduleUid &&
get().bookingUid === bookingUid &&
get().reschduledBy === reschduledBy &&
get().bookingData?.responses.email === bookingData?.responses.email &&
get().layout === layout
)
Expand All @@ -267,6 +272,7 @@ export const useBookerStore = create<BookerStore>((set, get) => ({
eventId,
org,
rescheduleUid,
reschduledBy,
bookingUid,
bookingData,
layout: layout || BookerLayouts.MONTH_VIEW,
Expand Down Expand Up @@ -356,6 +362,7 @@ export const useInitializeBookerStore = ({
month,
eventId,
rescheduleUid = null,
reschduledBy = null,
bookingData = null,
verifiedEmail = null,
layout,
Expand Down
1 change: 1 addition & 0 deletions packages/features/bookings/Booker/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export interface BookerProps {
export type WrappedBookerPropsMain = {
sessionUsername?: string | null;
rescheduleUid: string | null;
rescheduledBy: string | null;
bookingUid: string | null;
isRedirect: boolean;
fromUserNameRedirected: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type BookingOptions = {
timeZone: string;
language: string;
rescheduleUid: string | undefined;
rescheduledBy: string | undefined;
username: string;
metadata?: Record<string, string>;
bookingUid?: string;
Expand All @@ -31,6 +32,7 @@ export const mapBookingToMutationInput = ({
timeZone,
language,
rescheduleUid,
rescheduledBy,
username,
metadata,
bookingUid,
Expand All @@ -52,6 +54,7 @@ export const mapBookingToMutationInput = ({
timeZone: timeZone,
language: language,
rescheduleUid,
rescheduledBy,
metadata: metadata || {},
hasHashedBookingLink: hashedLink ? true : false,
bookingUid,
Expand Down
3 changes: 2 additions & 1 deletion packages/features/bookings/lib/handleCancelBooking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export type CustomRequest = NextApiRequest & {
};

async function handler(req: CustomRequest) {
const { id, uid, allRemainingBookings, cancellationReason, seatReferenceUid } =
const { id, uid, allRemainingBookings, cancellationReason, seatReferenceUid, canceledBy } =
schemaBookingCancelParams.parse(req.body);
req.bookingToDelete = await getBookingToDelete(id, uid);
const {
Expand Down Expand Up @@ -366,6 +366,7 @@ async function handler(req: CustomRequest) {
data: {
status: BookingStatus.CANCELLED,
cancellationReason: cancellationReason,
canceledBy: canceledBy ? canceledBy : undefined, // It's kind of a check the person who cancels the booking is the same person who created it
},
});
const allUpdatedBookings = await prisma.booking.findMany({
Expand Down
3 changes: 3 additions & 0 deletions packages/features/bookings/lib/handleNewBooking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,7 @@ async function handler(
}

let rescheduleUid = reqBody.rescheduleUid;
const reschduledBy = reqBody.rescheduledBy;

if (
Object.prototype.hasOwnProperty.call(eventType, "bookingLimits") ||
Expand Down Expand Up @@ -1243,6 +1244,7 @@ async function handler(
}
originalRescheduledBooking = await getOriginalRescheduledBooking(
rescheduleUid,
reschduledBy,
!!eventType.seatsPerTimeSlot
);
if (!originalRescheduledBooking) {
Expand Down Expand Up @@ -1793,6 +1795,7 @@ async function handler(
data: {
rescheduled: true,
status: BookingStatus.CANCELLED,
reschduledBy: reqBody.rescheduledBy,
},
});
}
Expand Down
11 changes: 7 additions & 4 deletions packages/lib/CalEventParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { TFunction } from "next-i18next";
import short from "short-uuid";
import { v5 as uuidv5 } from "uuid";

import type { CalendarEvent } from "@calcom/types/Calendar";
import type { CalendarEvent, Person } from "@calcom/types/Calendar";

import { WEBAPP_URL } from "./constants";
import getLabelValueMapFromResponses from "./getLabelValueMapFromResponses";
Expand Down Expand Up @@ -217,7 +217,7 @@ export const getPlatformCancelLink = (
return "";
};

export const getCancelLink = (calEvent: CalendarEvent): string => {
export const getCancelLink = (calEvent: CalendarEvent, attendee: Person): string => {
const Uid = getUid(calEvent);
const seatReferenceUid = getSeatReferenceId(calEvent);
if (calEvent.platformClientId) {
Expand All @@ -227,6 +227,7 @@ export const getCancelLink = (calEvent: CalendarEvent): string => {
const cancelLink = new URL(`${calEvent.bookerUrl ?? WEBAPP_URL}/booking/${Uid}`);
cancelLink.searchParams.append("cancel", "true");
cancelLink.searchParams.append("allRemainingBookings", String(!!calEvent.recurringEvent));
cancelLink.searchParams.append("cancelledBy", attendee.email);
if (seatReferenceUid) cancelLink.searchParams.append("seatReferenceUid", seatReferenceUid);
return cancelLink.toString();
};
Expand All @@ -249,15 +250,17 @@ export const getPlatformRescheduleLink = (
return "";
};

export const getRescheduleLink = (calEvent: CalendarEvent): string => {
export const getRescheduleLink = (calEvent: CalendarEvent, attendee: Person): string => {
const Uid = getUid(calEvent);
const seatUid = getSeatReferenceId(calEvent);

if (calEvent.platformClientId) {
return getPlatformRescheduleLink(calEvent, Uid, seatUid);
}

return `${calEvent.bookerUrl ?? WEBAPP_URL}/reschedule/${seatUid ? seatUid : Uid}`;
return `${calEvent.bookerUrl ?? WEBAPP_URL}/reschedule/${seatUid ? seatUid : Uid}$rescheduledBy=${
attendee.email
}`;
};

export const getRichDescription = (
Expand Down
2 changes: 2 additions & 0 deletions packages/platform/atoms/booker/BookerPlatformWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { AtomsWrapper } from "../src/components/atoms-wrapper";

type BookerPlatformWrapperAtomProps = Omit<BookerProps, "username" | "entity"> & {
rescheduleUid?: string;
rescheduledBy?: string;
bookingUid?: string;
username: string | string[];
entity?: BookerProps["entity"];
Expand Down Expand Up @@ -306,6 +307,7 @@ export const BookerPlatformWrapper = (props: BookerPlatformWrapperAtomProps) =>
}
}
rescheduleUid={props.rescheduleUid ?? null}
rescheduledBy={props.rescheduledBy ?? null}
bookingUid={props.bookingUid ?? null}
isRedirect={false}
fromUserNameRedirected=""
Expand Down
4 changes: 4 additions & 0 deletions packages/platform/atoms/booker/BookerWebWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export const BookerWebWrapper = (props: BookerWebWrapperAtomProps) => {
const fromUserNameRedirected = searchParams?.get("username") || "";
const rescheduleUid =
typeof window !== "undefined" ? new URLSearchParams(window.location.search).get("rescheduleUid") : null;
const rescheduledBy =
typeof window !== "undefined" ? new URLSearchParams(window.location.search).get("rescheduledBy") : null;
const bookingUid =
typeof window !== "undefined" ? new URLSearchParams(window.location.search).get("bookingUid") : null;
const date = dayjs(selectedDate).format("YYYY-MM-DD");
Expand All @@ -49,6 +51,7 @@ export const BookerWebWrapper = (props: BookerWebWrapperAtomProps) => {
...props,
eventId: event?.data?.id,
rescheduleUid,
reschduledBy,
bookingUid: bookingUid,
layout: bookerLayout.defaultLayout,
org: props.entity.orgSlug,
Expand Down Expand Up @@ -192,6 +195,7 @@ export const BookerWebWrapper = (props: BookerWebWrapperAtomProps) => {
isRedirect={isRedirect}
fromUserNameRedirected={fromUserNameRedirected}
rescheduleUid={rescheduleUid}
rescheduledBy={rescheduledBy}
bookingUid={bookingUid}
hasSession={hasSession}
extraOptions={routerQuery}
Expand Down
2 changes: 2 additions & 0 deletions packages/platform/atoms/hooks/useHandleBookEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const useHandleBookEvent = ({
const duration = useBookerStore((state) => state.selectedDuration);
const { timezone } = useTimePreferences();
const rescheduleUid = useBookerStore((state) => state.rescheduleUid);
const rescheduledBy = useBookerStore((state) => state.reschduledBy);
const { t, i18n } = useLocale();
const username = useBookerStore((state) => state.username);
const recurringEventCount = useBookerStore((state) => state.recurringEventCount);
Expand Down Expand Up @@ -77,6 +78,7 @@ export const useHandleBookEvent = ({
timeZone: timezone,
language: i18n.language,
rescheduleUid: rescheduleUid || undefined,
rescheduledBy: rescheduledBy || undefined,
bookingUid: (bookingData && bookingData.uid) || seatedEventData?.bookingUid || undefined,
username: username || "",
metadata: metadata,
Expand Down
Loading
Loading