Phase 8: Visitor Management - Visitor/VisitorLog/AccessZone models - Check-in/out with badge generation - Zone occupancy tracking - Kiosk and management pages Phase 9: Messaging & Communication - Announcements with priority levels - Acknowledgement tracking - Shift notes for team handoffs - AnnouncementBanner component Phase 10: Compliance & Audit Trail - Immutable AuditLog model - Document versioning and approval workflow - Acknowledgement tracking for SOPs - CSV export for audit logs Phase 11: Accessibility & i18n - WCAG 2.1 AA compliance utilities - react-i18next with EN/ES translations - User preferences context (theme, font size, etc) - High contrast and reduced motion support Phase 12: Hardware Integration - QR code generation for batches/plants/visitors - Printable label system - Visitor badge printing Phase 13: Advanced Features - Environmental monitoring (sensors, readings, alerts) - Financial tracking (transactions, P&L reports) - AI/ML insights (yield predictions, anomaly detection)
14 KiB
14 KiB
Facility Layout Designer - Premium UX Specification
🎯 Design Vision
A Figma-meets-SketchUp experience for cannabis facility floor planning. Premium, intuitive, and powerful enough for compliance while beautiful enough for investor demos.
🏗️ Core Architecture
Multi-Floor Support
PROPERTY
├── BUILDING 1 (Main Cultivation)
│ ├── FLOOR 1 (Ground)
│ │ ├── Veg Room A
│ │ ├── Veg Room B
│ │ └── Clone Room
│ └── FLOOR 2 (Upper)
│ ├── Flower Room A
│ ├── Flower Room B
│ └── Flower Room C
├── BUILDING 2 (Processing)
│ └── FLOOR 1
│ ├── Dry Room
│ ├── Cure Room
│ └── Trim Room
└── BUILDING 3 (Storage)
└── FLOOR 1
└── Vault
Address Format with Floor
MAIN.GROW1.F2.FLOWER-A.LEFT.R3.C5.P1
↑
Floor 2
🎨 UI Layout (Premium Dark Mode)
┌─────────────────────────────────────────────────────────────────────────────┐
│ ⚡ Layout Designer [Building ▼] [Floor 1 ▼] 🔍 100% ⊞ ⊟ ↺ ↻ 💾 Save │
├───────────────┬─────────────────────────────────────────────┬───────────────┤
│ │ │ │
│ 📁 LAYERS │ │ 📐 INSPECTOR │
│ ───────── │ │ ─────────── │
│ │ [ CANVAS - FLOOR PLAN ] │ │
│ ▼ Floor 1 │ │ Selected: │
│ ├ Veg-A │ ┌─────────────┐ ┌─────────────┐ │ VEG ROOM A │
│ ├ Veg-B │ │ │ │ │ │ │
│ └ Clones │ │ VEG-A │ │ VEG-B │ │ Size: 40x30' │
│ │ │ 🌱 234 │ │ 🌱 189 │ │ Tables: 6 │
│ ▶ Floor 2 │ │ │ │ │ │ Capacity: 480│
│ │ └─────────────┘ └─────────────┘ │ Occupied: 423│
│ ───────── │ │ ▓▓▓▓▓▓▓▓░░ │
│ │ ┌────────────────────────────┐ │ 88% full │
│ 🧩 ELEMENTS │ │ │ │ │
│ ───────── │ │ CLONE ROOM │ │ ─────────── │
│ │ │ 🌱 120 │ │ POSITIONS │
│ ▢ Room │ │ │ │ [Grid View] │
│ ▦ Table │ └────────────────────────────┘ │ │
│ ═ Rack │ │ R1: ████████ │
│ ⊡ Position │ [AISLE] │ R2: █████░░░ │
│ │ │ R3: ████████ │
│ 🎨 STYLES │ │ R4: ░░░░░░░░ │
│ ───────── │ │ │
│ ● Veg │ │ [+ Add Row] │
│ ● Flower │ │ │
│ ● Dry │ │ │
│ ● Cure │ │ │
│ │ │ │
└───────────────┴─────────────────────────────────────────────┴───────────────┘
✨ Premium UX Features
1. Canvas Interactions
| Gesture | Action |
|---|---|
| Scroll | Pan canvas |
| Pinch/Scroll+Ctrl | Zoom |
| Click element | Select |
| Double-click | Edit properties |
| Drag | Move element |
| Drag corner | Resize |
| Shift+Drag | Constrain proportions |
| Alt+Drag | Duplicate |
| Delete/Backspace | Remove |
2. Floor Selector
- Dropdown showing all floors
- 3D mini-map showing floor stack
- Shift+PageUp/Down to switch floors
- Floor comparison overlay (ghost previous floor)
3. Smart Snapping
- Snap to grid (configurable: 1ft, 6", 1m)
- Snap to edges (align with adjacent rooms)
- Snap to centers (center alignment guides)
- Smart dimensions (show distances while dragging)
4. Element Library
const ELEMENTS = {
rooms: [
{ type: 'VEG', icon: '🌱', color: 'emerald' },
{ type: 'FLOWER', icon: '🌸', color: 'purple' },
{ type: 'CLONE', icon: '🧬', color: 'blue' },
{ type: 'DRY', icon: '🍂', color: 'amber' },
{ type: 'CURE', icon: '🫙', color: 'orange' },
{ type: 'TRIM', icon: '✂️', color: 'slate' },
{ type: 'VAULT', icon: '🔒', color: 'zinc' },
],
fixtures: [
{ type: 'TABLE', icon: '▦', description: '4x8 grow table' },
{ type: 'RACK', icon: '═', description: 'Drying rack' },
{ type: 'TRAY', icon: '▢', description: 'Clone tray' },
{ type: 'HANGER', icon: '⌐', description: 'Vertical hanger' },
],
infrastructure: [
{ type: 'DOOR', icon: '🚪' },
{ type: 'HVAC', icon: '❄️' },
{ type: 'ELECTRICAL', icon: '⚡' },
{ type: 'WATER', icon: '💧' },
],
};
5. Inspector Panel
Room Properties
┌─────────────────────────────┐
│ VEG ROOM A │
│ ───────────────────────── │
│ │
│ 📍 Location │
│ Building: [Grow 1 ▼] │
│ Floor: [Floor 1 ▼] │
│ Code: [VEG-A ] │
│ │
│ 📐 Dimensions │
│ Width: [40] ft │
│ Height: [30] ft │
│ Area: 1,200 sq ft │
│ │
│ 🌱 Capacity │
│ Tables: [6 ] │
│ Positions: 480 │
│ Occupied: 423 (88%) │
│ │
│ 🎨 Appearance │
│ Color: [🟢 Emerald ▼] │
│ Label: [Vegetative A] │
│ │
│ [Delete Room] │
└─────────────────────────────┘
Table/Section Properties
┌─────────────────────────────┐
│ TABLE T1 │
│ ───────────────────────── │
│ │
│ 📐 Grid Configuration │
│ Rows: [6 ] │
│ Columns: [8 ] │
│ Spacing: [12] in │
│ │
│ Total Positions: 48 │
│ Occupied: 42 │
│ Empty: 6 │
│ │
│ 📊 Current Batch │
│ [OG Kush #4] - 42 plants │
│ │
│ [View Grid] [Edit Grid] │
└─────────────────────────────┘
🎨 Visual Design System
Color Palette (Dark Mode)
/* Background */
--bg-canvas: #0f172a; /* Slate 900 */
--bg-sidebar: #1e293b; /* Slate 800 */
--bg-panel: #334155; /* Slate 700 */
/* Room Types */
--room-veg: #10b981; /* Emerald */
--room-flower: #a855f7; /* Purple */
--room-clone: #3b82f6; /* Blue */
--room-dry: #f59e0b; /* Amber */
--room-cure: #f97316; /* Orange */
--room-trim: #64748b; /* Slate */
/* Grid */
--grid-line: rgba(255,255,255,0.05);
--grid-major: rgba(255,255,255,0.1);
/* Selection */
--selection: #10b981;
--selection-glow: rgba(16,185,129,0.3);
Typography
--font-ui: 'Space Grotesk', system-ui;
--font-mono: 'JetBrains Mono', monospace;
/* Sizes */
--text-panel-title: 0.75rem; /* 12px */
--text-label: 0.875rem; /* 14px */
--text-input: 1rem; /* 16px */
Glassmorphism Panels
.panel {
background: rgba(30, 41, 59, 0.8);
backdrop-filter: blur(12px);
border: 1px solid rgba(255,255,255,0.1);
border-radius: 12px;
box-shadow: 0 8px 32px rgba(0,0,0,0.3);
}
🖥️ Component Architecture
LayoutDesigner/
├── LayoutDesigner.tsx # Main container
├── components/
│ ├── Canvas/
│ │ ├── Canvas.tsx # react-konva stage
│ │ ├── Grid.tsx # Background grid
│ │ ├── RoomShape.tsx # Room polygon
│ │ ├── TableShape.tsx # Table rectangle
│ │ ├── SelectionBox.tsx # Multi-select
│ │ └── Guides.tsx # Alignment guides
│ ├── Sidebar/
│ │ ├── Sidebar.tsx
│ │ ├── LayersPanel.tsx # Floor/room hierarchy
│ │ ├── ElementsPanel.tsx # Draggable elements
│ │ └── StylesPanel.tsx # Color/appearance
│ ├── Inspector/
│ │ ├── Inspector.tsx
│ │ ├── RoomInspector.tsx
│ │ ├── TableInspector.tsx
│ │ └── GridEditor.tsx # Position grid editor
│ ├── Toolbar/
│ │ ├── Toolbar.tsx
│ │ ├── ZoomControls.tsx
│ │ ├── FloorSelector.tsx
│ │ └── HistoryButtons.tsx
│ └── Modals/
│ ├── AddFloorModal.tsx
│ ├── AddBuildingModal.tsx
│ └── ImportExportModal.tsx
├── hooks/
│ ├── useCanvas.ts # Canvas state
│ ├── useSelection.ts # Selected elements
│ ├── useHistory.ts # Undo/redo
│ └── useDragDrop.ts # Element placement
├── stores/
│ └── layoutStore.ts # Zustand state
└── utils/
├── geometry.ts # Collision, bounds
├── addressGenerator.ts # Create addresses
└── exporters.ts # PDF, image export
📱 Responsive Behavior
Desktop (1200px+)
- 3-column layout: Sidebar | Canvas | Inspector
- Full feature set
Tablet (768-1199px)
- 2-column: Collapsible sidebar | Canvas
- Inspector as slide-over panel
- Touch-friendly controls
Mobile (< 768px)
- Full-screen canvas
- Bottom sheet for elements/inspector
- Simplified tools
- "View Only" mode recommended
⌨️ Keyboard Shortcuts
| Shortcut | Action |
|---|---|
Space + Drag |
Pan |
Cmd/Ctrl + +/- |
Zoom |
Cmd/Ctrl + 0 |
Fit to screen |
Cmd/Ctrl + Z |
Undo |
Cmd/Ctrl + Shift + Z |
Redo |
Cmd/Ctrl + D |
Duplicate |
Cmd/Ctrl + G |
Group |
Delete |
Remove selected |
Escape |
Deselect |
Tab |
Cycle selection |
1-9 |
Quick zoom levels |
F |
Fit selection |
G |
Toggle grid |
S |
Toggle snap |
🔄 State Management (Zustand)
interface LayoutState {
// Current context
propertyId: string;
buildingId: string;
floorId: string;
// Canvas
zoom: number;
pan: { x: number; y: number };
showGrid: boolean;
snapToGrid: boolean;
gridSize: number; // feet
// Selection
selectedIds: string[];
hoveredId: string | null;
// Elements
rooms: Room[];
sections: Section[];
positions: Position[];
// History
past: LayoutSnapshot[];
future: LayoutSnapshot[];
// Actions
addRoom: (room: Partial<Room>) => void;
updateRoom: (id: string, updates: Partial<Room>) => void;
deleteRoom: (id: string) => void;
undo: () => void;
redo: () => void;
// ... etc
}
📄 Export Options
- PDF Floor Plan - Printable blueprint with dimensions
- PNG/SVG Image - For presentations
- JSON Layout - Backup/restore
- METRC Location Report - All addresses in compliance format
- Position Labels - Generate QR labels for all positions
🚀 Implementation Priority
Week 1: Foundation
- Zustand store setup
- Basic canvas with react-konva
- Grid rendering
- Pan & zoom
Week 2: Elements
- Room shapes (create, select, move, resize)
- Sidebar with element library
- Drag to canvas
- Inspector panel
Week 3: Multi-Floor
- Floor selector
- Floor switching
- Ghost overlay of other floors
- Building/floor CRUD
Week 4: Positions
- Table grid generator
- Position grid view
- Occupancy visualization
- Plant placement integration
Week 5: Polish
- Snap guides
- Keyboard shortcuts
- Undo/redo history
- Export functions
Week 6: Integration
- API integration
- Real-time updates
- METRC address mapping
- QR code generation