"use client"; import { useRef, useState } from "react"; import { useNavigation } from "../navigation"; import { useImmersiveMode } from "../platform"; import { toast } from "sonner"; import { ArrowLeft } from "lucide-react"; import { Input } from "@multica/ui/components/ui/input"; import { Label } from "@multica/ui/components/ui/label"; import { Button } from "@multica/ui/components/ui/button"; import { Dialog, DialogContent, DialogTitle, DialogDescription, } from "@multica/ui/components/ui/dialog"; import { Card, CardContent } from "@multica/ui/components/ui/card"; import { useCreateWorkspace } from "@multica/core/workspace/mutations"; import { WORKSPACE_SLUG_CONFLICT_ERROR, WORKSPACE_SLUG_FORMAT_ERROR, WORKSPACE_SLUG_REGEX, isWorkspaceSlugConflict, nameToWorkspaceSlug, } from "../workspace/slug"; export function CreateWorkspaceModal({ onClose }: { onClose: () => void }) { // This modal is full-screen, so it covers the app titlebar. On macOS desktop // we hide the traffic lights for its lifetime so the Back button in the top- // left corner isn't stolen by the native controls' hit-test. No-op elsewhere. useImmersiveMode(); const router = useNavigation(); const createWorkspace = useCreateWorkspace(); const [name, setName] = useState(""); const [slug, setSlug] = useState(""); const [slugServerError, setSlugServerError] = useState(null); const slugTouched = useRef(false); const slugValidationError = slug.length > 0 && !WORKSPACE_SLUG_REGEX.test(slug) ? WORKSPACE_SLUG_FORMAT_ERROR : null; const slugError = slugValidationError ?? slugServerError; const canSubmit = name.trim().length > 0 && slug.trim().length > 0 && !slugError; const handleNameChange = (value: string) => { setName(value); if (!slugTouched.current) { setSlug(nameToWorkspaceSlug(value)); setSlugServerError(null); } }; const handleSlugChange = (value: string) => { slugTouched.current = true; setSlug(value); setSlugServerError(null); }; const handleCreate = () => { if (!canSubmit) return; createWorkspace.mutate( { name: name.trim(), slug: slug.trim() }, { onSuccess: () => { onClose(); router.push("/onboarding"); }, onError: (error) => { if (isWorkspaceSlugConflict(error)) { setSlugServerError(WORKSPACE_SLUG_CONFLICT_ERROR); toast.error("Choose a different workspace URL"); return; } toast.error("Failed to create workspace"); }, }, ); }; return ( { if (!v) onClose(); }} > {/* Top drag region — restores window-drag ability that the full-screen modal would otherwise swallow. Transparent; web browsers ignore the -webkit-app-region property, so this is safe cross-platform. */}
Create a new workspace Workspaces are shared environments where teams can work on projects and issues.
handleNameChange(e.target.value)} placeholder="My Workspace" />
multica.ai/ handleSlugChange(e.target.value)} placeholder="my-workspace" className="border-0 shadow-none focus-visible:ring-0" onKeyDown={(e) => e.key === "Enter" && handleCreate()} />
{slugError && (

{slugError}

)}
); }