import { Dispatch, SetStateAction, useEffect, useState, FC } from "react"; import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; import { Controller, useForm } from "react-hook-form"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; // services import { WorkspaceService } from "services/workspace.service"; // hooks import useToast from "hooks/use-toast"; // ui import { Button, CustomSelect, Input } from "@plane/ui"; // types import { IWorkspace } from "types"; // constants import { ORGANIZATION_SIZE, RESTRICTED_URLS } from "constants/workspace"; type Props = { onSubmit?: (res: IWorkspace) => Promise; defaultValues: { name: string; slug: string; organization_size: string; }; setDefaultValues: Dispatch>; secondaryButton?: React.ReactNode; primaryButtonText?: { loading: string; default: string; }; }; const workspaceService = new WorkspaceService(); export const CreateWorkspaceForm: FC = observer((props) => { const { onSubmit, defaultValues, setDefaultValues, secondaryButton, primaryButtonText = { loading: "Creating...", default: "Create Workspace", }, } = props; const [slugError, setSlugError] = useState(false); const [invalidSlug, setInvalidSlug] = useState(false); const router = useRouter(); const { workspace: workspaceStore, trackEvent: { postHogEventTracker } } = useMobxStore(); const { setToastAlert } = useToast(); const { handleSubmit, control, setValue, getValues, formState: { errors, isSubmitting, isValid }, } = useForm({ defaultValues, mode: "onChange" }); const handleCreateWorkspace = async (formData: IWorkspace) => { await workspaceService .workspaceSlugCheck(formData.slug) .then(async (res) => { if (res.status === true && !RESTRICTED_URLS.includes(formData.slug)) { setSlugError(false); await workspaceStore .createWorkspace(formData) .then(async (res) => { postHogEventTracker( "WORKSPACE_CREATED", { ...res, state: "SUCCESS" }, ) setToastAlert({ type: "success", title: "Success!", message: "Workspace created successfully.", }); if (onSubmit) await onSubmit(res); }) .catch(() => { setToastAlert({ type: "error", title: "Error!", message: "Workspace could not be created. Please try again.", }) postHogEventTracker( "WORKSPACE_CREATED", { state: "FAILED" }, ) } ); } else setSlugError(true); }) .catch(() => { setToastAlert({ type: "error", title: "Error!", message: "Some error occurred while creating workspace. Please try again.", }); postHogEventTracker( "WORKSPACE_CREATED", { state: "FAILED" }, ) }); }; useEffect( () => () => { // when the component unmounts set the default values to whatever user typed in setDefaultValues(getValues()); }, [getValues, setDefaultValues] ); return (
/^[\w\s-]*$/.test(value) || `Name can only contain (" "), ( - ), ( _ ) & alphanumeric characters.`, maxLength: { value: 80, message: "Workspace name should not exceed 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, "-")); }} ref={ref} hasError={Boolean(errors.name)} placeholder="Enter workspace name..." className="w-full" /> )} />
{window && window.location.host}/ ( { /^[a-zA-Z0-9_-]+$/.test(e.target.value) ? setInvalidSlug(false) : setInvalidSlug(true); onChange(e.target.value.toLowerCase()); }} ref={ref} hasError={Boolean(errors.slug)} placeholder="Enter workspace url..." className="block rounded-md bg-transparent py-2 !px-0 text-sm w-full border-none" /> )} />
{slugError && Workspace URL is already taken!} {invalidSlug && ( {`URL can only contain ( - ), ( _ ) & alphanumeric characters.`} )}
What size is your organization?
( c === value) ?? ( Select organization size ) } buttonClassName="!border-[0.5px] !border-custom-border-200 !shadow-none" input width="w-full" > {ORGANIZATION_SIZE.map((item) => ( {item} ))} )} /> {errors.organization_size && ( {errors.organization_size.message} )}
{secondaryButton} {!secondaryButton && ( )}
); });