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:
2026-03-13 06:42:55 +08:00
parent 372d9e1001
commit 9e3cc99bed
96 changed files with 8348 additions and 0 deletions

View 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

View 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)

View 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

View 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