diff --git a/apps/web/components/v2/eventtype/AvailabilityTab.tsx b/apps/web/components/v2/eventtype/AvailabilityTab.tsx index ca2f30e919136b..895b131b128174 100644 --- a/apps/web/components/v2/eventtype/AvailabilityTab.tsx +++ b/apps/web/components/v2/eventtype/AvailabilityTab.tsx @@ -9,7 +9,7 @@ import { weekdayNames } from "@calcom/lib/weekday"; import { trpc } from "@calcom/trpc/react"; import useMeQuery from "@calcom/trpc/react/hooks/useMeQuery"; import { Icon } from "@calcom/ui"; -import { Badge } from "@calcom/ui/v2"; +import { Badge, SettingsToggle } from "@calcom/ui/v2"; import Button from "@calcom/ui/v2/core/Button"; import Select from "@calcom/ui/v2/core/form/select"; import { SkeletonText } from "@calcom/ui/v2/core/skeleton"; @@ -99,91 +99,114 @@ const format = (date: Date, hour12: boolean) => new Date(dayjs.utc(date).format("YYYY-MM-DDTHH:mm:ss")) ); -export const AvailabilityTab = () => { +export const AvailabilityTab = ({ isTeamEvent }: { isTeamEvent: boolean }) => { const { t, i18n } = useLocale(); const { watch } = useFormContext(); - const me = useMeQuery(); - const timeFormat = me?.data?.timeFormat; + + const EventTypeSchedule = () => { + const me = useMeQuery(); + const timeFormat = me?.data?.timeFormat; + return ( +
+
+
+ +
+ ( + { + field.onChange(selected?.value || null); + }} + /> + )} + /> +
+
+
    + {weekdayNames(i18n.language, 1, "long").map((day, index) => { + const isAvailable = !!filterDays(index).length; + return ( +
  1. + + {day} + + {isLoading ? ( + + ) : isAvailable ? ( +
    + {filterDays(index).map((dayRange, i) => ( +
    + + {format(dayRange.startTime, timeFormat === 12)} + + - +
    {format(dayRange.endTime, timeFormat === 12)}
    +
    + ))} +
    + ) : ( + {t("unavailable")} + )} +
  2. + ); + })} +
+
+
+ + + {schedule?.timeZone || } + + +
+
+
+ ); + }; + const scheduleId = watch("schedule"); const { isLoading, data: schedule } = trpc.useQuery(["viewer.availability.schedule", { scheduleId }]); const filterDays = (dayNum: number) => schedule?.schedule.availability.filter((item) => item.days.includes((dayNum + 1) % 7)) || []; - return ( - <> -
-
- -
- ( - { - field.onChange(selected?.value || null); - }} - /> - )} - /> -
+ if (!isTeamEvent) { + return ; + } -
-
    - {weekdayNames(i18n.language, 1, "long").map((day, index) => { - const isAvailable = !!filterDays(index).length; - return ( -
  1. - - {day} - - {isLoading ? ( - - ) : isAvailable ? ( -
    - {filterDays(index).map((dayRange, i) => ( -
    - - {format(dayRange.startTime, timeFormat === 12)} - - - -
    {format(dayRange.endTime, timeFormat === 12)}
    -
    - ))} -
    - ) : ( - {t("unavailable")} - )} -
  2. - ); - })} -
