From 2e0bf435fe71791a7985e78d15b224e1e73d749e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Guti=C3=A9rrez?= <35082514+alezmad@users.noreply.github.com> Date: Tue, 3 Feb 2026 22:47:50 +0100 Subject: [PATCH] Reorder Overview layout: charts hero, remove redundant health card - System Trends promoted to full-width hero row (most important info first) - Uptime and load average moved into Trends card header - Removed separate System Health card (redundant with VitalsBar + Trends) - Services + Deployments in row 2, Quick Links + WhyRating in row 3 - Taller charts (h-20), tighter gaps, cleaner visual hierarchy Co-Authored-By: Claude Opus 4.5 --- src/components/OverviewTab.tsx | 122 +++++--------------------------- src/components/SystemTrends.tsx | 44 ++++++++---- 2 files changed, 49 insertions(+), 117 deletions(-) diff --git a/src/components/OverviewTab.tsx b/src/components/OverviewTab.tsx index 1316501..bd90ff1 100644 --- a/src/components/OverviewTab.tsx +++ b/src/components/OverviewTab.tsx @@ -3,37 +3,10 @@ import { usePortal } from '@/lib/PortalContext'; import { Icon } from './Icons'; import { SystemTrends } from './SystemTrends'; -import { getVitalsBg, getVitalsTrack, formatUptime } from '@/lib/stats'; +import { formatUptime } from '@/lib/stats'; import { STATUS_COLORS, STATUS_LABELS, formatRelativeTime, formatDuration } from '@/lib/deployments'; import type { DeploymentStatus } from '@/lib/deployments'; -function StatBar({ label, percent, used, total, unit }: { - label: string; - percent: number; - used: string; - total: string; - unit: string; -}) { - const bg = getVitalsBg(percent); - const track = getVitalsTrack(percent); - - return ( -
-
- {label} - {Math.round(percent)}% -
-
-
-
-

{used} / {total} {unit}

-
- ); -} - const quickLinks = [ { name: 'Coolify', url: 'http://192.168.1.3:8000', icon: 'coolify', desc: 'Service manager' }, { name: 'Dozzle', url: 'http://192.168.1.3:9999', icon: 'scroll-text', desc: 'Container logs' }, @@ -52,7 +25,6 @@ const whyratingApps = [ export function OverviewTab() { const { systemStats, - statsLoading, services, healthStatus, deployments, @@ -68,69 +40,17 @@ export function OverviewTab() { const isDiscovered = discoveredServices.length > 0; return ( -
- {/* System Health */} -
-

- - System Health -

+
- {statsLoading && !systemStats ? ( -
- {[1, 2, 3].map(i => ( -
-
-
-
-
- ))} -
- ) : systemStats ? ( -
- - - - {systemStats.swap_percent > 50 && ( - - )} -
- Uptime: {formatUptime(systemStats.uptime_seconds)} - Load: {systemStats.load_avg.join(' / ')} -
-
- ) : ( -

Stats unavailable

- )} -
+ {/* Row 1: System Trends (full-width hero) with live stats in header */} + - {/* Service Summary */} + {/* Row 2 left: Services */}
-

+

Services {isDiscovered && ( @@ -140,12 +60,12 @@ export function OverviewTab() { )}

-
+
{runningCount} of {totalCount} running
-
+
{runningCount} running @@ -164,7 +84,6 @@ export function OverviewTab() { )}
- {/* Mini service status dots */}
{services.map(s => { const status = healthStatus[s.name]; @@ -180,12 +99,9 @@ export function OverviewTab() {
- {/* System Trends (6h from Prometheus) */} - - - {/* Recent Deployments */} + {/* Row 2 right: Recent Deployments */}
-

+

Recent Deployments

@@ -227,9 +143,9 @@ export function OverviewTab() { )}
- {/* Quick Links */} + {/* Row 3 left: Quick Links */}
-

+

Quick Links

@@ -253,14 +169,14 @@ export function OverviewTab() {
- {/* WhyRating Project */} -
-

+ {/* Row 3 right: WhyRating Project */} +
+

WhyRating Project

-
+
{whyratingApps.map(app => { const svc = services.find(s => s.url === app.url); const status = svc ? healthStatus[svc.name] : undefined; diff --git a/src/components/SystemTrends.tsx b/src/components/SystemTrends.tsx index 522eb11..a07d04f 100644 --- a/src/components/SystemTrends.tsx +++ b/src/components/SystemTrends.tsx @@ -30,7 +30,7 @@ function useMetrics() { useEffect(() => { refresh(); - const interval = setInterval(refresh, 60000); // refresh every 60s + const interval = setInterval(refresh, 60000); return () => clearInterval(interval); }, [refresh]); @@ -58,13 +58,13 @@ function SparkChart({ label, series, color, fillColor, formatValue, domain, unit return (
-
+
{label} - + {formatValue(lastVal)}{unit || ''}
-
+
@@ -116,28 +116,43 @@ function SparkChart({ label, series, color, fillColor, formatValue, domain, unit function ShimmerChart() { return (
-
+
-
+
); } -export function SystemTrends() { +interface SystemTrendsProps { + uptimeLabel?: string; + loadAvg?: [number, number, number]; +} + +export function SystemTrends({ uptimeLabel, loadAvg }: SystemTrendsProps) { const { data, loading, error } = useMetrics(); if (error && !data) return null; return (
+ {/* Header with title, live stats, and Grafana link */}
-

- - System Trends - 6h -

+
+

+ + System Trends + 6h +

+ {(uptimeLabel || loadAvg) && ( +
+ + {uptimeLabel && Up {uptimeLabel}} + {loadAvg && Load {loadAvg.map(v => v.toFixed(1)).join(' ')}} +
+ )} +
+ {/* Charts */} {loading && !data ? ( -
+
) : data ? ( -
+