"use client"; /** * CreateDialog — "New" menu: create a page or a database. * * - Page: POST /workspaces/:id/pages (useCreatePage), navigate to the new * page (/w/:slug/page/:id). * - Database: POST /databases (useCreateDatabase) with a title (+ optional * icon); the database is linked to a page automatically by the API. When * opened from a page (pageId given), the database block is embedded into * that page (the core insert flow already does this via InsertDialog — * this dialog is the sidebar/"New" entry point). */ import { useState } from "react"; import { useRouter } from "next/navigation"; import { Database as DatabaseIcon, FileText, Loader2, PenTool } from "lucide-react"; import { toast } from "@/stores/ui-store"; import { useCreatePage } from "@/hooks/use-pages"; import { useCreateDatabase } from "@/hooks/use-database"; import { Dialog, DialogFooter } from "@/components/dialogs/dialog"; type Kind = "page" | "database" | "whiteboard"; export interface CreateDialogProps { open: boolean; workspaceId: string; /** Workspace slug for navigation. */ workspaceSlug: string; /** When set, a database can be embedded into this page. */ pageId?: string | null; onClose: () => void; } export function CreateDialog({ open, workspaceId, workspaceSlug, pageId, onClose }: CreateDialogProps) { const router = useRouter(); const [kind, setKind] = useState("page"); const [title, setTitle] = useState(""); const [icon, setIcon] = useState(""); const createPage = useCreatePage(workspaceId); const createDatabase = useCreateDatabase(); const busy = createPage.isPending || createDatabase.isPending; const reset = () => { setTitle(""); setIcon(""); }; const submit = () => { if (!title.trim() && kind === "page") return; if (kind === "database") { createDatabase.mutate( { title: title.trim() || "Untitled database", icon: icon || undefined, pageId: pageId ?? null }, { onSuccess: (db) => { onClose(); reset(); if (db.pageId) router.push(`/w/${workspaceSlug}/page/${db.pageId}`); else toast("success", "Database created", db.title); }, onError: (e) => toast("error", "Create failed", (e as Error).message) } ); return; } // page and whiteboard both go through useCreatePage (the server sets the kind). createPage.mutate( { parentId: null, title: title.trim(), type: kind === "whiteboard" ? "whiteboard" : undefined }, { onSuccess: (page) => { onClose(); reset(); router.push(`/w/${workspaceSlug}/page/${page.id}`); }, onError: (e) => toast("error", "Create failed", (e as Error).message) } ); }; return ( { onClose(); reset(); }} footer={ { onClose(); reset(); }} onAction={submit} actionLabel={kind === "page" ? "Create page" : kind === "whiteboard" ? "Create whiteboard" : "Create database"} busy={busy} disabled={kind === "database" && !title.trim()} /> } >
{/* kind picker */}
{/* icon (databases only) */} {kind === "database" && (
{icon || "📊"} setIcon(e.target.value)} />
)} {/* title */}
setTitle(e.target.value)} onKeyDown={(e) => e.key === "Enter" && submit()} />
{kind === "database" && pageId && (

The database will be embedded at the top of the current page.

)} {busy && (

Creating…

)}
); }