From cf27a54caa70712070d9fb0620f6610ba22af206 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Fri, 13 Feb 2026 14:39:01 -0700 Subject: [PATCH] feat: mobile-responsive UI + canvas sync callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Responsive navigation: compact buttons with icons on mobile, hidden search bar (moved to dedicated row below nav on mobile) - Responsive typography: hero text scales from 3xl to 5xl - Responsive grids: sm:grid-cols-2 breakpoint for cards - Canvas split view: full-screen overlay on mobile with close button - Breadcrumbs collapse on mobile, truncate long titles - Buttons show icon-only on small screens (add, delete, pin) - Wire up onShapeUpdate callback in notebook detail page for bidirectional canvas sync (rSpace → rnotes via /api/sync) Co-Authored-By: Claude Opus 4.6 --- src/app/notebooks/[id]/page.tsx | 76 +++++++++++++++++++++++---------- src/app/notebooks/new/page.tsx | 12 +++--- src/app/notebooks/page.tsx | 21 +++++---- src/app/notes/[id]/page.tsx | 42 +++++++++--------- src/app/notes/new/page.tsx | 6 +-- src/app/page.tsx | 48 ++++++++++++--------- 6 files changed, 124 insertions(+), 81 deletions(-) diff --git a/src/app/notebooks/[id]/page.tsx b/src/app/notebooks/[id]/page.tsx index 1e8198b..acd4b68 100644 --- a/src/app/notebooks/[id]/page.tsx +++ b/src/app/notebooks/[id]/page.tsx @@ -7,6 +7,7 @@ import { NoteCard } from '@/components/NoteCard'; import { CanvasEmbed } from '@/components/CanvasEmbed'; import { UserMenu } from '@/components/UserMenu'; import { authFetch } from '@/lib/authFetch'; +import type { CanvasShapeMessage } from '@/lib/canvas-sync'; interface NoteData { id: string; @@ -51,6 +52,23 @@ export default function NotebookDetailPage() { fetchNotebook(); }, [fetchNotebook]); + const handleShapeUpdate = useCallback(async (message: CanvasShapeMessage) => { + try { + await fetch('/api/sync', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + shapeId: message.shapeId, + type: message.type, + data: message.data, + }), + }); + fetchNotebook(); + } catch (err) { + console.error('Canvas sync error:', err); + } + }, [fetchNotebook]); + const handleCreateCanvas = async () => { if (creatingCanvas) return; setCreatingCanvas(true); @@ -98,51 +116,54 @@ export default function NotebookDetailPage() { return (
-