import { useState, useEffect } from "react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { Controller, useForm } from "react-hook-form"; // plane imports import { WEB_BASE_URL, ORGANIZATION_SIZE, RESTRICTED_URLS } from "@plane/constants"; import { InstanceWorkspaceService } from "@plane/services"; import { IWorkspace } from "@plane/types"; // components import { Button, CustomSelect, getButtonStyling, Input, setToast, TOAST_TYPE } from "@plane/ui"; // hooks import { useWorkspace } from "@/hooks/store"; const instanceWorkspaceService = new InstanceWorkspaceService(); export const WorkspaceCreateForm = () => { // router const router = useRouter(); // states const [slugError, setSlugError] = useState(false); const [invalidSlug, setInvalidSlug] = useState(false); const [defaultValues, setDefaultValues] = useState>({ name: "", slug: "", organization_size: "", }); // store hooks const { createWorkspace } = useWorkspace(); // form info const { handleSubmit, control, setValue, getValues, formState: { errors, isSubmitting, isValid }, } = useForm({ defaultValues, mode: "onChange" }); // derived values const workspaceBaseURL = encodeURI(WEB_BASE_URL || window.location.origin + "/"); const handleCreateWorkspace = async (formData: IWorkspace) => { await instanceWorkspaceService .slugCheck(formData.slug) .then(async (res) => { if (res.status === true && !RESTRICTED_URLS.includes(formData.slug)) { setSlugError(false); await createWorkspace(formData) .then(async () => { setToast({ type: TOAST_TYPE.SUCCESS, title: "Success!", message: "Workspace created successfully.", }); router.push(`/workspace`); }) .catch(() => { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", message: "Workspace could not be created. Please try again.", }); }); } else setSlugError(true); }) .catch(() => { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", message: "Some error occurred while creating workspace. Please try again.", }); }); }; useEffect( () => () => { // when the component unmounts set the default values to whatever user typed in setDefaultValues(getValues()); }, [getValues, setDefaultValues] ); return (

Name your workspace

/^[\w\s-]*$/.test(value) || `Workspaces names can contain only (" "), ( - ), ( _ ) and alphanumeric characters.`, maxLength: { value: 80, message: "Limit your name to 80 characters.", }, }} render={({ field: { value, ref, onChange } }) => ( { onChange(e.target.value); setValue("name", e.target.value); setValue("slug", e.target.value.toLocaleLowerCase().trim().replace(/ /g, "-"), { shouldValidate: true, }); }} ref={ref} hasError={Boolean(errors.name)} placeholder="Something familiar and recognizable is always best." className="w-full" /> )} /> {errors?.name?.message}

Set your workspace's URL

{workspaceBaseURL} ( { if (/^[a-zA-Z0-9_-]+$/.test(e.target.value)) setInvalidSlug(false); else setInvalidSlug(true); onChange(e.target.value.toLowerCase()); }} ref={ref} hasError={Boolean(errors.slug)} placeholder="workspace-name" className="block w-full rounded-md border-none bg-transparent !px-0 py-2 text-sm" /> )} />
{slugError &&

This URL is taken. Try something else.

} {invalidSlug && (

{`URLs can contain only ( - ), ( _ ) and alphanumeric characters.`}

)} {errors.slug && {errors.slug.message}}

How many people will use this workspace?

( c === value) ?? ( Select a range ) } buttonClassName="!border-[0.5px] !border-custom-border-200 !shadow-none" input optionsClassName="w-full" > {ORGANIZATION_SIZE.map((item) => ( {item} ))} )} /> {errors.organization_size && ( {errors.organization_size.message} )}
Go back
); };