"use client"; import { useRef } from "react"; import { Hand, MessageSquare, MousePointer2, Plus, Redo2, Scissors, Undo2, } from "lucide-react"; import { CreditDisplay } from "@/components/canvas/credit-display"; import { ExportButton } from "@/components/canvas/export-button"; import { useCanvasPlacement } from "@/components/canvas/canvas-placement-context"; import { useCenteredFlowNodePosition } from "@/hooks/use-centered-flow-node-position"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { NODE_CATEGORY_META, NODE_CATEGORIES_ORDERED, catalogEntriesByCategory, getTemplateForCatalogType, isNodePaletteEnabled, type NodeCategoryId, } from "@/lib/canvas-node-catalog"; import type { CanvasNodeTemplate } from "@/lib/canvas-node-templates"; export type CanvasNavTool = "select" | "hand" | "scissor" | "comment"; interface CanvasToolbarProps { canvasName?: string; activeTool: CanvasNavTool; onToolChange: (tool: CanvasNavTool) => void; } export default function CanvasToolbar({ canvasName, activeTool, onToolChange, }: CanvasToolbarProps) { const { createNodeWithIntersection } = useCanvasPlacement(); const getCenteredPosition = useCenteredFlowNodePosition(); const nodeCountRef = useRef(0); const handleAddNode = async (template: CanvasNodeTemplate) => { const stagger = (nodeCountRef.current % 8) * 24; nodeCountRef.current += 1; await createNodeWithIntersection({ type: template.type, position: getCenteredPosition(template.width, template.height, stagger), width: template.width, height: template.height, data: template.defaultData, clientRequestId: crypto.randomUUID(), }); }; const byCategory = catalogEntriesByCategory(); const resolvedCanvasName = canvasName?.trim() || "Unbenannter Canvas"; const toolBtn = (tool: CanvasNavTool, icon: React.ReactNode, label: string) => ( ); return (
{NODE_CATEGORIES_ORDERED.map((categoryId: NodeCategoryId) => { const entries = byCategory.get(categoryId) ?? []; if (entries.length === 0) return null; return (
{NODE_CATEGORY_META[categoryId].label} {entries.map((entry) => { const template = getTemplateForCatalogType(entry.type); const enabled = isNodePaletteEnabled(entry) && Boolean(template); return ( { if (!template) return; void handleAddNode(template); }} > {entry.label} ); })}
); })}
{toolBtn( "select", , "Auswahl (V) — schwenken: Leertaste gedrückt halten und ziehen", )} {toolBtn( "hand", , "Hand (H) — schwenken: Leertaste gedrückt halten und ziehen oder linke Maustaste", )} {toolBtn("scissor", , "Schere (K) — Verbindungen kappen")}
{resolvedCanvasName}
); }