6.6 KiB
6.6 KiB
Phase 2 — React UI Components Task Spec
Context
- Project: web-cad-neu (clean rewrite of web-cad)
- Frontend: /a0/usr/workdir/web-cad-neu/frontend/
- Stack: React 18 + TypeScript + Vite, plain CSS (no Tailwind/styled-components)
- tsconfig: jsx=react-jsx, baseUrl=./src, paths @/* -> .
Reference Files (READ THESE FIRST)
- Mockup HTML: /a0/usr/workdir/web-cad-neu/mockup/editor.html (1133 lines)
- Mockup theme CSS: /a0/usr/workdir/web-cad-neu/mockup/assets/styles.css (195 lines)
- Mockup layout CSS: /a0/usr/workdir/web-cad-neu/mockup/assets/layout.css (1298 lines)
- Types: /a0/usr/workdir/web-cad-neu/frontend/src/types/cad.types.ts
- Phase 1 engines: /a0/usr/workdir/web-cad-neu/frontend/src/canvas/*.ts, /a0/usr/workdir/web-cad-neu/frontend/src/interaction/index.ts
Output Directory
/a0/usr/workdir/web-cad-neu/frontend/src/
Files to Create (15 components + 1 CSS)
1. styles.css
- Copy /a0/usr/workdir/web-cad-neu/mockup/assets/styles.css + layout.css content into ONE file at frontend/src/styles.css
- Keep all CSS class names verbatim from mockup
- Keep all CSS variables from styles.css
- Add mobile breakpoint rules from layout.css (<=768px)
2. App.tsx
- Root component: imports styles.css
- Layout: > Topbar + RibbonBar + > LeftSidebar + CanvasArea + RightSidebar + + CommandLine + StatusBar + MobileDrawers
- State: activeTool, activeRibbonTab, activeRightPanel, theme, snapEnabled, orthoEnabled, gridEnabled, selectedElements, layers, cursorPos, commandHistory
- Pass props to children
3. components/Topbar.tsx
- class="topbar" with topbar-left (hamburger, logo, app-name, project-name, saved-badge) and topbar-right (undo, redo, divider, versions, share, divider, theme-toggle, help, divider, lang-select, notifications, avatar)
- Copy SVG icons EXACTLY from mockup lines 21-68
- Props: projectName, savedStatus, onUndo, onRedo, onThemeToggle, theme
4. components/RibbonBar.tsx
- class="ribbon" with ribbon-tabs (6 tabs: Start/Einfügen/Format/Ansicht/Extras/KI) + ribbon-content
- Start tab groups: Datei (Neu/Öffnen/Speichern), Bearbeiten (Undo/Redo/Kopieren/Einfügen), Ansicht (Zoom Fit/100%/Grid/Layer), Extras (Messen/Suchen/KI/Plugins)
- Copy SVGs from mockup lines 72-191
- Props: activeTab, onTabChange, onAction
5. components/LeftSidebar.tsx
- class="leftbar" with header (title + toggle), 4 tool-sections, footer (3 buttons)
- Sections: Auswählen/Anzeigen (Auswahl/Pan/Zoom/Messen), Zeichnen (Linie/Polylinie/Rechteck/Kreis/Bogen/Text/Bemaßung/Schraffur), Bearbeiten (Move/Copy/Rotate/Scale/Mirror/Trim/Offset/Löschen), Bestuhlung (Reihe/Block/Tisch/Bühne)
- 20 tool buttons with data-tool, title, SVG icon, label, kbd shortcut
- Copy SVGs from mockup lines 198-360
- Props: activeTool, onToolChange
- Footer: Plugin/Settings/Help buttons
6. components/CanvasArea.tsx
- class="canvas-area" with canvas-coords (X/Y display), canvas-view-tabs (2D/ISO/Front/Top), element (NOT SVG)
- useEffect: init RenderEngine + ZoomPanController + InteractionEngine on canvas ref
- Floating toolbar: zoom in/out/fit, grid toggle, ortho toggle, snap toggle, prev view
- Props: cursorPos, viewMode, onViewChange, gridEnabled, orthoEnabled, snapEnabled, onToggleGrid, onToggleOrtho, onToggleSnap, onZoomIn, onZoomOut, onZoomFit
7. components/RightSidebar.tsx
- class="rightbar" with rightbar-tabs (Werkzeug/Layer/Bibliothek/KI) + rightbar-content
- Tab switching shows/hides panels
- KI tab has badge (count)
- Copy SVGs from mockup lines 669-687
- Props: activePanel, onPanelChange, selectedElement, layers, blocks
8. components/PropertiesPanel.tsx
- rightbar-panel data-panel-content="tool"
- Sections: selection info, Geometrie (X/Y/Breite/Tiefe/Drehung inputs), Darstellung (Farbe color picker+hex, Linientyp select, Stärke select, Layer select), Block (name+description inputs)
- Copy structure from mockup lines 692-776
- Props: selectedElement, layers, onUpdateProperty
9. components/LayerPanel.tsx
- rightbar-panel data-panel-content="layer"
- Uses TreeView component for layer hierarchy
- Header with options button + add-layer button
- Copy structure from mockup lines 779-866
- Props: layers, onSelectLayer, onAddLayer, onToggleLayer
10. components/BlockLibrary.tsx
- rightbar-panel data-panel-content="library"
- lib-search (input with search icon), lib-categories (Alle/Bestuhlung/Tische/Bühne/Deko chips), tree-library with draggable items
- Copy structure from mockup lines 897-976
- Props: blocks, category, onCategoryChange, onSearch, onDragBlock
11. components/KICopilot.tsx
- rightbar-panel data-panel-content="ki"
- ki-header (avatar, title, status), ki-suggestions (chips), ki-chat (messages), ki-input-wrap (input+voice+send)
- Copy structure from mockup lines 978-1026
- Props: messages, suggestions, onSend, onSuggestionClick
12. components/CommandLine.tsx
- class="cmdline" with cmdline-history (entries with prefix · or ›) + cmdline-input-wrap (prompt › + input)
- Copy structure from mockup lines 1076-1089
- Props: history, onCommand
13. components/StatusBar.tsx
- class="statusbar" with status-items: SNAP/ORTHO/POLAR/GRID toggles, X/Y coords, active layer, active tool, online status
- Copy structure from mockup lines 1092-1127
- Props: snapEnabled, orthoEnabled, polarEnabled, gridEnabled, cursorX, cursorY, activeLayer, activeTool, onlineCount, onToggleSnap, onToggleOrtho, onTogglePolar, onToggleGrid
14. components/TreeView.tsx
- Reusable tree component for LayerPanel and BlockLibrary
- Props: nodes (TreeNode[]), onSelect, onToggle, draggable, renderIcon
- TreeNode type: { id, name, count?, icon?, children?, expanded?, active?, draggable? }
- Renders tree-node > tree-row (tree-row-folder or tree-row-leaf) > tree-children recursively
15. components/MobileDrawers.tsx
- Scrim + drawer-left + drawer-right
- drawer-left: header (title + close) + body (filled with LeftSidebar content)
- drawer-right: header (title + close) + drawer-tabs (Wz/Layer/Lib/KI) + body
- Copy structure from mockup lines 1032-1073
- Props: leftOpen, rightOpen, activeRightTab, onCloseLeft, onCloseRight, onRightTabChange
Rules
- TypeScript functional components with React.FC or function syntax
- NO inline styles except where mockup uses them (style="...")
- NO styled-components, NO Tailwind
- Import styles.css once in App.tsx
- Copy SVG icons EXACTLY from mockup (viewBox, paths, attributes)
- Use mockup CSS class names verbatim
- All text in German (matching mockup)
- CanvasArea uses not
- Mobile breakpoint <=768px: hamburger shows, sidebars hide, drawers slide in
- npx tsc --noEmit must pass with zero errors
- Each component in its own file under components/