From 0f3773d7243b13ccc3b56d91545284db980f13b1 Mon Sep 17 00:00:00 2001 From: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com> Date: Mon, 18 Nov 2024 19:29:10 +0530 Subject: [PATCH] feat: add instant meeting parameter (#17647) * feat: add instant meeting parameter * feat: show modal only when parameter present * chore: remove logs * fix: type err * fix: UI * fix: remove useFieldArray --- apps/web/public/static/locales/en/common.json | 2 + packages/features/bookings/Booker/Booker.tsx | 40 ++++++++------ packages/features/bookings/types.ts | 1 + .../tabs/instant/InstantEventController.tsx | 54 +++++++++++++++++++ .../features/eventtypes/lib/getPublicEvent.ts | 4 +- packages/features/eventtypes/lib/types.ts | 1 + packages/lib/server/eventTypeSelect.ts | 1 + packages/lib/server/repository/eventType.ts | 1 + packages/lib/test/builder.ts | 1 + .../event-types/hooks/useEventTypeForm.ts | 1 + .../src/endpoints/events/event-types/types.ts | 1 + .../sdk/src/endpoints/events/types.ts | 1 + .../migration.sql | 2 + packages/prisma/schema.prisma | 1 + packages/prisma/zod-utils.ts | 1 + .../server/routers/viewer/eventTypes/types.ts | 1 + 16 files changed, 97 insertions(+), 16 deletions(-) create mode 100644 packages/prisma/migrations/20241114174956_add_instant_meeting_parameters/migration.sql diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json index e7ca29bddc..400a6b2df0 100644 --- a/apps/web/public/static/locales/en/common.json +++ b/apps/web/public/static/locales/en/common.json @@ -2218,6 +2218,8 @@ "add_times_to_your_email": "Select a few available times and embed them in your Email", "select_time": "Select Time", "select_date": "Select Date", + "only_show_if_parameter_set": "Only show if a parameter is set", + "add_parameter": "Add parameter", "connecting_you_to_someone": "We are connecting you to someone from {{orgName}}.", "please_do_not_close_this_tab": "Please do not close or refresh this page", "see_all_available_times": "See all available times", diff --git a/packages/features/bookings/Booker/Booker.tsx b/packages/features/bookings/Booker/Booker.tsx index 9fdb08d3f2..f5dd46f658 100644 --- a/packages/features/bookings/Booker/Booker.tsx +++ b/packages/features/bookings/Booker/Booker.tsx @@ -1,5 +1,6 @@ import { AnimatePresence, LazyMotion, m } from "framer-motion"; import dynamic from "next/dynamic"; +import { useSearchParams } from "next/navigation"; import { useEffect, useMemo, useRef } from "react"; import { Toaster } from "react-hot-toast"; import StickyBox from "react-sticky-box"; @@ -68,6 +69,13 @@ const BookerComponent = ({ customClassNames, }: BookerProps & WrappedBookerProps) => { const { t } = useLocale(); + const searchParams = useSearchParams(); + + const areInstantMeetingParametersSet = !!event.data?.instantMeetingParameters + ? searchParams && + event.data.instantMeetingParameters.every((param) => Array.from(searchParams.values()).includes(param)) + : true; + const [bookerState, setBookerState] = useBookerStore((state) => [state.state, state.setState], shallow); const selectedDate = useBookerStore((state) => state.selectedDate); const { @@ -441,21 +449,23 @@ const BookerComponent = ({ }} /> - {bookerState !== "booking" && event.data?.showInstantEventConnectNowModal && ( -
- { - onConnectNowInstantMeeting(); - }} - /> -
- )} + {bookerState !== "booking" && + event.data?.showInstantEventConnectNowModal && + areInstantMeetingParametersSet && ( +
+ { + onConnectNowInstantMeeting(); + }} + /> +
+ )} {!hideBranding && !isPlatform && ( & { users: BookerEventUser[]; showInstantEventConnectNowModal: boolean } & { profile: BookerEventProfile }; diff --git a/packages/features/eventtypes/components/tabs/instant/InstantEventController.tsx b/packages/features/eventtypes/components/tabs/instant/InstantEventController.tsx index aea168004a..a763ad9268 100644 --- a/packages/features/eventtypes/components/tabs/instant/InstantEventController.tsx +++ b/packages/features/eventtypes/components/tabs/instant/InstantEventController.tsx @@ -76,6 +76,10 @@ export default function InstantEventController({ const [instantEventState, setInstantEventState] = useState(eventType?.isInstantEvent ?? false); const formMethods = useFormContext(); + const [parameters, setParameters] = useState( + formMethods.getValues("instantMeetingParameters") || [] + ); + const { shouldLockDisableProps } = useLockedFieldsManager({ eventType, translate: t, @@ -171,6 +175,56 @@ export default function InstantEventController({ ); }} /> +
+ +
+ {parameters.map((parameter, index) => ( +
+ { + const newParameters = [...parameters]; + newParameters[index] = e.target.value; + setParameters(newParameters); + formMethods.setValue("instantMeetingParameters", newParameters, { + shouldDirty: true, + }); + }} + /> +
+ ))} +
+ +
( diff --git a/packages/features/eventtypes/lib/getPublicEvent.ts b/packages/features/eventtypes/lib/getPublicEvent.ts index 587a71ba3e..1c4b2f9f78 100644 --- a/packages/features/eventtypes/lib/getPublicEvent.ts +++ b/packages/features/eventtypes/lib/getPublicEvent.ts @@ -57,6 +57,7 @@ const publicEventSelect = Prisma.validator()({ eventName: true, slug: true, isInstantEvent: true, + instantMeetingParameters: true, aiPhoneCallConfig: true, schedulingType: true, length: true, @@ -299,6 +300,7 @@ export const getPublicEvent = async ( logoUrl: null, }, isInstantEvent: false, + instantMeetingParameters: [], showInstantEventConnectNowModal: false, autoTranslateDescriptionEnabled: false, fieldTranslations: [], @@ -455,7 +457,6 @@ export const getPublicEvent = async ( if (event.team?.isPrivate && !isTeamAdminOrOwner && !isOrgAdminOrOwner) { users = []; } - return { ...eventWithUserProfiles, bookerLayouts: bookerLayoutsSchema.parse(eventMetaData?.bookerLayouts || null), @@ -495,6 +496,7 @@ export const getPublicEvent = async ( isDynamic: false, isInstantEvent: eventWithUserProfiles.isInstantEvent, showInstantEventConnectNowModal, + instantMeetingParameters: eventWithUserProfiles.instantMeetingParameters, aiPhoneCallConfig: eventWithUserProfiles.aiPhoneCallConfig, assignAllTeamMembers: event.assignAllTeamMembers, }; diff --git a/packages/features/eventtypes/lib/types.ts b/packages/features/eventtypes/lib/types.ts index 382002f647..557b969df4 100644 --- a/packages/features/eventtypes/lib/types.ts +++ b/packages/features/eventtypes/lib/types.ts @@ -71,6 +71,7 @@ export type FormValues = { eventName: string; slug: string; isInstantEvent: boolean; + instantMeetingParameters: string[]; instantMeetingExpiryTimeOffsetInSeconds: number; length: number; offsetStart: number; diff --git a/packages/lib/server/eventTypeSelect.ts b/packages/lib/server/eventTypeSelect.ts index 3748949e8f..37647638f9 100644 --- a/packages/lib/server/eventTypeSelect.ts +++ b/packages/lib/server/eventTypeSelect.ts @@ -44,6 +44,7 @@ export const eventTypeSelect = Prisma.validator()({ successRedirectUrl: true, isInstantEvent: true, instantMeetingExpiryTimeOffsetInSeconds: true, + instantMeetingParameters: true, aiPhoneCallConfig: true, assignAllTeamMembers: true, isRRWeightsEnabled: true, diff --git a/packages/lib/server/repository/eventType.ts b/packages/lib/server/repository/eventType.ts index 9cbbd6fb97..3bc148fd48 100644 --- a/packages/lib/server/repository/eventType.ts +++ b/packages/lib/server/repository/eventType.ts @@ -428,6 +428,7 @@ export class EventTypeRepository { length: true, isInstantEvent: true, instantMeetingExpiryTimeOffsetInSeconds: true, + instantMeetingParameters: true, aiPhoneCallConfig: true, offsetStart: true, hidden: true, diff --git a/packages/lib/test/builder.ts b/packages/lib/test/builder.ts index 42c5de580b..46e8405b87 100644 --- a/packages/lib/test/builder.ts +++ b/packages/lib/test/builder.ts @@ -88,6 +88,7 @@ export const buildEventType = (eventType?: Partial): EventType => { description: faker.lorem.paragraph(), position: 1, isInstantEvent: false, + instantMeetingParameters: [], instantMeetingExpiryTimeOffsetInSeconds: 90, instantMeetingScheduleId: null, locations: null, diff --git a/packages/platform/atoms/event-types/hooks/useEventTypeForm.ts b/packages/platform/atoms/event-types/hooks/useEventTypeForm.ts index eb1712ee01..62771973a4 100644 --- a/packages/platform/atoms/event-types/hooks/useEventTypeForm.ts +++ b/packages/platform/atoms/event-types/hooks/useEventTypeForm.ts @@ -63,6 +63,7 @@ export const useEventTypeForm = ({ destinationCalendar: eventType.destinationCalendar, recurringEvent: eventType.recurringEvent || null, isInstantEvent: eventType.isInstantEvent, + instantMeetingParameters: eventType.instantMeetingParameters || [], instantMeetingExpiryTimeOffsetInSeconds: eventType.instantMeetingExpiryTimeOffsetInSeconds, description: eventType.description ?? undefined, schedule: eventType.schedule || undefined, diff --git a/packages/platform/sdk/src/endpoints/events/event-types/types.ts b/packages/platform/sdk/src/endpoints/events/event-types/types.ts index 9d88567fb7..3c1eba5000 100644 --- a/packages/platform/sdk/src/endpoints/events/event-types/types.ts +++ b/packages/platform/sdk/src/endpoints/events/event-types/types.ts @@ -59,6 +59,7 @@ export type EventType = { bookingLimits: number | null; durationLimits: number | null; isInstantEvent: boolean; + instantMeetingParameters: string[]; instantMeetingExpiryTimeOffsetInSeconds: number; assignAllTeamMembers: boolean; useEventTypeDestinationCalendarEmail: boolean; diff --git a/packages/platform/sdk/src/endpoints/events/types.ts b/packages/platform/sdk/src/endpoints/events/types.ts index c185c61474..04d21e20b5 100644 --- a/packages/platform/sdk/src/endpoints/events/types.ts +++ b/packages/platform/sdk/src/endpoints/events/types.ts @@ -45,6 +45,7 @@ export type Event = { eventName: string; slug: string; isInstantEvent: boolean; + instantMeetingParameters: string[]; instantMeetingExpiryTimeOffsetInSeconds: number; aiPhoneCallConfig: { eventTypeId: number; diff --git a/packages/prisma/migrations/20241114174956_add_instant_meeting_parameters/migration.sql b/packages/prisma/migrations/20241114174956_add_instant_meeting_parameters/migration.sql new file mode 100644 index 0000000000..eb5f8fc7d0 --- /dev/null +++ b/packages/prisma/migrations/20241114174956_add_instant_meeting_parameters/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "EventType" ADD COLUMN "instantMeetingParameters" TEXT[]; diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index 4965f8272d..b0af5935d6 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -146,6 +146,7 @@ model EventType { instantMeetingExpiryTimeOffsetInSeconds Int @default(90) instantMeetingScheduleId Int? instantMeetingSchedule Schedule? @relation("InstantMeetingSchedule", fields: [instantMeetingScheduleId], references: [id]) + instantMeetingParameters String[] assignAllTeamMembers Boolean @default(false) useEventTypeDestinationCalendarEmail Boolean @default(false) aiPhoneCallConfig AIPhoneCallConfiguration? diff --git a/packages/prisma/zod-utils.ts b/packages/prisma/zod-utils.ts index c5b97a381d..58c97fee79 100644 --- a/packages/prisma/zod-utils.ts +++ b/packages/prisma/zod-utils.ts @@ -649,6 +649,7 @@ export const allManagedEventTypeProps: { [k in keyof Omit