fix(ui): Header branding, sidebar collapse, and layout fitting 1024x600
- Header: Change 'Data Station' to 'RTU', use TCK logo, fix sizing - Sidebar: MENU text now clickable to collapse/expand - RainfallView: Fit 1024x600 without scrolling - GraphView: Fit 1024x600 screen
This commit is contained in:
@@ -103,7 +103,8 @@ None - ready to begin Phase 1 planning.
|
||||
| # | Description | Date | Commit | Directory |
|
||||
|---|-------------|------|--------|-----------|
|
||||
| 1 | Create start.sh script with menu for test, dev, etc. | 2026-03-13 | b474f70 | [1-create-start-sh-script-with-menu-for-tes](./quick/1-create-start-sh-script-with-menu-for-tes/) |
|
||||
| 2 | Update start.sh for network access and port configuration | 2026-03-13 | - | [2-update-start-sh-for-network-access-and-p](./quick/2-update-start-sh-for-network-access-and-p/) |
|
||||
| 2 | Update start.sh for network access and port configuration | 2026-03-13 | e327ab9 | [2-update-start-sh-for-network-access-and-p](./quick/2-update-start-sh-for-network-access-and-p/) |
|
||||
| 3 | Fix UI feedback: header, navigation, and layout issues | 2026-03-13 | - | [3-fix-ui-feedback-header-navigation-and-la](./quick/3-fix-ui-feedback-header-navigation-and-la/) |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
plan: 1
|
||||
type: quick
|
||||
files_modified:
|
||||
- sample_interface/src/app/components/Header.tsx
|
||||
- sample_interface/src/app/components/Sidebar.tsx
|
||||
- sample_interface/src/app/components/views/RainfallView.tsx
|
||||
- sample_interface/src/app/components/views/GraphView.tsx
|
||||
---
|
||||
|
||||
<objective>
|
||||
Fix UI feedback: header branding, navigation collapse, and layout fitting 1024x600
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
User feedback:
|
||||
1. Header: Change "Data Station" to "RTU", use @logo/[LOGO] TCK.svg for logo, fix Solar/Battery box sizing
|
||||
2. Navigation: Make "Menu" text clickable to collapse sidebar, not just the icon
|
||||
3. RainfallView: Remove extra space before title, fit to 1024x600 without scrolling
|
||||
4. GraphView: Fit to 1024x600 screen
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task>
|
||||
<name>Fix Header branding and sizing</name>
|
||||
<files>sample_interface/src/app/components/Header.tsx</files>
|
||||
<action>
|
||||
1. Change "Data Station" text to "RTU"
|
||||
2. Use @logo/[LOGO] TCK.svg as logo (need to check correct path)
|
||||
3. Fix Solar/Battery boxes to match other header items size (same row, consistent height)
|
||||
4. Ensure all header items fit in 1-2 rows with compact height
|
||||
</action>
|
||||
<verify>grep -E "RTU|Data Station" sample_interface/src/app/components/Header.tsx</verify>
|
||||
<done>Header shows RTU branding with correct logo and sizing</done>
|
||||
</task>
|
||||
|
||||
<task>
|
||||
<name>Fix Sidebar collapse behavior</name>
|
||||
<files>sample_interface/src/app/components/Sidebar.tsx</files>
|
||||
<action>
|
||||
1. Make "Menu" text clickable to toggle collapse (not just the icon)
|
||||
2. Ensure collapse/expand works on click
|
||||
</action>
|
||||
<verify>grep -E "Menu|collapse" sample_interface/src/app/components/Sidebar.tsx | head -5</verify>
|
||||
<done>Sidebar Menu text is clickable</done>
|
||||
</task>
|
||||
|
||||
<task>
|
||||
<name>Fix RainfallView layout</name>
|
||||
<files>sample_interface/src/app/components/views/RainfallView.tsx</files>
|
||||
<action>
|
||||
1. Remove extra space/padding before title
|
||||
2. Reduce padding/margins to fit 1024x600 without scrolling
|
||||
3. Make Last Update section visible without page down
|
||||
</action>
|
||||
<verify>grep "p-" RainfallView.tsx | head -5</verify>
|
||||
<done>RainfallView fits 1024x600 screen</done>
|
||||
</task>
|
||||
|
||||
<task>
|
||||
<name>Fix GraphView layout</name>
|
||||
<files>sample_interface/src/app/components/views/GraphView.tsx</files>
|
||||
<action>
|
||||
1. Adjust layout to fit 1024x600 screen
|
||||
2. Reduce padding/margins as needed
|
||||
</action>
|
||||
<verify>ls -la sample_interface/src/app/components/views/GraphView.tsx</verify>
|
||||
<done>GraphView fits 1024x600 screen</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<success_criteria>
|
||||
- Header shows "RTU" with TCK logo
|
||||
- Header items (Solar/Battery) same size as Time/Date/Station
|
||||
- Sidebar Menu text toggles collapse
|
||||
- RainfallView fits 1024x600 without scrolling
|
||||
- GraphView fits 1024x600
|
||||
</success_criteria>
|
||||
@@ -0,0 +1,38 @@
|
||||
# Quick Task 3 Summary - UI Fixes
|
||||
|
||||
**Task:** Fix UI feedback: header, navigation, and layout issues
|
||||
**Date:** 2026-03-13
|
||||
**Status:** Complete
|
||||
|
||||
---
|
||||
|
||||
## Completed
|
||||
|
||||
### Task 1: Fix Header branding and sizing
|
||||
- Changed "Data Station" text to "RTU"
|
||||
- Added TCK logo from `/logo/[LOGO] TCK.svg`
|
||||
- Made all header items (Solar, Battery, Time, Date, Station, etc.) same size with consistent padding
|
||||
- Reduced header height to fit better
|
||||
|
||||
### Task 2: Fix Sidebar collapse behavior
|
||||
- Made MENU text clickable (not just the chevron icon)
|
||||
- Clicking MENU now toggles sidebar collapse/expand
|
||||
|
||||
### Task 3: Fix RainfallView layout
|
||||
- Removed extra space before title
|
||||
- Reduced padding to fit 1024x600 screen
|
||||
- Made Last Update section visible without scrolling
|
||||
|
||||
### Task 4: Fix GraphView layout
|
||||
- Reduced padding and spacing
|
||||
- Made chart smaller to fit 1024x600
|
||||
- Reduced stat cards size
|
||||
|
||||
---
|
||||
|
||||
## Files Modified
|
||||
|
||||
- `sample_interface/src/app/components/Header.tsx`
|
||||
- `sample_interface/src/app/components/Sidebar.tsx`
|
||||
- `sample_interface/src/app/components/views/RainfallView.tsx`
|
||||
- `sample_interface/src/app/components/views/GraphView.tsx`
|
||||
@@ -4,6 +4,7 @@ import { useSensorStore } from "../stores/sensorStore";
|
||||
import { VoltageDisplay } from "./VoltageDisplay";
|
||||
import { BatteryStatus } from "./BatteryStatus";
|
||||
import { LoginIndicator } from "./LoginIndicator";
|
||||
import TCKLogo from "../../../../logo/[LOGO] TCK.svg?react";
|
||||
|
||||
export function Header() {
|
||||
const [currentTime, setCurrentTime] = useState(new Date());
|
||||
@@ -34,36 +35,36 @@ export function Header() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-gray-950 border-b border-gray-700 px-4 py-2 flex items-center gap-4 text-xs">
|
||||
<div className="bg-gray-950 border-b border-gray-700 px-2 py-1 flex items-center gap-2 text-xs">
|
||||
{/* Logo */}
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-8 h-8 bg-blue-600 rounded flex items-center justify-center font-bold text-white">
|
||||
DS
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="w-6 h-6">
|
||||
<TCKLogo className="w-full h-full" />
|
||||
</div>
|
||||
<span className="text-white font-semibold hidden sm:inline">Data Station</span>
|
||||
<span className="text-white font-semibold">RTU</span>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 flex items-center gap-4 justify-end flex-wrap">
|
||||
<div className="flex-1 flex items-center gap-2 justify-end">
|
||||
{/* Time */}
|
||||
<div className="flex items-center gap-2 px-2 py-1 bg-gray-800 rounded">
|
||||
<div className="flex items-center gap-1 px-2 py-1 bg-gray-800 rounded">
|
||||
<span className="text-gray-400">Time:</span>
|
||||
<span className="text-green-400 font-mono font-semibold">{formatTime(currentTime)}</span>
|
||||
</div>
|
||||
|
||||
{/* Date */}
|
||||
<div className="flex items-center gap-2 px-2 py-1 bg-gray-800 rounded">
|
||||
<div className="flex items-center gap-1 px-2 py-1 bg-gray-800 rounded">
|
||||
<span className="text-gray-400">Date:</span>
|
||||
<span className="text-blue-400 font-mono font-semibold">{formatDate(currentTime)}</span>
|
||||
</div>
|
||||
|
||||
{/* Station ID */}
|
||||
<div className="flex items-center gap-2 px-2 py-1 bg-gray-800 rounded">
|
||||
<div className="flex items-center gap-1 px-2 py-1 bg-gray-800 rounded">
|
||||
<span className="text-gray-400">Station:</span>
|
||||
<span className="text-white font-semibold">{data.station.id}</span>
|
||||
</div>
|
||||
|
||||
{/* Comm Status */}
|
||||
<div className="flex items-center gap-2 px-2 py-1 bg-gray-800 rounded">
|
||||
<div className="flex items-center gap-1 px-2 py-1 bg-gray-800 rounded">
|
||||
{isOnline ? (
|
||||
<>
|
||||
<Wifi className="w-3 h-3 text-green-500" />
|
||||
@@ -80,7 +81,7 @@ export function Header() {
|
||||
</div>
|
||||
|
||||
{/* Version */}
|
||||
<div className="flex items-center gap-2 px-2 py-1 bg-gray-800 rounded">
|
||||
<div className="flex items-center gap-1 px-2 py-1 bg-gray-800 rounded">
|
||||
<span className="text-gray-400">Ver:</span>
|
||||
<span className="text-white">{data.station.version}</span>
|
||||
</div>
|
||||
@@ -89,10 +90,21 @@ export function Header() {
|
||||
<LoginIndicator isLoggedIn={isLoggedIn} />
|
||||
|
||||
{/* Solar Voltage */}
|
||||
<VoltageDisplay label="Solar" voltage={data.voltage.solar} />
|
||||
<div className="flex items-center gap-1 px-2 py-1 bg-gray-800 rounded">
|
||||
<span className="text-gray-400">Solar:</span>
|
||||
<span className="text-yellow-500 font-mono">{data.voltage.solar.toFixed(1)}V</span>
|
||||
</div>
|
||||
|
||||
{/* Battery Voltage */}
|
||||
<BatteryStatus voltage={data.voltage.battery} />
|
||||
<div className="flex items-center gap-1 px-2 py-1 bg-gray-800 rounded">
|
||||
<span className="text-gray-400">Battery:</span>
|
||||
<span className={`font-mono ${data.voltage.batteryStatus === 'HIGH' ? 'text-green-500' : 'text-red-500'}`}>
|
||||
{data.voltage.battery.toFixed(1)}V
|
||||
</span>
|
||||
<span className={`text-xs px-1 rounded ${data.voltage.batteryStatus === 'HIGH' ? 'bg-green-500/20 text-green-500' : 'bg-red-500/20 text-red-500'}`}>
|
||||
{data.voltage.batteryStatus}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -117,13 +117,13 @@ export function Sidebar({ collapsed, onToggle }: SidebarProps) {
|
||||
collapsed ? "w-16" : "w-64"
|
||||
}`}
|
||||
>
|
||||
<div className="p-3 border-b border-gray-700 flex items-center justify-between">
|
||||
{!collapsed && <span className="text-white font-bold text-sm">MENU</span>}
|
||||
<div className="p-2 border-b border-gray-700 flex items-center justify-between">
|
||||
<button
|
||||
onClick={onToggle}
|
||||
className="p-1.5 hover:bg-gray-800 rounded text-gray-400 hover:text-white transition-colors"
|
||||
className="flex items-center gap-2 text-white font-bold text-sm hover:bg-gray-800 px-2 py-1 rounded transition-colors"
|
||||
>
|
||||
<ChevronRight className={`w-4 h-4 transition-transform ${collapsed ? "" : "rotate-180"}`} />
|
||||
{!collapsed && <span>MENU</span>}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -3,45 +3,45 @@ import { BarChart3 } from "lucide-react";
|
||||
|
||||
export function GraphView() {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<BarChart3 className="w-6 h-6 text-blue-400" />
|
||||
<h1 className="text-2xl font-bold text-white">Graph View</h1>
|
||||
<div className="h-full p-1">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<BarChart3 className="w-5 h-5 text-blue-400" />
|
||||
<h1 className="text-lg font-bold text-white">Graph View</h1>
|
||||
</div>
|
||||
|
||||
<Card className="bg-gray-900 border-gray-700">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-white">Data Visualization</CardTitle>
|
||||
<Card className="bg-gray-900 border-gray-700 mb-2">
|
||||
<CardHeader className="py-2">
|
||||
<CardTitle className="text-white text-sm">Data Visualization</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="h-64 bg-gray-800 rounded flex items-center justify-center">
|
||||
<span className="text-gray-500">Chart visualization area</span>
|
||||
<CardContent className="py-2">
|
||||
<div className="h-32 bg-gray-800 rounded flex items-center justify-center">
|
||||
<span className="text-gray-500 text-sm">Chart visualization area</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
<Card className="bg-gray-900 border-gray-700">
|
||||
<CardContent className="pt-6">
|
||||
<CardContent className="py-3">
|
||||
<div className="text-center">
|
||||
<div className="text-2xl font-bold text-blue-400">24h</div>
|
||||
<div className="text-sm text-gray-400 mt-1">Time Range</div>
|
||||
<div className="text-xl font-bold text-blue-400">24h</div>
|
||||
<div className="text-xs text-gray-400">Time Range</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="bg-gray-900 border-gray-700">
|
||||
<CardContent className="pt-6">
|
||||
<CardContent className="py-3">
|
||||
<div className="text-center">
|
||||
<div className="text-2xl font-bold text-green-400">156</div>
|
||||
<div className="text-sm text-gray-400 mt-1">Data Points</div>
|
||||
<div className="text-xl font-bold text-green-400">156</div>
|
||||
<div className="text-xs text-gray-400">Data Points</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="bg-gray-900 border-gray-700">
|
||||
<CardContent className="pt-6">
|
||||
<CardContent className="py-3">
|
||||
<div className="text-center">
|
||||
<div className="text-2xl font-bold text-purple-400">12.5</div>
|
||||
<div className="text-sm text-gray-400 mt-1">Avg Value</div>
|
||||
<div className="text-xl font-bold text-purple-400">12.5</div>
|
||||
<div className="text-xs text-gray-400">Avg Value</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "../ui/card";
|
||||
import { Droplets } from "lucide-react";
|
||||
import { useSensorStore } from "../../stores/sensorStore";
|
||||
import { RainfallCard } from "../RainfallCard";
|
||||
@@ -20,26 +19,24 @@ export function RainfallView() {
|
||||
const isKiosk = displayMode === 'kiosk';
|
||||
|
||||
return (
|
||||
<div className={`space-y-4 ${isKiosk ? 'p-2' : 'p-6'}`}>
|
||||
<div className="flex items-center justify-between flex-wrap gap-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<Droplets className="w-6 h-6 text-blue-400" />
|
||||
<h1 className={`font-bold text-white ${isKiosk ? 'text-lg' : 'text-2xl'}`}>
|
||||
Rainfall Monitor
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
<ClockDisplay />
|
||||
<CommStatus
|
||||
asu={data.communication.asu}
|
||||
dBm={data.communication.dBm}
|
||||
percentage={data.communication.percentage}
|
||||
/>
|
||||
</div>
|
||||
<div className={`h-full ${isKiosk ? 'p-1' : 'p-2'}`}>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Droplets className="w-5 h-5 text-blue-400" />
|
||||
<h1 className="font-bold text-white text-lg">
|
||||
Rainfall Monitor
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div className={`grid gap-4 ${isKiosk ? 'grid-cols-2' : 'grid-cols-4'}`}>
|
||||
<div className="flex items-center gap-4 mb-3">
|
||||
<ClockDisplay />
|
||||
<CommStatus
|
||||
asu={data.communication.asu}
|
||||
dBm={data.communication.dBm}
|
||||
percentage={data.communication.percentage}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={`grid gap-2 ${isKiosk ? 'grid-cols-2' : 'grid-cols-4'}`}>
|
||||
{rainfallItems.map((item) => (
|
||||
<RainfallCard
|
||||
key={item.label}
|
||||
@@ -50,16 +47,9 @@ export function RainfallView() {
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Card className="bg-gray-900 border-gray-700">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-white">Last Update</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-gray-400 font-mono">
|
||||
{new Date(data.timestamp).toLocaleString()}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<div className="mt-2 text-xs text-gray-500">
|
||||
Last Update: {new Date(data.timestamp).toLocaleString()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user