# Phase 3: Dashboard & Intake UI - Context **Gathered:** 2026-04-10 **Status:** Ready for planning **Mode:** Auto-generated (autonomous mode) ## Phase Boundary Users can browse their full inventory, run intake for new items, and view item detail — all through the React SPA served by the Go binary. This phase delivers the React+TypeScript frontend with the ClickHouse design system, inventory dashboard, intake flow, item detail view, and PWA installation with camera-based QR scanner. ## Implementation Decisions ### Tech Stack (from PROJECT.md) - Vite 5.x for build tooling - React 18 + TypeScript 5.x - TanStack Router v1 for routing - TanStack Query v5 for server state - Zustand v4 for client state - shadcn/ui (Radix + Tailwind) for components - Tailwind CSS 3.x with ClickHouse design tokens - react-dropzone for file uploads - react-hot-toast for notifications - lucide-react for icons ### Design System — ClickHouse - Pure black (#000000) canvas - Neon volt (#faff69) accent for CTAs - Forest green (#166534) for primary actions - Inter 900 (Black) for display typography - Charcoal borders rgba(65,65,65,0.8) - 4px sharp corners for buttons, 8px for cards - Reference: ~/.claude/DESIGN.md (already globally configured) ### Project Structure - Frontend lives in `web/` directory - Built assets go to `web/dist/` (already embedded via go:embed) - Dev mode: Vite serves at http://localhost:5173, proxies /api to Go backend at :8080 - Prod mode: Go binary serves embedded SPA ### Routing - `/` — Inventory Dashboard (grid/list view) - `/item/:id` — Item detail - `/intake` — AI Intake Wizard (photo upload) - `/scan` — PWA camera QR scanner - 404 fallback to dashboard ### PWA - Manifest.json with installable config - Service worker for offline shell caching - Camera access via MediaDevices API for QR scanning - QR decoding via @zxing/browser or html5-qrcode ### State Management - TanStack Query for all NetBox data (dashboard list, item detail) - Zustand for UI state (intake wizard steps, scanner state) - No Redux ### API Contract - Backend exposes: GET /api/inventory (list), GET /api/inventory/:id (detail), POST /api/intake (upload photos) - Phase 3 adds GET endpoints; intake POST already exists from Phase 2 ### Claude's Discretion All visual details and component hierarchy at Claude's discretion, following the ClickHouse DESIGN.md. ## Existing Code Insights ### Reusable Assets from Phase 1-2 - `cmd/hwlab/main.go` — binary entry, already serves web/dist via go:embed - `internal/api/router.go` — chi router, add GET inventory endpoints - `internal/api/handlers/` — health.go, intake.go patterns - `internal/netbox/client.go` — ListDevices for dashboard - `web/dist/index.html` — current stub placeholder - `assets.go` — go:embed directive ### Established Patterns - Integration tests skip gracefully - Module path: git.georgsen.dk/hwlab - ClickHouse design system global default ### Integration Points - Add GET /api/inventory handler listing NetBox devices - Add GET /api/inventory/:id handler for detail - Replace web/dist stub with real Vite build output - Makefile targets: `make frontend` (vite build), `make dev` (parallel vite + go run) ## Specific Ideas - Tailwind config should inherit ClickHouse tokens directly from ~/.claude/DESIGN.md - Use shadcn/ui CLI to scaffold components - Drag-drop intake zone with thumbnail preview - Dashboard uses data-table pattern with sort/filter - Item detail is a side-panel or full-page modal ## Deferred Ideas - Real-time updates (websockets) — not needed for single-operator - Offline sync — PWA shell only - Advanced filtering (Phase 7 — AI NLP search) - Lab Advisor chat (Phase 6)