@@ -2,11 +2,9 @@ import type { GetServerSidePropsContext } from "next";
22import { z } from "zod" ;
33
44import { getServerSession } from "@calcom/features/auth/lib/getServerSession" ;
5+ import type { GetBookingType } from "@calcom/features/bookings/lib/get-booking" ;
56import { getBookingForReschedule } from "@calcom/features/bookings/lib/get-booking" ;
6- import {
7- orgDomainConfig ,
8- whereClauseForOrgWithSlugOrRequestedSlug ,
9- } from "@calcom/features/ee/organizations/lib/orgDomains" ;
7+ import { getSlugOrRequestedSlug , orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains" ;
108import { getOrganizationSEOSettings } from "@calcom/features/ee/organizations/lib/orgSettings" ;
119import { FeaturesRepository } from "@calcom/features/flags/features.repository" ;
1210import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage" ;
@@ -32,7 +30,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
3230 const { req, params, query } = context ;
3331 const session = await getServerSession ( { req } ) ;
3432 const { slug : teamSlug , type : meetingSlug } = paramsSchema . parse ( params ) ;
35- const { rescheduleUid, isInstantMeeting : queryIsInstantMeeting } = query ;
33+ const { rescheduleUid, isInstantMeeting : queryIsInstantMeeting , email } = query ;
3634 const allowRescheduleForCancelledBooking = query . allowRescheduleForCancelledBooking === "true" ;
3735 const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig ( req , params ?. orgSlug ) ;
3836 const isOrgContext = currentOrgDomain && isValidOrgDomain ;
@@ -43,57 +41,50 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
4341 redirectType : RedirectType . Team ,
4442 eventTypeSlug : meetingSlug ,
4543 currentQuery : context . query ,
46- prismaClient : prisma ,
4744 } ) ;
4845
4946 if ( redirect ) {
5047 return redirect ;
5148 }
5249 }
5350
54- const [ orgId , booking ] = await Promise . all ( [
55- isOrgContext ? getOrgId ( currentOrgDomain ) : Promise . resolve ( null ) ,
56- rescheduleUid ? getBookingForReschedule ( `${ rescheduleUid } ` , session ?. user ?. id ) : Promise . resolve ( null ) ,
57- ] ) ;
51+ const team = await getTeamWithEventsData ( teamSlug , meetingSlug , isValidOrgDomain , currentOrgDomain ) ;
5852
59- const team = await getTeamData ( teamSlug , orgId ) ;
60-
61- if ( ! team ) {
53+ if ( ! team || ! team . eventTypes ?. [ 0 ] ) {
6254 return { notFound : true } as const ;
6355 }
6456
65- const eventData = await getEventTypeData ( meetingSlug , team . id ) ;
66-
67- if ( ! eventData ) {
68- return { notFound : true } as const ;
69- }
57+ const eventData = team . eventTypes [ 0 ] ;
7058
7159 if ( rescheduleUid && eventData . disableRescheduling ) {
7260 return { redirect : { destination : `/booking/${ rescheduleUid } ` , permanent : false } } ;
7361 }
7462
75- if (
76- booking ?. status === BookingStatus . CANCELLED &&
77- ! allowRescheduleForCancelledBooking &&
78- ! eventData . allowReschedulingCancelledBookings
79- ) {
80- return {
81- redirect : {
82- permanent : false ,
83- destination : `/team/${ teamSlug } /${ meetingSlug } ` ,
84- } ,
85- } ;
86- }
87-
8863 const eventTypeId = eventData . id ;
64+ const eventHostsUserData = await getUsersData (
65+ team . isPrivate ,
66+ eventTypeId ,
67+ eventData . hosts . map ( ( h ) => h . user )
68+ ) ;
8969 const orgSlug = isValidOrgDomain ? currentOrgDomain : null ;
9070 const name = team . parent ?. name ?? team . name ?? null ;
9171
92- const eventHostsUserData = getEventHosts (
93- team . isPrivate ,
94- eventData . hosts . map ( ( h ) => h . user ) ,
95- eventData . users ?? [ ]
96- ) ;
72+ let booking : GetBookingType | null = null ;
73+ if ( rescheduleUid ) {
74+ booking = await getBookingForReschedule ( `${ rescheduleUid } ` , session ?. user ?. id ) ;
75+ if (
76+ booking ?. status === BookingStatus . CANCELLED &&
77+ ! allowRescheduleForCancelledBooking &&
78+ ! eventData . allowReschedulingCancelledBookings
79+ ) {
80+ return {
81+ redirect : {
82+ permanent : false ,
83+ destination : `/team/${ teamSlug } /${ meetingSlug } ` ,
84+ } ,
85+ } ;
86+ }
87+ }
9788
9889 const fromRedirectOfNonOrgLink = context . query . orgRedirection === "true" ;
9990 const isUnpublished = team . parent ? ! team . parent . slug : ! team . slug ;
@@ -104,9 +95,11 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
10495
10596 // Handle string[] type from query params
10697 let teamMemberEmail = Array . isArray ( crmContactOwnerEmail ) ? crmContactOwnerEmail [ 0 ] : crmContactOwnerEmail ;
98+
10799 let crmOwnerRecordType = Array . isArray ( crmContactOwnerRecordType )
108100 ? crmContactOwnerRecordType [ 0 ]
109101 : crmContactOwnerRecordType ;
102+
110103 let crmAppSlug = Array . isArray ( crmAppSlugParam ) ? crmAppSlugParam [ 0 ] : crmAppSlugParam ;
111104
112105 if ( ! teamMemberEmail || ! crmOwnerRecordType || ! crmAppSlug ) {
@@ -129,6 +122,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
129122
130123 const organizationSettings = getOrganizationSEOSettings ( team ) ;
131124 const allowSEOIndexing = organizationSettings ?. allowSEOIndexing ?? false ;
125+
132126 const featureRepo = new FeaturesRepository ( ) ;
133127 const teamHasApiV2Route = await featureRepo . checkIfTeamHasFeature ( team . id , "use-api-v2-for-team-slots" ) ;
134128 const useApiV2 = teamHasApiV2Route && hasApiV2RouteInEnv ( ) ;
@@ -178,149 +172,116 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
178172 } ;
179173} ;
180174
181- const getOrgId = async ( orgSlug : string ) : Promise < number | null > => {
182- const org = await prisma . team . findFirst ( {
183- where : whereClauseForOrgWithSlugOrRequestedSlug ( orgSlug ) ,
184- select : { id : true } ,
185- } ) ;
186-
187- return org ?. id ?? null ;
188- } ;
189-
190- const getTeamData = async ( teamSlug : string , orgId : number | null ) => {
191- const teamSelectFields = {
192- id : true ,
193- isPrivate : true ,
194- hideBranding : true ,
195- logoUrl : true ,
196- name : true ,
197- slug : true ,
198- isOrganization : true ,
199- parent : {
200- select : {
201- slug : true ,
202- name : true ,
203- bannerUrl : true ,
204- logoUrl : true ,
205- hideBranding : true ,
206- organizationSettings : {
207- select : {
208- allowSEOIndexing : true ,
209- } ,
210- } ,
211- } ,
212- } ,
213- organizationSettings : {
214- select : {
215- allowSEOIndexing : true ,
216- } ,
217- } ,
218- } ;
219-
220- if ( orgId !== null ) {
221- const publishedTeam = await prisma . team . findUnique ( {
222- where : {
223- slug_parentId : {
224- slug : teamSlug ,
225- parentId : orgId ,
226- } ,
227- isOrganization : false ,
228- } ,
229- select : teamSelectFields ,
230- } ) ;
231- if ( publishedTeam ) return publishedTeam ;
232- }
233-
175+ const getTeamWithEventsData = async (
176+ teamSlug : string ,
177+ meetingSlug : string ,
178+ isValidOrgDomain : boolean ,
179+ currentOrgDomain : string | null
180+ ) => {
234181 return await prisma . team . findFirst ( {
235182 where : {
236- parentId : orgId ?? null ,
237- isOrganization : false ,
238- OR : [
239- { slug : teamSlug } ,
240- {
241- metadata : {
242- path : [ "requestedSlug" ] ,
243- equals : teamSlug ,
244- } ,
245- } ,
246- ] ,
183+ ...getSlugOrRequestedSlug ( teamSlug ) ,
184+ parent : isValidOrgDomain && currentOrgDomain ? getSlugOrRequestedSlug ( currentOrgDomain ) : null ,
247185 } ,
248- select : teamSelectFields ,
249186 orderBy : {
250187 slug : { sort : "asc" , nulls : "last" } ,
251188 } ,
252- } ) ;
253- } ;
254-
255- const getEventTypeData = async ( meetingSlug : string , teamId : number ) => {
256- return await prisma . eventType . findUnique ( {
257- where : {
258- // Use the EventType_teamId_slug_key unique index
259- teamId_slug : {
260- teamId : teamId ,
261- slug : meetingSlug ,
262- } ,
263- } ,
264189 select : {
265190 id : true ,
266- title : true ,
267- isInstantEvent : true ,
268- schedulingType : true ,
269- metadata : true ,
270- length : true ,
271- hidden : true ,
272- disableCancelling : true ,
273- disableRescheduling : true ,
274- allowReschedulingCancelledBookings : true ,
275- interfaceLanguage : true ,
276- hosts : {
277- take : 3 ,
191+ isPrivate : true ,
192+ hideBranding : true ,
193+ parent : {
278194 select : {
279- user : {
195+ slug : true ,
196+ name : true ,
197+ bannerUrl : true ,
198+ logoUrl : true ,
199+ hideBranding : true ,
200+ organizationSettings : {
280201 select : {
281- name : true ,
282- username : true ,
202+ allowSEOIndexing : true ,
283203 } ,
284204 } ,
285205 } ,
286206 } ,
287- // Include users for when hosts is empty
288- users : {
289- take : 1 ,
207+ logoUrl : true ,
208+ name : true ,
209+ slug : true ,
210+ eventTypes : {
211+ where : {
212+ slug : meetingSlug ,
213+ } ,
290214 select : {
291- username : true ,
292- name : true ,
215+ id : true ,
216+ title : true ,
217+ isInstantEvent : true ,
218+ schedulingType : true ,
219+ metadata : true ,
220+ length : true ,
221+ hidden : true ,
222+ disableCancelling : true ,
223+ disableRescheduling : true ,
224+ allowReschedulingCancelledBookings : true ,
225+ interfaceLanguage : true ,
226+ hosts : {
227+ take : 3 ,
228+ select : {
229+ user : {
230+ select : {
231+ name : true ,
232+ username : true ,
233+ email : true ,
234+ } ,
235+ } ,
236+ } ,
237+ } ,
238+ } ,
239+ } ,
240+ isOrganization : true ,
241+ organizationSettings : {
242+ select : {
243+ allowSEOIndexing : true ,
293244 } ,
294245 } ,
295246 } ,
296247 } ) ;
297248} ;
298249
299- const getEventHosts = (
250+ const getUsersData = async (
300251 isPrivateTeam : boolean ,
301- hosts : Pick < User , "username" | "name" > [ ] ,
252+ eventTypeId : number ,
302253 users : Pick < User , "username" | "name" > [ ]
303254) => {
304- if ( isPrivateTeam ) {
305- return [ ] ;
306- }
307-
308- if ( hosts . length > 0 ) {
309- return hosts
255+ if ( ! isPrivateTeam && users . length > 0 ) {
256+ return users
310257 . filter ( ( user ) => user . username )
311258 . map ( ( user ) => ( {
312259 username : user . username ?? "" ,
313260 name : user . name ?? "" ,
314261 } ) ) ;
315262 }
316-
317- if ( users . length > 0 ) {
318- return [
319- {
320- username : users [ 0 ] . username ?? "" ,
321- name : users [ 0 ] . name ?? "" ,
263+ if ( ! isPrivateTeam && users . length === 0 ) {
264+ const { users : data } = await prisma . eventType . findUniqueOrThrow ( {
265+ where : { id : eventTypeId } ,
266+ select : {
267+ users : {
268+ take : 1 ,
269+ select : {
270+ username : true ,
271+ name : true ,
272+ } ,
273+ } ,
322274 } ,
323- ] ;
275+ } ) ;
276+
277+ return data . length > 0
278+ ? [
279+ {
280+ username : data [ 0 ] . username ?? "" ,
281+ name : data [ 0 ] . name ?? "" ,
282+ } ,
283+ ]
284+ : [ ] ;
324285 }
325286
326287 return [ ] ;
0 commit comments