-
-
- - - {schedule?.timeZone || } - - -
-
- + return ( + ( + { + onChange(!checked); + }} + title={t("choose_common_schedule_team_event")} + description={t("choose_common_schedule_team_event_description")}> + + + )} + /> ); }; diff --git a/apps/web/middleware.ts b/apps/web/middleware.ts index dddd96ec1f3487..4be198227c3565 100644 --- a/apps/web/middleware.ts +++ b/apps/web/middleware.ts @@ -39,6 +39,10 @@ const middleware: NextMiddleware = async (req) => { return NextResponse.next(); }; +export const config = { + matcher: ["/api/collect-events/:path*", "/api/auth/:path*", "/apps/routing_forms/:path*", "/:path*/embed"], +}; + export default collectEvents({ middleware, ...nextCollectBasicSettings, diff --git a/apps/web/pages/apps/[slug]/[...pages].tsx b/apps/web/pages/apps/[slug]/[...pages].tsx index f528391e251f82..80c3fd0f6e894c 100644 --- a/apps/web/pages/apps/[slug]/[...pages].tsx +++ b/apps/web/pages/apps/[slug]/[...pages].tsx @@ -9,6 +9,8 @@ import { AppGetServerSideProps } from "@calcom/types/AppGetServerSideProps"; import { AppProps } from "@lib/app-providers"; import { getSession } from "@lib/auth"; +import { ssrInit } from "@server/lib/ssr"; + type AppPageType = { getServerSideProps: AppGetServerSideProps; // A component than can accept any properties @@ -128,7 +130,8 @@ export async function getServerSideProps( appPages: string[]; }>, prisma, - user + user, + ssrInit ); // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore diff --git a/apps/web/pages/event-types/[type]/index.tsx b/apps/web/pages/event-types/[type]/index.tsx index 3c8c43a1a074d4..4b1fa3050b9c66 100644 --- a/apps/web/pages/event-types/[type]/index.tsx +++ b/apps/web/pages/event-types/[type]/index.tsx @@ -192,7 +192,7 @@ const EventTypePage = (props: inferSSRProps) => { teamMembers={teamMembers} /> ), - availability: , + availability: , team: ( + +
+ { + return ( + onChange(val)} + /> + ); + }} + /> +
{!form._count?.responses && ( ; + response: Response; + subject: string; +} & Partial>) => { + return ( + +

+ + <>Manage this form + +

+ + } + title={form.name} + subtitle="New Response Received" + {...props}> + {Object.entries(response).map(([fieldId, fieldResponse]) => { + return ( + + ); + })} +
+ ); +}; diff --git a/packages/app-store/ee/routing-forms/emails/components/index.tsx b/packages/app-store/ee/routing-forms/emails/components/index.tsx new file mode 100644 index 00000000000000..f31987110f16b1 --- /dev/null +++ b/packages/app-store/ee/routing-forms/emails/components/index.tsx @@ -0,0 +1 @@ +export { ResponseEmail } from "./ResponseEmail"; diff --git a/packages/app-store/ee/routing-forms/emails/templates/response-email.ts b/packages/app-store/ee/routing-forms/emails/templates/response-email.ts new file mode 100644 index 00000000000000..1805b96b46fc0c --- /dev/null +++ b/packages/app-store/ee/routing-forms/emails/templates/response-email.ts @@ -0,0 +1,33 @@ +import { renderEmail } from "@calcom/emails"; +import BaseEmail from "@calcom/emails/templates/_base-email"; + +import { Response } from "../../types/types"; +import { App_RoutingForms_Form } from ".prisma/client"; + +type Form = Pick; +export default class ResponseEmail extends BaseEmail { + response: Response; + toAddresses: string[]; + form: Form; + constructor({ toAddresses, response, form }: { form: Form; toAddresses: string[]; response: Response }) { + super(); + this.form = form; + this.response = response; + this.toAddresses = toAddresses; + } + + protected getNodeMailerPayload(): Record { + const toAddresses = this.toAddresses; + const subject = `${this.form.name} has a new response`; + return { + from: `Cal.com <${this.getMailerOptions().from}>`, + to: toAddresses.join(","), + subject, + html: renderEmail("ResponseEmail", { + form: this.form, + response: this.response, + subject, + }), + }; + } +} diff --git a/packages/app-store/ee/routing-forms/lib/getSerializableForm.ts b/packages/app-store/ee/routing-forms/lib/getSerializableForm.ts index aabf39c405017c..6edc814ef83403 100644 --- a/packages/app-store/ee/routing-forms/lib/getSerializableForm.ts +++ b/packages/app-store/ee/routing-forms/lib/getSerializableForm.ts @@ -1,5 +1,7 @@ import { App_RoutingForms_Form } from "@prisma/client"; +import { RoutingFormSettings } from "@calcom/prisma/zod-utils"; + import { SerializableForm } from "../types/types"; import { zodFields, zodRoutes } from "../zod"; @@ -13,10 +15,17 @@ export function getSerializableForm(form: T if (!fieldsParsed.success) { throw new Error("Error parsing fields"); } + const settings = RoutingFormSettings.parse( + form.settings || { + // Would have really loved to do it using zod. But adding .default(true) throws type error in prisma/zod/app_routingforms_form.ts + emailOwnerOnSubmission: true, + } + ); // Ideally we shouldb't have needed to explicitly type it but due to some reason it's not working reliably with VSCode TypeCheck const serializableForm: SerializableForm = { ...form, + settings: settings, fields: fieldsParsed.data, routes: routesParsed.data, createdAt: form.createdAt.toString(), diff --git a/packages/app-store/ee/routing-forms/pages/form-edit/[...appPages].tsx b/packages/app-store/ee/routing-forms/pages/form-edit/[...appPages].tsx index 29842e6dd8bf82..7586df8fb8806f 100644 --- a/packages/app-store/ee/routing-forms/pages/form-edit/[...appPages].tsx +++ b/packages/app-store/ee/routing-forms/pages/form-edit/[...appPages].tsx @@ -6,7 +6,12 @@ import { UseFormReturn } from "react-hook-form"; import { v4 as uuidv4 } from "uuid"; import classNames from "@calcom/lib/classNames"; -import { AppGetServerSidePropsContext, AppPrisma, AppUser } from "@calcom/types/AppGetServerSideProps"; +import { + AppGetServerSidePropsContext, + AppPrisma, + AppUser, + AppSsrInit, +} from "@calcom/types/AppGetServerSideProps"; import { Icon } from "@calcom/ui"; import { Button, EmptyScreen, SelectField, TextAreaField, TextField, Shell } from "@calcom/ui/v2"; import { BooleanToggleGroupField } from "@calcom/ui/v2/core/form/BooleanToggleGroup"; @@ -300,8 +305,10 @@ FormEditPage.getLayout = (page: React.ReactElement) => { export const getServerSideProps = async function getServerSideProps( context: AppGetServerSidePropsContext, prisma: AppPrisma, - user: AppUser + user: AppUser, + ssrInit: AppSsrInit ) { + const ssr = await ssrInit(context); if (!user) { return { redirect: { @@ -349,6 +356,8 @@ export const getServerSideProps = async function getServerSideProps( } return { props: { + trpcState: ssr.dehydrate(), + form: getSerializableForm(form), }, }; diff --git a/packages/app-store/ee/routing-forms/pages/route-builder/[...appPages].tsx b/packages/app-store/ee/routing-forms/pages/route-builder/[...appPages].tsx index e3c3bc0ef6aaa6..906e8635165b7e 100644 --- a/packages/app-store/ee/routing-forms/pages/route-builder/[...appPages].tsx +++ b/packages/app-store/ee/routing-forms/pages/route-builder/[...appPages].tsx @@ -6,7 +6,12 @@ import { Query, Config, Builder, Utils as QbUtils } from "react-awesome-query-bu import { JsonTree, ImmutableTree, BuilderProps } from "react-awesome-query-builder"; import { trpc } from "@calcom/trpc/react"; -import { AppGetServerSidePropsContext, AppPrisma, AppUser } from "@calcom/types/AppGetServerSideProps"; +import { + AppGetServerSidePropsContext, + AppPrisma, + AppUser, + AppSsrInit, +} from "@calcom/types/AppGetServerSideProps"; import { inferSSRProps } from "@calcom/types/inferSSRProps"; import { Icon } from "@calcom/ui"; import { Button, TextField, SelectWithValidation as Select, TextArea, Shell } from "@calcom/ui/v2"; @@ -463,8 +468,11 @@ RouteBuilder.getLayout = (page: React.ReactElement) => { export const getServerSideProps = async function getServerSideProps( context: AppGetServerSidePropsContext, prisma: AppPrisma, - user: AppUser + user: AppUser, + ssrInit: AppSsrInit ) { + const ssr = await ssrInit(context); + if (!user) { return { redirect: { @@ -513,6 +521,7 @@ export const getServerSideProps = async function getServerSideProps( return { props: { + trpcState: ssr.dehydrate(), form: getSerializableForm(form), }, }; diff --git a/packages/app-store/ee/routing-forms/trpc-router.ts b/packages/app-store/ee/routing-forms/trpc-router.ts index 4f88633e05f836..af454ab9a3f160 100644 --- a/packages/app-store/ee/routing-forms/trpc-router.ts +++ b/packages/app-store/ee/routing-forms/trpc-router.ts @@ -1,16 +1,77 @@ -import { Prisma, WebhookTriggerEvents } from "@prisma/client"; +import { App_RoutingForms_Form, Prisma, User, WebhookTriggerEvents } from "@prisma/client"; import { v4 as uuidv4 } from "uuid"; import { z } from "zod"; import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks"; import { sendGenericWebhookPayload } from "@calcom/features/webhooks/lib/sendPayload"; +import logger from "@calcom/lib/logger"; +import { RoutingFormSettings } from "@calcom/prisma/zod-utils"; import { TRPCError } from "@calcom/trpc/server"; import { createProtectedRouter, createRouter } from "@calcom/trpc/server/createRouter"; +import { Ensure } from "@calcom/types/utils"; +import ResponseEmail from "./emails/templates/response-email"; import { getSerializableForm } from "./lib/getSerializableForm"; import { isAllowed } from "./lib/isAllowed"; +import { Response, SerializableForm } from "./types/types"; import { zodFields, zodRoutes } from "./zod"; +async function onFormSubmission( + form: Ensure & { user: User }, "fields">, + response: Response +) { + const fieldResponsesByName: Record = {}; + + for (const [fieldId, fieldResponse] of Object.entries(response)) { + // Use the label lowercased as the key to identify a field. + const key = + form.fields.find((f) => f.id === fieldId)?.identifier || + (fieldResponse.label as keyof typeof fieldResponsesByName); + fieldResponsesByName[key] = fieldResponse.value; + } + + const subscriberOptions = { + userId: form.user.id, + // It isn't an eventType webhook + eventTypeId: -1, + triggerEvent: WebhookTriggerEvents.FORM_SUBMITTED, + }; + + const webhooks = await getWebhooks(subscriberOptions); + const promises = webhooks.map((webhook) => { + sendGenericWebhookPayload( + webhook.secret, + "FORM_SUBMITTED", + new Date().toISOString(), + webhook, + fieldResponsesByName + ).catch((e) => { + console.error(`Error executing routing form webhook`, webhook, e); + }); + }); + + await Promise.all(promises); + if (form.settings?.emailOwnerOnSubmission) { + logger.debug( + `Preparing to send Form Response email for Form:${form.id} to form owner: ${form.user.email}` + ); + await sendResponseEmail(form, response, form.user.email); + } +} + +const sendResponseEmail = async ( + form: Pick, + response: Response, + ownerEmail: string +) => { + try { + const email = new ResponseEmail({ form: form, toAddresses: [ownerEmail], response: response }); + await email.sendEmail(); + } catch (e) { + logger.error("Error sending response email", e); + } +}; + const app_RoutingForms = createRouter() .merge( "public.", @@ -41,24 +102,21 @@ const app_RoutingForms = createRouter() code: "NOT_FOUND", }); } - const fieldsParsed = zodFields.safeParse(form.fields); - if (!fieldsParsed.success) { - // This should not be possible normally as before saving the form it is verified by zod - throw new TRPCError({ - code: "INTERNAL_SERVER_ERROR", - }); - } - - const fields = fieldsParsed.data; - if (!fields) { + const serializableForm = getSerializableForm(form); + if (!serializableForm.fields) { // There is no point in submitting a form that doesn't have fields defined throw new TRPCError({ code: "BAD_REQUEST", }); } - const missingFields = fields + const serializableFormWithFields = { + ...serializableForm, + fields: serializableForm.fields, + }; + + const missingFields = serializableFormWithFields.fields .filter((field) => !(field.required ? response[field.id]?.value : true)) .map((f) => f.label); @@ -68,7 +126,7 @@ const app_RoutingForms = createRouter() message: `Missing required fields ${missingFields.join(", ")}`, }); } - const invalidFields = fields + const invalidFields = serializableFormWithFields.fields .filter((field) => { const fieldValue = response[field.id]?.value; // The field isn't required at this point. Validate only if it's set @@ -94,39 +152,12 @@ const app_RoutingForms = createRouter() }); } - const fieldResponsesByName: Record = {}; - - for (const [fieldId, fieldResponse] of Object.entries(response)) { - // Use the label lowercased as the key to identify a field. - const key = - fields.find((f) => f.id === fieldId)?.identifier || - (fieldResponse.label as keyof typeof fieldResponsesByName); - fieldResponsesByName[key] = fieldResponse.value; - } - - const subscriberOptions = { - userId: form.user.id, - // It isn't an eventType webhook - eventTypeId: -1, - triggerEvent: WebhookTriggerEvents.FORM_SUBMITTED, - }; - const webhooks = await getWebhooks(subscriberOptions); - const promises = webhooks.map((webhook) => { - sendGenericWebhookPayload( - webhook.secret, - "FORM_SUBMITTED", - new Date().toISOString(), - webhook, - fieldResponsesByName - ).catch((e) => { - console.error(`Error executing routing form webhook`, webhook, e); - }); - }); - await Promise.all(promises); - - return await prisma.app_RoutingForms_FormResponse.create({ + const dbFormResponse = await prisma.app_RoutingForms_FormResponse.create({ data: input, }); + + await onFormSubmission(serializableFormWithFields, dbFormResponse.response as Response); + return dbFormResponse; } catch (e) { if (e instanceof Prisma.PrismaClientKnownRequestError) { if (e.code === "P2002") { @@ -201,9 +232,10 @@ const app_RoutingForms = createRouter() routes: zodRoutes, addFallback: z.boolean().optional(), duplicateFrom: z.string().nullable().optional(), + settings: RoutingFormSettings.optional(), }), async resolve({ ctx: { user, prisma }, input }) { - const { name, id, description, disabled, addFallback, duplicateFrom } = input; + const { name, id, description, settings, disabled, addFallback, duplicateFrom } = input; if (!(await isAllowed({ userId: user.id, formId: id }))) { throw new TRPCError({ code: "FORBIDDEN", @@ -284,6 +316,7 @@ const app_RoutingForms = createRouter() fields: fields, name: name, description, + settings: settings === null ? Prisma.JsonNull : settings, routes: routes === null ? Prisma.JsonNull : routes, }, }); diff --git a/packages/app-store/ee/routing-forms/types/types.d.ts b/packages/app-store/ee/routing-forms/types/types.d.ts index 21f8b1b04220a7..33b97c8cb75de1 100644 --- a/packages/app-store/ee/routing-forms/types/types.d.ts +++ b/packages/app-store/ee/routing-forms/types/types.d.ts @@ -1,6 +1,8 @@ import { App_RoutingForms_Form } from "@prisma/client"; import z from "zod"; +import { RoutingFormSettings } from "@calcom/prisma/zod-utils"; + import { zodFields, zodRoutes } from "../zod"; export type Response = Record< @@ -17,10 +19,11 @@ export type Routes = z.infer; export type Route = Routes[0]; export type SerializableForm = Omit< T, - "fields" | "routes" | "createdAt" | "updatedAt" + "fields" | "routes" | "createdAt" | "updatedAt" | "settings" > & { routes: Routes; fields: Fields; + settings: z.infer; createdAt: string; updatedAt: string; }; diff --git a/packages/core/getUserAvailability.ts b/packages/core/getUserAvailability.ts index 0c084f32a2bee9..bfeeb0171f9af4 100644 --- a/packages/core/getUserAvailability.ts +++ b/packages/core/getUserAvailability.ts @@ -9,7 +9,7 @@ import logger from "@calcom/lib/logger"; import { checkLimit } from "@calcom/lib/server"; import { performance } from "@calcom/lib/server/perfObserver"; import prisma, { availabilityUserSelect } from "@calcom/prisma"; -import { stringToDayjs } from "@calcom/prisma/zod-utils"; +import { EventTypeMetaDataSchema, stringToDayjs } from "@calcom/prisma/zod-utils"; import { BookingLimit, EventBusyDetails } from "@calcom/types/Calendar"; import { getBusyTimes } from "./getBusyTimes"; @@ -27,14 +27,15 @@ const availabilitySchema = z }) .refine((data) => !!data.username || !!data.userId, "Either username or userId should be filled in."); -const getEventType = (id: number) => - prisma.eventType.findUnique({ +const getEventType = async (id: number) => { + const eventType = await prisma.eventType.findUnique({ where: { id }, select: { id: true, seatsPerTimeSlot: true, bookingLimits: true, timeZone: true, + metadata: true, schedule: { select: { availability: true, @@ -50,6 +51,14 @@ const getEventType = (id: number) => }, }, }); + if (!eventType) { + return eventType; + } + return { + ...eventType, + metadata: EventTypeMetaDataSchema.parse(eventType.metadata), + }; +}; type EventType = Awaited>; @@ -200,13 +209,15 @@ export async function getUserAvailability( }); } } - const schedule = eventType?.schedule - ? { ...eventType?.schedule } - : { - ...currentUser.schedules.filter( - (schedule) => !currentUser.defaultScheduleId || schedule.id === currentUser.defaultScheduleId - )[0], - }; + + const schedule = + !eventType?.metadata?.config?.useHostSchedulesForTeamEvent && eventType?.schedule + ? { ...eventType?.schedule } + : { + ...currentUser.schedules.filter( + (schedule) => !currentUser.defaultScheduleId || schedule.id === currentUser.defaultScheduleId + )[0], + }; const startGetWorkingHours = performance.now(); diff --git a/packages/emails/src/templates/index.ts b/packages/emails/src/templates/index.ts index b1682fc23fb734..ee8fe10b195466 100644 --- a/packages/emails/src/templates/index.ts +++ b/packages/emails/src/templates/index.ts @@ -18,3 +18,4 @@ export { OrganizerRescheduledEmail } from "./OrganizerRescheduledEmail"; export { OrganizerScheduledEmail } from "./OrganizerScheduledEmail"; export { TeamInviteEmail } from "./TeamInviteEmail"; export { BrokenIntegrationEmail } from "./BrokenIntegrationEmail"; +export * from "@calcom/app-store/ee/routing-forms/emails/components"; diff --git a/packages/prisma/migrations/20221028093727_add_routing_form_settings/migration.sql b/packages/prisma/migrations/20221028093727_add_routing_form_settings/migration.sql new file mode 100644 index 00000000000000..c74a622a06cceb --- /dev/null +++ b/packages/prisma/migrations/20221028093727_add_routing_form_settings/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "App_RoutingForms_Form" ADD COLUMN "settings" JSONB; diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index a7e08e718045bf..8c96334d967b28 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -518,6 +518,8 @@ model App_RoutingForms_Form { userId Int responses App_RoutingForms_FormResponse[] disabled Boolean @default(false) + /// @zod.custom(imports.RoutingFormSettings) + settings Json? } model App_RoutingForms_FormResponse { diff --git a/packages/prisma/zod-utils.ts b/packages/prisma/zod-utils.ts index 3444ce490b9046..fe4bd8ccc67438 100644 --- a/packages/prisma/zod-utils.ts +++ b/packages/prisma/zod-utils.ts @@ -32,6 +32,11 @@ export const EventTypeMetaDataSchema = z giphyThankYouPage: z.string().optional(), apps: z.object(appDataSchemas).partial().optional(), additionalNotesRequired: z.boolean().optional(), + config: z + .object({ + useHostSchedulesForTeamEvent: z.boolean().optional(), + }) + .optional(), }) .nullable(); @@ -208,6 +213,12 @@ export const successRedirectUrl = z ]) .optional(); +export const RoutingFormSettings = z + .object({ + emailOwnerOnSubmission: z.boolean(), + }) + .nullable(); + export type ZodDenullish = T extends ZodNullable | ZodOptional ? ZodDenullish : T; diff --git a/packages/trpc/server/routers/viewer/slots.tsx b/packages/trpc/server/routers/viewer/slots.tsx index 72939da7f0cf28..9723ee8fa56bf8 100644 --- a/packages/trpc/server/routers/viewer/slots.tsx +++ b/packages/trpc/server/routers/viewer/slots.tsx @@ -11,6 +11,7 @@ import logger from "@calcom/lib/logger"; import { performance } from "@calcom/lib/server/perfObserver"; import getTimeSlots from "@calcom/lib/slots"; import prisma, { availabilityUserSelect } from "@calcom/prisma"; +import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils"; import { EventBusyDate } from "@calcom/types/Calendar"; import { TimeRange } from "@calcom/types/schedule"; @@ -104,7 +105,7 @@ export const slotsRouter = createRouter().query("getSchedule", { }); async function getEventType(ctx: { prisma: typeof prisma }, input: z.infer) { - return ctx.prisma.eventType.findUnique({ + const eventType = await ctx.prisma.eventType.findUnique({ where: { id: input.eventTypeId, }, @@ -124,6 +125,7 @@ async function getEventType(ctx: { prisma: typeof prisma }, input: z.infer) { diff --git a/packages/types/AppGetServerSideProps.d.ts b/packages/types/AppGetServerSideProps.d.ts index e2f1d5ee7cbec3..0a31b856d0fbbb 100644 --- a/packages/types/AppGetServerSideProps.d.ts +++ b/packages/types/AppGetServerSideProps.d.ts @@ -3,14 +3,17 @@ import { CalendsoSessionUser } from "next-auth"; import prisma from "@calcom/prisma"; +import type { ssrInit } from "@server/lib/ssr"; + export type AppUser = CalendsoSessionUser | undefined; export type AppPrisma = typeof prisma; export type AppGetServerSidePropsContext = GetServerSidePropsContext<{ appPages: string[]; }>; - +export type AppSsrInit = ssrInit; export type AppGetServerSideProps = ( context: AppGetServerSidePropsContext, prisma: AppPrisma, - user: AppUser + user: AppUser, + ssrInit: AppSsrInit ) => GetServerSidePropsResult; diff --git a/packages/ui/v2/core/SettingsToggle.tsx b/packages/ui/v2/core/SettingsToggle.tsx index a81d873bc53920..0778e5c4750035 100644 --- a/packages/ui/v2/core/SettingsToggle.tsx +++ b/packages/ui/v2/core/SettingsToggle.tsx @@ -44,8 +44,8 @@ function SettingsToggle({ {children && ( -
- {checked && children} +
+ {checked &&
{children}
}
)}