From 3aaad38e0672205514217ef618822a6b56d52b24 Mon Sep 17 00:00:00 2001 From: Matthias Meister Date: Fri, 3 Apr 2026 13:51:41 +0200 Subject: [PATCH] Enhance canvas sidebar and toolbar with improved UI and state management - Integrated NextImage for logo display in the canvas sidebar, enhancing visual consistency. - Updated canvas name handling in the toolbar to ensure proper display and accessibility. - Refactored sidebar layout for better responsiveness and user experience. - Improved state management for category collapsibility in the sidebar, allowing for a more intuitive navigation experience. --- components/canvas/canvas-sidebar.tsx | 154 +++++++++++++++----------- components/canvas/canvas-toolbar.tsx | 12 +- components/canvas/canvas.tsx | 2 +- convex/ai.ts | 159 ++++++++++++++++++++++----- convex/credits.ts | 90 +++++++++++---- convex/edges.ts | 15 ++- convex/helpers.ts | 18 +++ convex/nodes.ts | 137 ++++++++++++++++------- convex/openrouter.ts | 59 ++++++++-- 9 files changed, 477 insertions(+), 169 deletions(-) diff --git a/components/canvas/canvas-sidebar.tsx b/components/canvas/canvas-sidebar.tsx index 18ef893..442596a 100644 --- a/components/canvas/canvas-sidebar.tsx +++ b/components/canvas/canvas-sidebar.tsx @@ -1,6 +1,7 @@ "use client"; import { useState } from "react"; +import NextImage from "next/image"; import { Bot, ClipboardList, @@ -160,77 +161,98 @@ export default function CanvasSidebar({ ) : ( -
- {canvas === undefined ? ( -
- ) : ( - <> -

- Canvas -

-

- {canvas?.name ?? "…"} -

- - )} +
+
+
+ + +
+
)} -
- {railMode ? ( -
- {railEntries.map((entry) => ( - - ))} -
- ) : ( - <> - {NODE_CATEGORIES_ORDERED.map((categoryId) => { - const entries = byCategory.get(categoryId) ?? []; - if (entries.length === 0) return null; - const { label } = NODE_CATEGORY_META[categoryId]; - const isCollapsed = collapsedByCategory[categoryId] ?? categoryId !== "source"; - return ( -
- - {!isCollapsed ? ( -
- {entries.map((entry) => ( - - ))} -
- ) : null} -
- ); - })} - - )} +
+
+ {railMode ? ( +
+ {railEntries.map((entry) => ( + + ))} +
+ ) : ( + <> + {NODE_CATEGORIES_ORDERED.map((categoryId) => { + const entries = byCategory.get(categoryId) ?? []; + if (entries.length === 0) return null; + const { label } = NODE_CATEGORY_META[categoryId]; + const isCollapsed = collapsedByCategory[categoryId] ?? categoryId !== "source"; + return ( +
+ + {!isCollapsed ? ( +
+ {entries.map((entry) => ( + + ))} +
+ ) : null} +
+ ); + })} + + )} +
+ - +
+ +
); } diff --git a/components/canvas/canvas-toolbar.tsx b/components/canvas/canvas-toolbar.tsx index 345810f..343c8d6 100644 --- a/components/canvas/canvas-toolbar.tsx +++ b/components/canvas/canvas-toolbar.tsx @@ -65,6 +65,7 @@ export default function CanvasToolbar({ }; const byCategory = catalogEntriesByCategory(); + const resolvedCanvasName = canvasName?.trim() || "Unbenannter Canvas"; const toolBtn = (tool: CanvasNavTool, icon: React.ReactNode, label: string) => (