'use client'; import { useEffect } from 'react'; import Link from 'next/link'; import { UserButton } from '@clerk/nextjs'; import { Toolbar } from './Toolbar'; import { ArtboardNavigator } from '../navigator/ArtboardNavigator'; import { Canvas } from '../canvas/Canvas'; import { Inspector } from '../inspector/Inspector'; import { useHistory } from '@/store/history'; import { useCanvas, type Tool } from '@/store/canvas'; interface AppChromeProps { workspaceId?: string; projectId?: string; workspaceName?: string; projectName?: string; } export function AppChrome({ workspaceId, projectId, workspaceName, projectName }: AppChromeProps) { const selectedArtboardId = useCanvas((s) => s.selectedArtboardId); const setContext = useCanvas((s) => s.setContext); const setActiveTool = useCanvas((s) => s.setActiveTool); // Push workspace/project IDs into the store so Canvas and Navigator can read them. useEffect(() => { if (workspaceId && projectId) setContext(workspaceId, projectId); }, [workspaceId, projectId, setContext]); useEffect(() => { function onKeyDown(e: KeyboardEvent) { // Skip if user is typing in an input if ((e.target as HTMLElement).matches('input, textarea, [contenteditable]')) return; // Tool shortcuts (no modifier) if (!e.metaKey && !e.ctrlKey) { const toolKeys: Record = { v: 'select', h: 'pan', a: 'artboard', z: 'zone' }; const mapped = toolKeys[e.key.toLowerCase()]; if (mapped !== undefined) { e.preventDefault(); setActiveTool(mapped); return; } // Escape cancels active tool back to select if (e.key === 'Escape') { setActiveTool('select'); return; } } // Undo/Redo require a selected artboard if (!(e.metaKey || e.ctrlKey)) return; if (!selectedArtboardId) return; if (e.key === 'z' && !e.shiftKey) { e.preventDefault(); useHistory.getState().undo(selectedArtboardId); } else if ((e.key === 'z' && e.shiftKey) || e.key === 'y') { e.preventDefault(); useHistory.getState().redo(selectedArtboardId); } } window.addEventListener('keydown', onKeyDown); return () => window.removeEventListener('keydown', onKeyDown); }, [selectedArtboardId, setActiveTool]); const showBreadcrumb = Boolean(workspaceId && projectId); return ( // Outer flex-column: breadcrumb on top (fixed height), inner grid fills the rest. // Breadcrumb lives OUTSIDE the grid so the Toolbar/panel gridRow placements // never shift regardless of whether the breadcrumb is visible.
{/* ── Breadcrumb bar ─────────────────────────────────── */} {showBreadcrumb && (
{/* Logo */} Originmain / Workspaces / {workspaceName ?? 'Workspace'} / {projectName ?? 'Canvas'}
)} {/* ── Inner grid: Toolbar (row 1) + panels (row 2) ─── */} {/* Rows are always 44px + 1fr — breadcrumb never enters this grid. */}
); }