diff --git a/packages/features/ee/teams/components/CreateANewTeamForm.tsx b/packages/features/ee/teams/components/CreateANewTeamForm.tsx index 6ca3e2ebc8..1dc42a91a7 100644 --- a/packages/features/ee/teams/components/CreateANewTeamForm.tsx +++ b/packages/features/ee/teams/components/CreateANewTeamForm.tsx @@ -1,4 +1,5 @@ import { useRouter } from "next/router"; +import { useState } from "react"; import { Controller, useForm } from "react-hook-form"; import { z } from "zod"; @@ -7,7 +8,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale"; import slugify from "@calcom/lib/slugify"; import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry"; import { trpc } from "@calcom/trpc/react"; -import { Avatar, Button, Form, ImageUploader, TextField } from "@calcom/ui"; +import { Avatar, Button, Form, ImageUploader, TextField, Alert } from "@calcom/ui"; import { FiArrowRight } from "@calcom/ui/components/icon"; import type { NewTeamFormValues } from "../lib/types"; @@ -21,6 +22,7 @@ export const CreateANewTeamForm = () => { const router = useRouter(); const telemetry = useTelemetry(); const returnToParsed = querySchema.safeParse(router.query); + const [serverErrorMessage, setServerErrorMessage] = useState(null); const returnToParam = (returnToParsed.success ? getSafeRedirectUrl(returnToParsed.data.returnTo) : "/settings/teams") || @@ -33,29 +35,32 @@ export const CreateANewTeamForm = () => { telemetry.event(telemetryEventTypes.team_created); router.push(`/settings/teams/${data.id}/onboard-members`); }, + onError: (err) => { + if (err.message === "team_url_taken") { + newTeamFormMethods.setError("slug", { type: "custom", message: t("team_url_taken") }); + } else { + setServerErrorMessage(err.message); + } + }, }); - const validateTeamSlugQuery = trpc.viewer.teams.validateTeamSlug.useQuery( - { slug: newTeamFormMethods.watch("slug") }, - { - enabled: false, - refetchOnWindowFocus: false, - } - ); - - const validateTeamSlug = async () => { - await validateTeamSlugQuery.refetch(); - if (validateTeamSlugQuery.isFetched) return validateTeamSlugQuery.data || t("team_url_taken"); - }; - return ( <>
{ - if (!createTeamMutation.isLoading) createTeamMutation.mutate(v); + if (!createTeamMutation.isLoading) { + setServerErrorMessage(null); + createTeamMutation.mutate(v); + } }}>
+ {serverErrorMessage && ( +
+ +
+ )} + { if (newTeamFormMethods.formState.touchedFields["slug"] === undefined) { newTeamFormMethods.setValue("slug", slugify(e?.target.value)); } - createTeamMutation.reset(); }} autoComplete="off" /> @@ -88,7 +92,7 @@ export const CreateANewTeamForm = () => { await validateTeamSlug() }} + rules={{ required: t("team_url_required") }} render={({ field: { value } }) => ( { newTeamFormMethods.setValue("slug", slugify(e?.target.value), { shouldTouch: true, }); - createTeamMutation.reset(); + newTeamFormMethods.clearErrors("slug"); }} /> )} @@ -143,11 +147,7 @@ export const CreateANewTeamForm = () => { {t("cancel")}
- {createTeamMutation.isError && ( -

{createTeamMutation.error.message}

- )}
); diff --git a/packages/trpc/server/routers/viewer/teams.tsx b/packages/trpc/server/routers/viewer/teams.tsx index 59650c00a8..7e9c6ac67b 100644 --- a/packages/trpc/server/routers/viewer/teams.tsx +++ b/packages/trpc/server/routers/viewer/teams.tsx @@ -85,13 +85,13 @@ export const viewerTeamsRouter = router({ .mutation(async ({ ctx, input }) => { const { slug, name, logo } = input; - const nameCollisions = await ctx.prisma.team.findFirst({ + const slugCollisions = await ctx.prisma.team.findFirst({ where: { slug: slug, }, }); - if (nameCollisions) throw new TRPCError({ code: "BAD_REQUEST", message: "Team name already taken." }); + if (slugCollisions) throw new TRPCError({ code: "BAD_REQUEST", message: "team_url_taken" }); // Ensure that the user is not duplicating a requested team const duplicatedRequest = await ctx.prisma.team.findFirst({ @@ -587,21 +587,6 @@ export const viewerTeamsRouter = router({ }, }); }), - validateTeamSlug: authedProcedure - .input( - z.object({ - slug: z.string(), - }) - ) - .query(async ({ ctx, input }) => { - const team = await ctx.prisma.team.findFirst({ - where: { - slug: input.slug, - }, - }); - - return !team; - }), publish: authedProcedure .input( z.object({