1
1
import { ChevronDownIcon , PlusIcon } from "@heroicons/react/solid" ;
2
2
import { zodResolver } from "@hookform/resolvers/zod" ;
3
3
import { SchedulingType } from "@prisma/client" ;
4
+ import { useSession } from "next-auth/react" ;
4
5
import { useRouter } from "next/router" ;
5
6
import { useEffect } from "react" ;
6
7
import { useForm } from "react-hook-form" ;
7
8
import type { z } from "zod" ;
8
9
10
+ import classNames from "@calcom/lib/classNames" ;
9
11
import { WEBAPP_URL } from "@calcom/lib/constants" ;
10
12
import { useLocale } from "@calcom/lib/hooks/useLocale" ;
11
13
import showToast from "@calcom/lib/notification" ;
@@ -37,7 +39,7 @@ export interface EventTypeParent {
37
39
image ?: string | null ;
38
40
}
39
41
40
- interface Props {
42
+ interface CreateEventTypeBtnProps {
41
43
// set true for use on the team settings page
42
44
canAddEvents : boolean ;
43
45
// set true when in use on the team settings page
@@ -46,7 +48,7 @@ interface Props {
46
48
options : EventTypeParent [ ] ;
47
49
}
48
50
49
- export default function CreateEventTypeButton ( props : Props ) {
51
+ export default function CreateEventTypeButton ( props : CreateEventTypeBtnProps ) {
50
52
const { t } = useLocale ( ) ;
51
53
const router = useRouter ( ) ;
52
54
@@ -142,39 +144,13 @@ export default function CreateEventTypeButton(props: Props) {
142
144
< Dialog
143
145
name = "new-eventtype"
144
146
clearQueryParamsOnClose = { [ "eventPage" , "teamId" , "type" , "description" , "title" , "length" , "slug" ] } >
145
- { ! hasTeams || props . isIndividualTeam ? (
146
- < Button
147
- onClick = { ( ) => openModal ( props . options [ 0 ] ) }
148
- data-testid = "new-event-type"
149
- StartIcon = { PlusIcon }
150
- disabled = { ! props . canAddEvents } >
151
- { t ( "new_event_type_btn" ) }
152
- </ Button >
153
- ) : (
154
- < Dropdown >
155
- < DropdownMenuTrigger asChild >
156
- < Button EndIcon = { ChevronDownIcon } > { t ( "new_event_type_btn" ) } </ Button >
157
- </ DropdownMenuTrigger >
158
- < DropdownMenuContent align = "end" >
159
- < DropdownMenuLabel > { t ( "new_event_subtitle" ) } </ DropdownMenuLabel >
160
- < DropdownMenuSeparator className = "h-px bg-gray-200" />
161
- { props . options . map ( ( option ) => (
162
- < DropdownMenuItem
163
- key = { option . slug }
164
- className = "cursor-pointer px-3 py-2 hover:bg-neutral-100 focus:outline-none"
165
- onSelect = { ( ) => openModal ( option ) } >
166
- < Avatar
167
- alt = { option . name || "" }
168
- imageSrc = { option . image || `${ WEBAPP_URL } /${ option . slug } /avatar.png` } // if no image, use default avatar
169
- size = { 6 }
170
- className = "inline ltr:mr-2 rtl:ml-2"
171
- />
172
- { option . name ? option . name : option . slug }
173
- </ DropdownMenuItem >
174
- ) ) }
175
- </ DropdownMenuContent >
176
- </ Dropdown >
177
- ) }
147
+ < CreateEventTypeTrigger
148
+ hasTeams = { hasTeams }
149
+ canAddEvents = { props . canAddEvents }
150
+ isIndividualTeam = { props . isIndividualTeam }
151
+ openModal = { openModal }
152
+ options = { props . options }
153
+ />
178
154
179
155
< DialogContent className = "overflow-y-auto" >
180
156
< div className = "mb-4" >
@@ -290,3 +266,83 @@ export default function CreateEventTypeButton(props: Props) {
290
266
</ Dialog >
291
267
) ;
292
268
}
269
+
270
+ type CreateEventTypeTrigger = {
271
+ isIndividualTeam ?: boolean ;
272
+ // EventTypeParent can be a profile (as first option) or a team for the rest.
273
+ options : EventTypeParent [ ] ;
274
+ hasTeams : boolean ;
275
+ // set true for use on the team settings page
276
+ canAddEvents : boolean ;
277
+ openModal : ( option : EventTypeParent ) => void ;
278
+ } ;
279
+
280
+ export function CreateEventTypeTrigger ( props : CreateEventTypeTrigger ) {
281
+ const { t } = useLocale ( ) ;
282
+
283
+ return (
284
+ < >
285
+ { ! props . hasTeams || props . isIndividualTeam ? (
286
+ < Button
287
+ onClick = { ( ) => props . openModal ( props . options [ 0 ] ) }
288
+ data-testid = "new-event-type"
289
+ StartIcon = { PlusIcon }
290
+ disabled = { ! props . canAddEvents } >
291
+ { t ( "new_event_type_btn" ) }
292
+ </ Button >
293
+ ) : (
294
+ < Dropdown >
295
+ < DropdownMenuTrigger asChild >
296
+ < Button EndIcon = { ChevronDownIcon } > { t ( "new_event_type_btn" ) } </ Button >
297
+ </ DropdownMenuTrigger >
298
+ < DropdownMenuContent align = "end" >
299
+ < DropdownMenuLabel > { t ( "new_event_subtitle" ) } </ DropdownMenuLabel >
300
+ < DropdownMenuSeparator className = "h-px bg-gray-200" />
301
+ { props . options . map ( ( option ) => (
302
+ < CreateEventTeamsItem
303
+ key = { option . slug }
304
+ option = { option }
305
+ openModal = { ( ) => props . openModal ( option ) }
306
+ />
307
+ ) ) }
308
+ </ DropdownMenuContent >
309
+ </ Dropdown >
310
+ ) }
311
+ </ >
312
+ ) ;
313
+ }
314
+
315
+ function CreateEventTeamsItem ( props : {
316
+ openModal : ( option : EventTypeParent ) => void ;
317
+ option : EventTypeParent ;
318
+ } ) {
319
+ const session = useSession ( ) ;
320
+ const membershipQuery = trpc . useQuery ( [
321
+ "viewer.teams.getMembershipbyUser" ,
322
+ {
323
+ memberId : session . data ?. user . id as number ,
324
+ teamId : props . option . teamId as number ,
325
+ } ,
326
+ ] ) ;
327
+
328
+ const isDisabled = membershipQuery . data ?. role === "MEMBER" ;
329
+
330
+ return (
331
+ < DropdownMenuItem
332
+ key = { props . option . slug }
333
+ className = { classNames (
334
+ "cursor-pointer px-3 py-2 focus:outline-none" ,
335
+ isDisabled ? "cursor-default !text-gray-300" : "hover:bg-neutral-100"
336
+ ) }
337
+ disabled = { isDisabled }
338
+ onSelect = { ( ) => props . openModal ( props . option ) } >
339
+ < Avatar
340
+ alt = { props . option . name || "" }
341
+ imageSrc = { props . option . image }
342
+ size = { 6 }
343
+ className = "inline ltr:mr-2 rtl:ml-2"
344
+ />
345
+ { props . option . name ? props . option . name : props . option . slug }
346
+ </ DropdownMenuItem >
347
+ ) ;
348
+ }
0 commit comments