File
Blob: src/client/hooks/use-create-page.ts
| 1 | import { useState, useCallback, useRef } from "react"; |
| 2 | import { useNavigate } from "@tanstack/react-router"; |
| 3 | import type { Page, PageKind } from "@/shared/types"; |
| 4 | import { DEFAULT_PAGE_TITLE } from "@/shared/constants"; |
| 5 | import { api } from "@/client/lib/api"; |
| 6 | import { useCurrentWorkspace } from "@/client/components/workspace/use-workspace-view"; |
| 7 | import { replicaCommands } from "@/client/stores/db/workspace-replica"; |
| 8 | import { useOnline } from "@/client/hooks/use-online"; |
| 9 | import { toast } from "@/client/components/toast-store"; |
| 10 | |
| 11 | export function useCreatePage() { |
| 12 | const [isCreating, setIsCreating] = useState(false); |
| 13 | const busyRef = useRef(false); |
| 14 | const workspace = useCurrentWorkspace(); |
| 15 | const navigate = useNavigate(); |
| 16 | const online = useOnline(); |
| 17 | |
| 18 | const createPage = useCallback( |
| 19 | async (opts?: { kind?: PageKind; parentId?: string; onCreated?: (page: Page) => void }) => { |
| 20 | if (!workspace || busyRef.current) return; |
| 21 | if (!online) { |
| 22 | toast.info("You're offline"); |
| 23 | return; |
| 24 | } |
| 25 | busyRef.current = true; |
| 26 | setIsCreating(true); |
| 27 | try { |
| 28 | const page = await api.pages.create(workspace.id, { |
| 29 | kind: opts?.kind, |
| 30 | title: DEFAULT_PAGE_TITLE, |
| 31 | parent_id: opts?.parentId, |
| 32 | }); |
| 33 | await replicaCommands.addPage(workspace.id, page); |
| 34 | opts?.onCreated?.(page); |
| 35 | navigate({ |
| 36 | to: "/$workspaceSlug/$pageId", |
| 37 | params: { workspaceSlug: workspace.slug, pageId: page.id }, |
| 38 | }); |
| 39 | } catch { |
| 40 | toast.error("Failed to create page"); |
| 41 | } finally { |
| 42 | busyRef.current = false; |
| 43 | setIsCreating(false); |
| 44 | } |
| 45 | }, |
| 46 | [workspace, navigate, online], |
| 47 | ); |
| 48 | |
| 49 | return { createPage, isCreating }; |
| 50 | } |