diff --git a/packages/features/eventtypes/components/DuplicateDialog.tsx b/packages/features/eventtypes/components/DuplicateDialog.tsx index 35e37b5eda..25873bd648 100644 --- a/packages/features/eventtypes/components/DuplicateDialog.tsx +++ b/packages/features/eventtypes/components/DuplicateDialog.tsx @@ -43,12 +43,12 @@ const DuplicateDialog = () => { showToast(message, "error"); } - if (err.data?.code === "BAD_REQUEST") { - const message = `${err.data.code}: URL already exists.`; + if (err.data?.code === "INTERNAL_SERVER_ERROR" || err.data?.code === "BAD_REQUEST") { + const message = t("unexpected_error_try_again"); showToast(message, "error"); } - if (err.data?.code === "UNAUTHORIZED") { + if (err.data?.code === "UNAUTHORIZED" || err.data?.code === "FORBIDDEN") { const message = `${err.data.code}: You are not able to create this event`; showToast(message, "error"); } diff --git a/packages/trpc/server/routers/viewer/eventTypes.tsx b/packages/trpc/server/routers/viewer/eventTypes.tsx index 7068af435c..9f83d62e60 100644 --- a/packages/trpc/server/routers/viewer/eventTypes.tsx +++ b/packages/trpc/server/routers/viewer/eventTypes.tsx @@ -622,111 +622,114 @@ export const eventTypesRouter = router({ }; }), duplicate: eventOwnerProcedure.input(EventTypeDuplicateInput.strict()).mutation(async ({ ctx, input }) => { - const { id: originalEventTypeId, title: newEventTitle, slug: newSlug } = input; - const eventType = await ctx.prisma.eventType.findUnique({ - where: { - id: originalEventTypeId, - }, - include: { - customInputs: true, - schedule: true, - users: true, - team: true, - workflows: true, - webhooks: true, - }, - }); + try { + const { id: originalEventTypeId, title: newEventTitle, slug: newSlug } = input; + const eventType = await ctx.prisma.eventType.findUnique({ + where: { + id: originalEventTypeId, + }, + include: { + customInputs: true, + schedule: true, + users: true, + team: true, + workflows: true, + webhooks: true, + }, + }); - if (!eventType) { - throw new TRPCError({ code: "NOT_FOUND" }); - } + if (!eventType) { + throw new TRPCError({ code: "NOT_FOUND" }); + } - // Validate user is owner of event type or in the team - if (eventType.userId !== ctx.user.id) { - if (eventType.teamId) { - const isMember = await ctx.prisma.membership.findFirst({ - where: { - userId: ctx.user.id, - teamId: eventType.teamId, - }, - }); - if (!isMember) { - throw new TRPCError({ code: "FORBIDDEN" }); + // Validate user is owner of event type or in the team + if (eventType.userId !== ctx.user.id) { + if (eventType.teamId) { + const isMember = await ctx.prisma.membership.findFirst({ + where: { + userId: ctx.user.id, + teamId: eventType.teamId, + }, + }); + if (!isMember) { + throw new TRPCError({ code: "FORBIDDEN" }); + } } } - throw new TRPCError({ code: "FORBIDDEN" }); - } - const { - customInputs, - users, - locations, - team, - recurringEvent, - bookingLimits, - metadata, - workflows, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - id: _id, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - webhooks: _webhooks, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - schedule: _schedule, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - not typed correctly as its set on SSR - descriptionAsSafeHTML: _descriptionAsSafeHTML, - ...rest - } = eventType; + const { + customInputs, + users, + locations, + team, + recurringEvent, + bookingLimits, + metadata, + workflows, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + id: _id, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + webhooks: _webhooks, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + schedule: _schedule, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - not typed correctly as its set on SSR + descriptionAsSafeHTML: _descriptionAsSafeHTML, + ...rest + } = eventType; - const data: Prisma.EventTypeCreateInput = { - ...rest, - title: newEventTitle, - slug: newSlug, - locations: locations ?? undefined, - team: team ? { connect: { id: team.id } } : undefined, - users: users ? { connect: users.map((user) => ({ id: user.id })) } : undefined, - recurringEvent: recurringEvent || undefined, - bookingLimits: bookingLimits ?? undefined, - metadata: metadata === null ? Prisma.DbNull : metadata, - }; - - const newEventType = await ctx.prisma.eventType.create({ data }); - - // Create custom inputs - if (customInputs) { - const customInputsData = customInputs.map((customInput) => { - const { id: _, options, ...rest } = customInput; - return { - options: options ?? undefined, - ...rest, - eventTypeId: newEventType.id, - }; - }); - await ctx.prisma.eventTypeCustomInput.createMany({ - data: customInputsData, - }); - } - - if (workflows.length > 0) { - const workflowIds = workflows.map((workflow) => { - return { id: workflow.workflowId }; - }); - - const eventUpdateData: Prisma.EventTypeUpdateInput = { - workflows: { - connect: workflowIds, - }, + const data: Prisma.EventTypeUncheckedCreateInput = { + ...rest, + title: newEventTitle, + slug: newSlug, + locations: locations ?? undefined, + teamId: team ? team.id : undefined, + users: users ? { connect: users.map((user) => ({ id: user.id })) } : undefined, + recurringEvent: recurringEvent || undefined, + bookingLimits: bookingLimits ?? undefined, + metadata: metadata === null ? Prisma.DbNull : metadata, }; - await ctx.prisma.eventType.update({ - where: { - id: newEventType.id, - }, - data: eventUpdateData, - }); - } - return { - eventType: newEventType, - }; + const newEventType = await ctx.prisma.eventType.create({ data }); + + // Create custom inputs + if (customInputs) { + const customInputsData = customInputs.map((customInput) => { + const { id: _, options, ...rest } = customInput; + return { + options: options ?? undefined, + ...rest, + eventTypeId: newEventType.id, + }; + }); + await ctx.prisma.eventTypeCustomInput.createMany({ + data: customInputsData, + }); + } + + if (workflows.length > 0) { + const workflowIds = workflows.map((workflow) => { + return { id: workflow.workflowId }; + }); + + const eventUpdateData: Prisma.EventTypeUpdateInput = { + workflows: { + connect: workflowIds, + }, + }; + await ctx.prisma.eventType.update({ + where: { + id: newEventType.id, + }, + data: eventUpdateData, + }); + } + + return { + eventType: newEventType, + }; + } catch (error) { + throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" }); + } }), });