File
Blob: src/client/hooks/use-create-workspace.ts
| 1 | import { useState, useCallback, useRef } from "react"; |
| 2 | import { useNavigate } from "@tanstack/react-router"; |
| 3 | import { api } from "@/client/lib/api"; |
| 4 | import { directoryCommands } from "@/client/stores/db/workspace-directory"; |
| 5 | import { toast } from "@/client/components/toast-store"; |
| 6 | |
| 7 | export function useCreateWorkspace() { |
| 8 | const [isCreating, setIsCreating] = useState(false); |
| 9 | const busyRef = useRef(false); |
| 10 | const navigate = useNavigate(); |
| 11 | |
| 12 | const createWorkspace = useCallback( |
| 13 | async (name: string, slug: string, onCreated?: () => void) => { |
| 14 | if (!name.trim() || !slug.trim() || busyRef.current) return; |
| 15 | busyRef.current = true; |
| 16 | setIsCreating(true); |
| 17 | try { |
| 18 | const ws = await api.workspaces.create({ name: name.trim(), slug: slug.trim() }); |
| 19 | // POST /workspaces makes the caller the owner, so inject that into the |
| 20 | // membership summary we cache locally. |
| 21 | await directoryCommands.upsert({ ...ws, role: "owner" }); |
| 22 | onCreated?.(); |
| 23 | navigate({ to: "/$workspaceSlug", params: { workspaceSlug: ws.slug } }); |
| 24 | } catch { |
| 25 | toast.error("Failed to create workspace"); |
| 26 | } finally { |
| 27 | busyRef.current = false; |
| 28 | setIsCreating(false); |
| 29 | } |
| 30 | }, |
| 31 | [navigate], |
| 32 | ); |
| 33 | |
| 34 | return { createWorkspace, isCreating }; |
| 35 | } |