---
phase: 01-foundation-dashboard
plan: 02
type: execute
wave: 1
depends_on:
- 01-01
files_modified:
- src/app/components/Header.tsx
- src/app/components/VoltageDisplay.tsx
- src/app/components/BatteryStatus.tsx
- src/app/components/__tests__/Header.test.tsx
- src/app/components/__tests__/VoltageDisplay.test.tsx
- src/app/components/__tests__/BatteryStatus.test.tsx
autonomous: true
requirements:
- DASH-02
- DASH-03
- DASH-04
- DASH-07
- UI-01
- UI-02
must_haves:
truths:
- Header displays all status information
- Voltage displays show solar and battery readings
- Battery status shows HIGH/LOW indicator with color
- All touch targets are minimum 44px
- Header is compact for 1024x600 display
artifacts:
- path: src/app/components/Header.tsx
provides: Main header with status info
exports: Header
min_lines: 80
- path: src/app/components/VoltageDisplay.tsx
provides: Solar/battery voltage display
exports: VoltageDisplay
- path: src/app/components/BatteryStatus.tsx
provides: Battery status indicator
exports: BatteryStatus
key_links:
- from: Header
to: sensorStore
via: useSensorStore hook
- from: BatteryStatus
to: VoltageDisplay
via: Status color based on voltage level
---
Create the Header component and voltage monitoring components with modern styling, touch-friendly sizing, and status indicators.
Purpose: The header is the primary information display area, showing station status, voltage, and login state. These components are used across all views.
Output: Header.tsx, VoltageDisplay.tsx, BatteryStatus.tsx components with tests, all meeting touch target requirements.
@./.opencode/get-shit-done/workflows/execute-plan.md
@./.opencode/get-shit-done/templates/summary.md
@.planning/phases/01-foundation-dashboard/01-CONTEXT.md
@.planning/phases/01-foundation-dashboard/01-01-SUMMARY.md
@sample_interface/src/app/components/Header.tsx
## Key Implementation Details
**Header Layout (compact for 1024x600):**
```
[TCK Logo] [Station ID] [Version] [Solar: XX.XV] [Battery: XX.XV] [Status]
[HH:MM:SS] [YYYY-MM-DD] [ASU: XX] [Login: ●]
```
**Voltage Display:**
- Format: XX.XV (one decimal place)
- Solar voltage: Always shown
- Battery voltage: With status indicator
**Battery Status:**
- HIGH (≥12.0V): Green indicator
- LOW (<12.0V): Red/orange indicator
- Threshold: 12.0V configurable
**Touch Targets:**
- All interactive elements: minimum 44px height
- Prefer 56px for primary actions
- Use padding not margin for hit areas
**Design Tokens:**
- Use existing Tailwind classes
- shadcn/ui Badge for status indicators
- Lucide icons for visual elements
task 1: Create VoltageDisplay component
src/app/components/VoltageDisplay.tsx, src/app/components/__tests__/VoltageDisplay.test.tsx
- Displays voltage with one decimal place
- Shows label (Solar/Battery)
- Updates when sensor data changes
- Touch-friendly container (44px min)
1. Create src/app/components/VoltageDisplay.tsx:
- Props: label (string), voltage (number), className (optional)
- Format voltage to XX.XV
- Use flex layout with gap-2
- Min-height 44px for touch
- Use text-sm for compact display
- Add voltage icon from Lucide (Zap or Battery)
2. Create tests:
- Renders label and formatted voltage
- Updates on prop change
- Has minimum touch target size
npm test -- --run VoltageDisplay 2>&1 | grep -E "(PASS|FAIL|✓|✗)"
VoltageDisplay component created with tests passing
task 2: Create BatteryStatus component
src/app/components/BatteryStatus.tsx, src/app/components/__tests__/BatteryStatus.test.tsx
- Shows battery voltage with status badge
- HIGH status (≥12V): green badge
- LOW status (<12V): red/orange badge
- Status text visible: HIGH or LOW
1. Create src/app/components/BatteryStatus.tsx:
- Props: voltage (number), threshold (optional, default 12.0)
- Calculate status based on threshold
- Use shadcn/ui Badge component
- Green variant for HIGH, destructive for LOW
- Display "XX.XV - HIGH/LOW" format
- Touch-friendly (44px min)
2. Create tests:
- Shows HIGH for voltage ≥12.0
- Shows LOW for voltage <12.0
- Uses custom threshold if provided
- Updates when voltage changes
npm test -- --run BatteryStatus 2>&1 | grep -E "(PASS|FAIL|✓|✗)"
BatteryStatus component created with color-coded indicators
task 3: Modernize Header component
src/app/components/Header.tsx, src/app/components/__tests__/Header.test.tsx
- Displays TCK logo from /logo/
- Shows station ID and version
- Shows current time (HH:MM:SS) updating every second
- Shows current date (YYYY-MM-DD)
- Shows solar voltage
- Shows battery voltage with status
- Shows communication ASU
- Shows login status indicator
- All in compact layout for 1024x600
1. Update/modernize src/app/components/Header.tsx:
- Import useSensorStore from stores
- Import VoltageDisplay and BatteryStatus
- Use useEffect for clock updates (1s interval)
- Layout: Logo | Station Info | Time/Date | Voltages | Comm | Login
- Use flexbox with justify-between
- Compact padding (py-2 px-4)
- Use text-sm throughout
- Login indicator: green dot when logged in
- Cleanup clock interval on unmount
2. Create tests:
- Renders all required elements
- Time updates every second
- Uses sensor store data
- Has proper structure
npm test -- --run Header 2>&1 | grep -E "(PASS|FAIL|✓|✗)"
Header component displays all status info, tests pass
task 4: Verify touch target sizing
src/app/components/Header.tsx, src/app/components/VoltageDisplay.tsx, src/app/components/BatteryStatus.tsx
- All interactive elements ≥44px
- Verified via CSS inspection
- Document any exceptions
1. Review all components for touch target compliance:
- Check min-height on containers
- Check padding on clickable elements
- Ensure no margins-only hit areas
2. Add explicit classes where needed:
- `min-h-[44px]` for touch targets
- `flex items-center` for vertical centering
3. Run visual verification:
- DevTools element picker
- Verify minimum dimensions
grep -n "min-h-\[44px\]\|min-h-11\|h-11\|h-\[44px\]" src/app/components/Header.tsx src/app/components/VoltageDisplay.tsx src/app/components/BatteryStatus.tsx 2>/dev/null | wc -l
All components have minimum 44px touch targets
task 5: Update DashboardLayout to use new Header
src/app/components/DashboardLayout.tsx
- DashboardLayout imports and renders new Header
- Layout works with Sidebar
- Content area scrollable
1. Update src/app/components/DashboardLayout.tsx:
- Import new Header component
- Place Header above main content area
- Ensure flex layout works correctly
- Test with both kiosk and remote modes
2. Verify integration:
- Header displays correctly
- Sidebar navigation still works
- Main content has proper padding
grep -n "import.*Header\|
DashboardLayout integrates new Header component
After completing all tasks:
1. Run `npm test` — all tests should pass
2. Verify components exist: `ls src/app/components/Header.tsx src/app/components/VoltageDisplay.tsx src/app/components/BatteryStatus.tsx`
3. Check touch targets: `grep -r "min-h-" src/app/components/*.tsx | grep -E "(Header|Voltage|Battery)"`
4. Verify Header integration: `grep "
- VoltageDisplay component shows formatted voltage (XX.XV)
- BatteryStatus component shows color-coded HIGH/LOW status
- Header displays all required info: Logo, Station ID, Version, Time, Date, Solar, Battery, Comm, Login
- All touch targets minimum 44px
- Components tested and passing
- DashboardLayout uses new Header