| 
									
										
										
										
											2021-06-24 22:26:55 +00:00
										 |  |  | import dayjs from "dayjs"; | 
					
						
							|  |  |  | import timezone from "dayjs/plugin/timezone"; | 
					
						
							| 
									
										
										
										
											2021-09-22 18:36:13 +00:00
										 |  |  | import utc from "dayjs/plugin/utc"; | 
					
						
							|  |  |  | import { GetServerSidePropsContext } from "next"; | 
					
						
							| 
									
										
										
										
											2022-02-01 21:48:40 +00:00
										 |  |  | import { JSONObject } from "superjson/dist/types"; | 
					
						
							| 
									
										
										
										
											2021-03-22 13:48:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 18:03:22 +00:00
										 |  |  | import { getLocationLabels } from "@calcom/app-store/utils"; | 
					
						
							| 
									
										
										
										
											2022-04-08 16:50:10 +00:00
										 |  |  | import { | 
					
						
							|  |  |  |   getDefaultEvent, | 
					
						
							|  |  |  |   getDynamicEventName, | 
					
						
							|  |  |  |   getGroupName, | 
					
						
							|  |  |  |   getUsernameList, | 
					
						
							|  |  |  | } from "@calcom/lib/defaultEvents"; | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  | import { useLocale } from "@calcom/lib/hooks/useLocale"; | 
					
						
							| 
									
										
										
										
											2022-04-05 18:03:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-11 22:20:10 +00:00
										 |  |  | import { asStringOrThrow } from "@lib/asStringOrNull"; | 
					
						
							| 
									
										
										
										
											2022-04-14 21:25:24 +00:00
										 |  |  | import getBooking, { GetBookingType } from "@lib/getBooking"; | 
					
						
							| 
									
										
										
										
											2022-02-11 22:20:10 +00:00
										 |  |  | import prisma from "@lib/prisma"; | 
					
						
							|  |  |  | import { inferSSRProps } from "@lib/types/inferSSRProps"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import BookingPage from "@components/booking/pages/BookingPage"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 18:03:22 +00:00
										 |  |  | import { getTranslation } from "@server/lib/i18n"; | 
					
						
							| 
									
										
										
										
											2022-02-11 22:20:10 +00:00
										 |  |  | import { ssrInit } from "@server/lib/ssr"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-26 18:40:22 +00:00
										 |  |  | dayjs.extend(utc); | 
					
						
							|  |  |  | dayjs.extend(timezone); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-22 18:36:13 +00:00
										 |  |  | export type BookPageProps = inferSSRProps<typeof getServerSideProps>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default function Book(props: BookPageProps) { | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  |   const { t } = useLocale(); | 
					
						
							|  |  |  |   return props.isDynamicGroupBooking && !props.profile.allowDynamicBooking ? ( | 
					
						
							|  |  |  |     <div className="h-screen dark:bg-neutral-900"> | 
					
						
							|  |  |  |       <main className="mx-auto max-w-3xl px-4 py-24"> | 
					
						
							|  |  |  |         <div className="space-y-6" data-testid="event-types"> | 
					
						
							|  |  |  |           <div className="overflow-hidden rounded-sm border dark:border-gray-900"> | 
					
						
							|  |  |  |             <div className="p-8 text-center text-gray-400 dark:text-white"> | 
					
						
							|  |  |  |               <h2 className="font-cal mb-2 text-3xl text-gray-600 dark:text-white"> | 
					
						
							|  |  |  |                 {" " + t("unavailable")} | 
					
						
							|  |  |  |               </h2> | 
					
						
							|  |  |  |               <p className="mx-auto max-w-md">{t("user_dynamic_booking_disabled")}</p> | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       </main> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |   ) : ( | 
					
						
							|  |  |  |     <BookingPage {...props} /> | 
					
						
							|  |  |  |   ); | 
					
						
							| 
									
										
										
										
											2021-03-22 13:48:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-22 18:36:13 +00:00
										 |  |  | export async function getServerSideProps(context: GetServerSidePropsContext) { | 
					
						
							| 
									
										
										
										
											2021-10-20 16:00:11 +00:00
										 |  |  |   const ssr = await ssrInit(context); | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  |   const usernameList = getUsernameList(asStringOrThrow(context.query.user as string)); | 
					
						
							|  |  |  |   const eventTypeSlug = context.query.slug as string; | 
					
						
							|  |  |  |   const users = await prisma.user.findMany({ | 
					
						
							| 
									
										
										
										
											2021-09-14 08:45:28 +00:00
										 |  |  |     where: { | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  |       username: { | 
					
						
							|  |  |  |         in: usernameList, | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2021-07-11 19:35:56 +00:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2021-09-14 08:45:28 +00:00
										 |  |  |     select: { | 
					
						
							| 
									
										
										
										
											2022-02-01 21:48:40 +00:00
										 |  |  |       id: true, | 
					
						
							| 
									
										
										
										
											2021-09-14 08:45:28 +00:00
										 |  |  |       username: true, | 
					
						
							|  |  |  |       name: true, | 
					
						
							|  |  |  |       email: true, | 
					
						
							|  |  |  |       bio: true, | 
					
						
							|  |  |  |       avatar: true, | 
					
						
							|  |  |  |       theme: true, | 
					
						
							| 
									
										
										
										
											2021-11-16 08:51:46 +00:00
										 |  |  |       brandColor: true, | 
					
						
							| 
									
										
										
										
											2022-03-05 15:37:46 +00:00
										 |  |  |       darkBrandColor: true, | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  |       allowDynamicBooking: true, | 
					
						
							| 
									
										
										
										
											2021-09-14 08:45:28 +00:00
										 |  |  |     }, | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2021-03-22 13:48:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  |   if (!users.length) return { notFound: true }; | 
					
						
							|  |  |  |   const [user] = users; | 
					
						
							|  |  |  |   const eventTypeRaw = | 
					
						
							|  |  |  |     usernameList.length > 1 | 
					
						
							|  |  |  |       ? getDefaultEvent(eventTypeSlug) | 
					
						
							|  |  |  |       : await prisma.eventType.findUnique({ | 
					
						
							|  |  |  |           where: { | 
					
						
							|  |  |  |             id: parseInt(asStringOrThrow(context.query.type)), | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |           select: { | 
					
						
							|  |  |  |             id: true, | 
					
						
							|  |  |  |             title: true, | 
					
						
							|  |  |  |             slug: true, | 
					
						
							|  |  |  |             description: true, | 
					
						
							|  |  |  |             length: true, | 
					
						
							|  |  |  |             locations: true, | 
					
						
							|  |  |  |             customInputs: true, | 
					
						
							|  |  |  |             periodType: true, | 
					
						
							|  |  |  |             periodDays: true, | 
					
						
							|  |  |  |             periodStartDate: true, | 
					
						
							|  |  |  |             periodEndDate: true, | 
					
						
							|  |  |  |             metadata: true, | 
					
						
							|  |  |  |             periodCountCalendarDays: true, | 
					
						
							|  |  |  |             price: true, | 
					
						
							|  |  |  |             currency: true, | 
					
						
							|  |  |  |             disableGuests: true, | 
					
						
							|  |  |  |             users: { | 
					
						
							|  |  |  |               select: { | 
					
						
							| 
									
										
										
										
											2022-04-14 21:25:24 +00:00
										 |  |  |                 id: true, | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  |                 username: true, | 
					
						
							|  |  |  |                 name: true, | 
					
						
							|  |  |  |                 email: true, | 
					
						
							|  |  |  |                 bio: true, | 
					
						
							|  |  |  |                 avatar: true, | 
					
						
							|  |  |  |                 theme: true, | 
					
						
							|  |  |  |               }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2021-06-09 18:28:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-01 21:48:40 +00:00
										 |  |  |   if (!eventTypeRaw) return { notFound: true }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const credentials = await prisma.credential.findMany({ | 
					
						
							|  |  |  |     where: { | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  |       userId: { | 
					
						
							|  |  |  |         in: users.map((user) => user.id), | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2022-02-01 21:48:40 +00:00
										 |  |  |     }, | 
					
						
							|  |  |  |     select: { | 
					
						
							|  |  |  |       id: true, | 
					
						
							|  |  |  |       type: true, | 
					
						
							|  |  |  |       key: true, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const web3Credentials = credentials.find((credential) => credential.type.includes("_web3")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const eventType = { | 
					
						
							|  |  |  |     ...eventTypeRaw, | 
					
						
							|  |  |  |     metadata: (eventTypeRaw.metadata || {}) as JSONObject, | 
					
						
							|  |  |  |     isWeb3Active: | 
					
						
							|  |  |  |       web3Credentials && web3Credentials.key | 
					
						
							|  |  |  |         ? (((web3Credentials.key as JSONObject).isWeb3Active || false) as boolean) | 
					
						
							|  |  |  |         : false, | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-09-22 18:36:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-08 16:17:17 +00:00
										 |  |  |   const eventTypeObject = [eventType].map((e) => { | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       ...e, | 
					
						
							|  |  |  |       periodStartDate: e.periodStartDate?.toString() ?? null, | 
					
						
							|  |  |  |       periodEndDate: e.periodEndDate?.toString() ?? null, | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2021-08-04 10:39:43 +00:00
										 |  |  |   })[0]; | 
					
						
							| 
									
										
										
										
											2021-07-15 14:10:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-14 21:25:24 +00:00
										 |  |  |   let booking: GetBookingType | null = null; | 
					
						
							| 
									
										
										
										
											2022-02-10 17:42:06 +00:00
										 |  |  |   if (context.query.rescheduleUid) { | 
					
						
							| 
									
										
										
										
											2022-04-14 21:25:24 +00:00
										 |  |  |     booking = await getBooking(prisma, context.query.rescheduleUid as string); | 
					
						
							| 
									
										
										
										
											2022-02-10 17:42:06 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  |   const isDynamicGroupBooking = users.length > 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-07 13:41:26 +00:00
										 |  |  |   const dynamicNames = isDynamicGroupBooking | 
					
						
							|  |  |  |     ? users.map((user) => { | 
					
						
							|  |  |  |         return user.name || ""; | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     : []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  |   const profile = isDynamicGroupBooking | 
					
						
							|  |  |  |     ? { | 
					
						
							| 
									
										
										
										
											2022-04-07 13:41:26 +00:00
										 |  |  |         name: getGroupName(dynamicNames), | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  |         image: null, | 
					
						
							|  |  |  |         slug: eventTypeSlug, | 
					
						
							|  |  |  |         theme: null, | 
					
						
							|  |  |  |         brandColor: "", | 
					
						
							|  |  |  |         darkBrandColor: "", | 
					
						
							|  |  |  |         allowDynamicBooking: users.some((user) => { | 
					
						
							|  |  |  |           return !user.allowDynamicBooking; | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |           ? false | 
					
						
							|  |  |  |           : true, | 
					
						
							| 
									
										
										
										
											2022-04-08 16:50:10 +00:00
										 |  |  |         eventName: getDynamicEventName(dynamicNames, eventTypeSlug), | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     : { | 
					
						
							|  |  |  |         name: user.name || user.username, | 
					
						
							|  |  |  |         image: user.avatar, | 
					
						
							|  |  |  |         slug: user.username, | 
					
						
							|  |  |  |         theme: user.theme, | 
					
						
							|  |  |  |         brandColor: user.brandColor, | 
					
						
							|  |  |  |         darkBrandColor: user.darkBrandColor, | 
					
						
							| 
									
										
										
										
											2022-04-08 16:50:10 +00:00
										 |  |  |         eventName: null, | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 18:03:22 +00:00
										 |  |  |   const t = await getTranslation(context.locale ?? "en", "common"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-24 22:26:55 +00:00
										 |  |  |   return { | 
					
						
							|  |  |  |     props: { | 
					
						
							| 
									
										
										
										
											2022-04-05 18:03:22 +00:00
										 |  |  |       locationLabels: getLocationLabels(t), | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  |       profile, | 
					
						
							| 
									
										
										
										
											2021-07-15 14:10:26 +00:00
										 |  |  |       eventType: eventTypeObject, | 
					
						
							| 
									
										
										
										
											2021-06-24 22:26:55 +00:00
										 |  |  |       booking, | 
					
						
							| 
									
										
										
										
											2021-10-20 16:00:11 +00:00
										 |  |  |       trpcState: ssr.dehydrate(), | 
					
						
							| 
									
										
										
										
											2022-04-06 17:20:30 +00:00
										 |  |  |       isDynamicGroupBooking, | 
					
						
							| 
									
										
										
										
											2021-06-24 22:26:55 +00:00
										 |  |  |     }, | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-06-15 15:26:16 +00:00
										 |  |  | } |