feat: Phase 1 Foundation & Dashboard implementation
- Core infrastructure: Zustand store, API client with mock fallback - Mode detection: Port 8080 (kiosk) / 9090 (remote) - Dashboard components: RainfallCard, ClockDisplay, CommStatus - Header components: VoltageDisplay, BatteryStatus, LoginIndicator - Data polling with visibility awareness - Bundle size: ~100KB gzipped Also adds README.md and WIKI.md documentation
This commit is contained in:
73
.planning/phases/01-foundation-dashboard/01-01-SUMMARY.md
Normal file
73
.planning/phases/01-foundation-dashboard/01-01-SUMMARY.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Plan 01 Summary - Core Infrastructure
|
||||
|
||||
**Plan:** 01
|
||||
**Phase:** 01-foundation-dashboard
|
||||
**Completed:** 2026-03-13
|
||||
|
||||
---
|
||||
|
||||
## Tasks Completed
|
||||
|
||||
### Task 1: Test Infrastructure
|
||||
- Created `vitest.config.ts` - Vitest configuration extending Vite
|
||||
- Created `src/test/setup.ts` - Test utilities and mocks
|
||||
- Added test scripts to `package.json`
|
||||
- Installed test dependencies: vitest, @testing-library/react, @testing-library/jest-dom, jsdom
|
||||
|
||||
### Task 2: Zustand Sensor Store
|
||||
- Created `src/app/stores/sensorStore.ts`:
|
||||
- SensorData interface with rainfall, voltage, station, communication types
|
||||
- useSensorStore hook with actions: setSensorData, updatePollingInterval, setIsPolling, setError
|
||||
- Selectors: selectRainfall, selectVoltage, selectStation, selectCommunication, selectTimestamp
|
||||
|
||||
### Task 3: API Client with Mock Fallback
|
||||
- Created `src/app/api/client.ts`:
|
||||
- fetchSensorData function with timeout and AbortController support
|
||||
- generateMockSensorData for realistic mock data
|
||||
- Automatic fallback to mock data on API failure
|
||||
|
||||
### Task 4: Port-based Mode Detection
|
||||
- Created `src/app/hooks/useDisplayMode.ts`:
|
||||
- useDisplayMode hook returning 'kiosk' or 'remote'
|
||||
- Port 8080 → kiosk, Port 9090 → remote
|
||||
- Updated `src/app/App.tsx` to use display mode and initialize polling
|
||||
|
||||
### Task 5: Data Polling with Cleanup
|
||||
- Created `src/app/hooks/useSensorPolling.ts`:
|
||||
- Configurable polling interval (default 5 seconds)
|
||||
- Page Visibility API support (pause when hidden)
|
||||
- Proper cleanup with AbortController
|
||||
- Start/stop/refresh controls
|
||||
|
||||
---
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
| File | Status |
|
||||
|------|--------|
|
||||
| src/app/stores/sensorStore.ts | Created |
|
||||
| src/app/api/client.ts | Created |
|
||||
| src/app/hooks/useDisplayMode.ts | Created |
|
||||
| src/app/hooks/useSensorPolling.ts | Created |
|
||||
| src/app/App.tsx | Modified |
|
||||
| src/test/setup.ts | Created |
|
||||
| vitest.config.ts | Created |
|
||||
| package.json | Modified |
|
||||
|
||||
---
|
||||
|
||||
## Bundle Size
|
||||
|
||||
- JS: 325KB uncompressed, 99KB gzipped
|
||||
- CSS: 92KB uncompressed, 15KB gzipped
|
||||
|
||||
**Status:** Under 200KB limit (gzipped) ✓
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- Mock data generation creates realistic values for testing
|
||||
- API client gracefully falls back to mock data
|
||||
- Polling pauses when tab is hidden to save resources
|
||||
- Mode detection enables responsive/kiosk layouts
|
||||
75
.planning/phases/01-foundation-dashboard/01-02-SUMMARY.md
Normal file
75
.planning/phases/01-foundation-dashboard/01-02-SUMMARY.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Plan 02 Summary - Header & Voltage Components
|
||||
|
||||
**Plan:** 02
|
||||
**Phase:** 01-foundation-dashboard
|
||||
**Completed:** 2026-03-13
|
||||
|
||||
---
|
||||
|
||||
## Tasks Completed
|
||||
|
||||
### Task 1: VoltageDisplay Component
|
||||
- Created `src/app/components/VoltageDisplay.tsx`:
|
||||
- Props: label, voltage, className
|
||||
- Displays voltage with one decimal place
|
||||
- Uses Zap icon from Lucide
|
||||
- Min-height 44px for touch targets
|
||||
|
||||
### Task 2: BatteryStatus Component
|
||||
- Created `src/app/components/BatteryStatus.tsx`:
|
||||
- Props: voltage, threshold (default 12.0V), className
|
||||
- Shows color-coded status badge (HIGH/LOW)
|
||||
- Green for >= 12V, Red for < 12V
|
||||
- Touch-friendly (44px min)
|
||||
|
||||
### Task 3: Modernize Header Component
|
||||
- Updated `src/app/components/Header.tsx`:
|
||||
- Imports and uses sensor store
|
||||
- Shows: logo, station ID, version, time, date
|
||||
- Shows: solar voltage, battery voltage with status
|
||||
- Shows: communication status (ASU/dBm/percentage)
|
||||
- Shows: login status
|
||||
- Clock updates every second with cleanup
|
||||
|
||||
### Task 4: Touch Target Verification
|
||||
- All interactive elements have min-height 44px
|
||||
- Verified in VoltageDisplay, BatteryStatus, Header
|
||||
|
||||
### Task 5: DashboardLayout Integration
|
||||
- DashboardLayout already uses Header component
|
||||
- Layout works correctly with sidebar
|
||||
|
||||
---
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
| File | Status |
|
||||
|------|--------|
|
||||
| src/app/components/VoltageDisplay.tsx | Created |
|
||||
| src/app/components/BatteryStatus.tsx | Created |
|
||||
| src/app/components/Header.tsx | Modified |
|
||||
|
||||
---
|
||||
|
||||
## Component Usage
|
||||
|
||||
```tsx
|
||||
// VoltageDisplay
|
||||
<VoltageDisplay label="Solar" voltage={12.5} />
|
||||
|
||||
// BatteryStatus
|
||||
<BatteryStatus voltage={12.5} threshold={12.0} />
|
||||
|
||||
// In Header
|
||||
<VoltageDisplay label="Solar" voltage={data.voltage.solar} />
|
||||
<BatteryStatus voltage={data.voltage.battery} />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- Components use Tailwind CSS classes
|
||||
- Icons from Lucide React
|
||||
- Touch targets meet 44px minimum requirement
|
||||
- Status colors follow design guidelines (green/yellow/red)
|
||||
89
.planning/phases/01-foundation-dashboard/01-03-SUMMARY.md
Normal file
89
.planning/phases/01-foundation-dashboard/01-03-SUMMARY.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# Plan 03 Summary - Dashboard View
|
||||
|
||||
**Plan:** 03
|
||||
**Phase:** 01-foundation-dashboard
|
||||
**Completed:** 2026-03-13
|
||||
|
||||
---
|
||||
|
||||
## Tasks Completed
|
||||
|
||||
### Task 1: RainfallCard Component
|
||||
- Created `src/app/components/RainfallCard.tsx`:
|
||||
- Props: label, value, variant (today/hourly/monthly/yearly)
|
||||
- Color-coded: Today (blue), Hourly (cyan), MAR (green), Yearly (purple)
|
||||
- Large value display with unit
|
||||
- CloudRain icon from Lucide
|
||||
|
||||
### Task 2: ClockDisplay Component
|
||||
- Created `src/app/components/ClockDisplay.tsx`:
|
||||
- Real-time clock (HH:MM:SS) updating every second
|
||||
- Date display (YYYY-MM-DD)
|
||||
- Proper cleanup on unmount
|
||||
|
||||
### Task 3: CommStatus Component
|
||||
- Created `src/app/components/CommStatus.tsx`:
|
||||
- Props: asu, dBm, percentage
|
||||
- Color-coded signal quality indicator
|
||||
- Shows: good (green), fair (yellow), poor (red)
|
||||
|
||||
### Task 4: RainfallView Dashboard
|
||||
- Updated `src/app/components/views/RainfallView.tsx`:
|
||||
- Uses sensor store for real-time data
|
||||
- 4 rainfall cards in responsive grid
|
||||
- ClockDisplay and CommStatus integrated
|
||||
- Last update timestamp
|
||||
|
||||
### Task 5: Dual-Mode Responsive Layout
|
||||
- Implemented port-based mode detection
|
||||
- Kiosk (1024x600): 2-column grid, compact padding
|
||||
- Remote (Full HD): 4-column grid, more spacing
|
||||
|
||||
---
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
| File | Status |
|
||||
|------|--------|
|
||||
| src/app/components/RainfallCard.tsx | Created |
|
||||
| src/app/components/ClockDisplay.tsx | Created |
|
||||
| src/app/components/CommStatus.tsx | Created |
|
||||
| src/app/components/views/RainfallView.tsx | Modified |
|
||||
|
||||
---
|
||||
|
||||
## Component Usage
|
||||
|
||||
```tsx
|
||||
// RainfallCard
|
||||
<RainfallCard label="Today" value={12.5} variant="today" />
|
||||
|
||||
// ClockDisplay
|
||||
<ClockDisplay />
|
||||
|
||||
// CommStatus
|
||||
<CommStatus asu={15} dBm={-75} percentage={50} />
|
||||
|
||||
// In RainfallView
|
||||
<RainfallCard
|
||||
label={item.label}
|
||||
value={item.value}
|
||||
variant={item.variant}
|
||||
/>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Responsive Behavior
|
||||
|
||||
- **Kiosk (port 8080)**: 2-column grid, smaller padding
|
||||
- **Remote (port 9090)**: 4-column grid, expanded layout
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- Dashboard updates in real-time from sensor store
|
||||
- All components connect to Zustand store
|
||||
- Dual-mode display responds to port number
|
||||
- Touch-friendly with adequate hit areas
|
||||
107
.planning/phases/01-foundation-dashboard/01-04-SUMMARY.md
Normal file
107
.planning/phases/01-foundation-dashboard/01-04-SUMMARY.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# Plan 04 Summary - Navigation & Verification
|
||||
|
||||
**Plan:** 04
|
||||
**Phase:** 01-foundation-dashboard
|
||||
**Completed:** 2026-03-13
|
||||
|
||||
---
|
||||
|
||||
## Tasks Completed
|
||||
|
||||
### Task 1: LoginIndicator Component
|
||||
- Created `src/app/components/LoginIndicator.tsx`:
|
||||
- Props: isLoggedIn, className
|
||||
- Shows User icon and status dot
|
||||
- Green for logged in, gray for logged out
|
||||
- Compact for header placement
|
||||
|
||||
### Task 2: Sidebar Navigation
|
||||
- Sidebar already exists with proper navigation:
|
||||
- HOME → /rainfall
|
||||
- GRAPH → /graph
|
||||
- UTILITY (expandable) → 10 sub-items
|
||||
- CALIBRATION → /calibration
|
||||
- FLASH MEMORY → /flash-memory
|
||||
- SETTING → /setting
|
||||
- LOGIN → /login
|
||||
|
||||
### Task 3: Routes Configuration
|
||||
- Routes already configured in `src/app/routes.ts`:
|
||||
- `/` → RainfallView
|
||||
- `/rainfall` → RainfallView
|
||||
- `/graph` → GraphView
|
||||
- `/utility/*` → Various setting views
|
||||
- `/calibration` → CalibrationView
|
||||
- `/flash-memory` → FlashMemoryView
|
||||
|
||||
### Task 4: LoginIndicator Integration
|
||||
- Updated Header to use LoginIndicator component
|
||||
- Integrated in header layout
|
||||
|
||||
### Task 5: Bundle Size Configuration
|
||||
- Created `.bundlesize.json`:
|
||||
- Max size: 200KB gzipped
|
||||
- Configured for dist/assets/*.js
|
||||
|
||||
### Task 6: Build Verification
|
||||
- Production build successful
|
||||
- Bundle size: 99KB gzipped (under 200KB limit)
|
||||
|
||||
### Task 7: Integration Testing
|
||||
- App builds without errors
|
||||
- All routes configured
|
||||
- Navigation works
|
||||
|
||||
---
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
| File | Status |
|
||||
|------|--------|
|
||||
| src/app/components/LoginIndicator.tsx | Created |
|
||||
| src/app/components/Header.tsx | Modified |
|
||||
| .bundlesize.json | Created |
|
||||
|
||||
---
|
||||
|
||||
## Bundle Size
|
||||
|
||||
| Asset | Size | Gzipped |
|
||||
|-------|------|---------|
|
||||
| JS | 326KB | 100KB |
|
||||
| CSS | 92KB | 15KB |
|
||||
|
||||
**Status:** Under 200KB gzipped limit ✓
|
||||
|
||||
---
|
||||
|
||||
## Navigation Structure
|
||||
|
||||
```
|
||||
HOME (Rainfall Dashboard)
|
||||
GRAPH
|
||||
UTILITY (expandable)
|
||||
├── Station Info
|
||||
├── Date/Time
|
||||
├── Mobile
|
||||
├── ADC
|
||||
├── Rainfall
|
||||
├── EVAP
|
||||
├── GPRS
|
||||
├── Level
|
||||
├── SIREN
|
||||
└── Network
|
||||
CALIBRATION
|
||||
FLASH MEMORY
|
||||
SETTING
|
||||
LOGIN
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- All navigation items have 44px+ touch targets
|
||||
- Active route highlighting works
|
||||
- Login indicator integrated in header
|
||||
- Bundle size within limits
|
||||
Reference in New Issue
Block a user