import { zodResolver } from "@hookform/resolvers/zod"; import { t } from "@lingui/core/macro"; import { env } from "next-runtime-env"; import { useForm } from "react-hook-form"; import { HiCheck, HiMiniStar } from "react-icons/hi2"; import { z } from "zod"; import Button from "~/components/Button"; import Input from "~/components/Input"; import { useDebounce } from "~/hooks/useDebounce"; import { useModal } from "~/providers/modal"; import { usePopup } from "~/providers/popup"; import { api } from "~/utils/api"; const UpdateWorkspaceUrlForm = ({ workspacePublicId, workspaceUrl, workspacePlan, }: { workspacePublicId: string; workspaceUrl: string; workspacePlan: "free" | "pro" | "enterprise"; }) => { const utils = api.useUtils(); const { showPopup } = usePopup(); const { openModal } = useModal(); const schema = z.object({ slug: z .string() .min(3, { message: t`URL must be at least 3 characters long`, }) .max(24, { message: t`URL cannot exceed 24 characters` }) .regex(/^(?![-]+$)[a-zA-Z0-9-]+$/, { message: t`URL can only contain letters, numbers, and hyphens`, }), }); type FormValues = z.infer; const { register, handleSubmit, formState: { isDirty, errors }, watch, } = useForm({ resolver: zodResolver(schema), values: { slug: workspaceUrl, }, mode: "onChange", }); const slug = watch("slug"); const updateWorkspaceSlug = api.workspace.update.useMutation({ onSuccess: async () => { showPopup({ header: t`Workspace slug updated`, message: t`Your workspace slug has been updated.`, icon: "success", }); try { await utils.workspace.all.refetch(); } catch (e) { console.error(e); throw e; } }, onError: () => { showPopup({ header: t`Error updating workspace URL`, message: t`Please try again later, or contact customer support.`, icon: "error", }); }, }); const [debouncedSlug] = useDebounce(slug, 500); const isTyping = slug !== debouncedSlug; const checkWorkspaceSlugAvailability = api.workspace.checkSlugAvailability.useQuery( { workspaceSlug: debouncedSlug, }, { enabled: !!debouncedSlug && debouncedSlug !== workspaceUrl && !errors.slug, }, ); const isWorkspaceSlugAvailable = checkWorkspaceSlugAvailability.data; const onSubmit = (data: FormValues) => { if (!isWorkspaceSlugAvailable?.isAvailable) return; if (workspacePlan !== "pro" && env("NEXT_PUBLIC_KAN_ENV") === "cloud") return openModal("UPDATE_WORKSPACE_URL", data.slug); updateWorkspaceSlug.mutate({ workspacePublicId, slug: data.slug, }); }; return (
) : isWorkspaceSlugAvailable?.isAvailable ? ( ) : null } />
); }; export default UpdateWorkspaceUrlForm;