From f3db7d36545fa0db74249fc13e24d6cf616af855 Mon Sep 17 00:00:00 2001 From: "Gan, Jimmy" Date: Thu, 19 Feb 2026 02:29:25 +0800 Subject: [PATCH] Dashboard UI overhaul: modern design with system stats, SVG icons, Inter font, theme toggle, loading states, and log modal --- dashboard/backend/main.py | 3 +- dashboard/backend/requirements.txt | 5 +- dashboard/backend/routers/system.py | 38 ++++ dashboard/frontend/index.html | 8 +- dashboard/frontend/src/App.svelte | 36 ++-- dashboard/frontend/src/app.css | 63 +++++++ .../frontend/src/components/Sidebar.svelte | 106 ++++++++--- dashboard/frontend/src/lib/api.js | 38 +++- .../frontend/src/routes/Dashboard.svelte | 171 ++++++++++++++++-- dashboard/frontend/src/routes/Docker.svelte | 159 ++++++++++++---- dashboard/frontend/src/routes/Files.svelte | 162 +++++++++++++---- dashboard/frontend/src/routes/Gitea.svelte | 132 +++++++++++--- dashboard/frontend/src/routes/Terminal.svelte | 121 +++++++++---- 13 files changed, 854 insertions(+), 188 deletions(-) create mode 100644 dashboard/backend/routers/system.py diff --git a/dashboard/backend/main.py b/dashboard/backend/main.py index fe1cc82..042ed05 100644 --- a/dashboard/backend/main.py +++ b/dashboard/backend/main.py @@ -1,10 +1,11 @@ from fastapi import FastAPI from fastapi.staticfiles import StaticFiles -from routers import docker_router, gitea, files, terminal +from routers import docker_router, gitea, files, terminal, system app = FastAPI(title="NAS Dashboard") app.include_router(docker_router.router, prefix="/api/docker") app.include_router(gitea.router, prefix="/api/gitea") app.include_router(files.router, prefix="/api/files") +app.include_router(system.router, prefix="/api/system") app.add_api_websocket_route("/ws/terminal", terminal.ws_endpoint) app.mount("/", StaticFiles(directory="/app/static", html=True), name="static") diff --git a/dashboard/backend/requirements.txt b/dashboard/backend/requirements.txt index 0c8e8ec..6cc3804 100644 --- a/dashboard/backend/requirements.txt +++ b/dashboard/backend/requirements.txt @@ -1,5 +1,6 @@ fastapi==0.115.0 -uvicorn==0.30.6 +uvicorn[standard]==0.30.0 docker==7.1.0 -httpx==0.27.2 +httpx==0.27.0 python-multipart==0.0.9 +psutil==6.1.0 diff --git a/dashboard/backend/routers/system.py b/dashboard/backend/routers/system.py new file mode 100644 index 0000000..408dabf --- /dev/null +++ b/dashboard/backend/routers/system.py @@ -0,0 +1,38 @@ +import shutil +import psutil +import platform +import time +from fastapi import APIRouter + +router = APIRouter() + + +@router.get("/stats") +def system_stats(): + disk = shutil.disk_usage("/volume1") + mem = psutil.virtual_memory() + cpu_pct = psutil.cpu_percent(interval=0.5) + load_1, load_5, load_15 = psutil.getloadavg() + uptime_s = time.time() - psutil.boot_time() + + days = int(uptime_s // 86400) + hours = int((uptime_s % 86400) // 3600) + + return { + "cpu_percent": cpu_pct, + "cpu_count": psutil.cpu_count(), + "load_avg": [round(load_1, 2), round(load_5, 2), round(load_15, 2)], + "memory": { + "total": mem.total, + "used": mem.used, + "percent": mem.percent, + }, + "disk": { + "total": disk.total, + "used": disk.used, + "free": disk.free, + "percent": round(disk.used / disk.total * 100, 1), + }, + "uptime": f"{days}d {hours}h", + "platform": platform.platform(), + } diff --git a/dashboard/frontend/index.html b/dashboard/frontend/index.html index a12e24f..e1cb4a1 100644 --- a/dashboard/frontend/index.html +++ b/dashboard/frontend/index.html @@ -1,9 +1,13 @@ - - + + + NAS Dashboard + + +
diff --git a/dashboard/frontend/src/App.svelte b/dashboard/frontend/src/App.svelte index 6bc69c0..41f1f61 100644 --- a/dashboard/frontend/src/App.svelte +++ b/dashboard/frontend/src/App.svelte @@ -7,21 +7,29 @@ import Terminal from "./routes/Terminal.svelte"; let page = $state("dashboard"); + let dark = $state(false); + + function toggleTheme() { + dark = !dark; + document.documentElement.classList.toggle("dark", dark); + } -
- -
- {#if page === "dashboard"} - - {:else if page === "docker"} - - {:else if page === "gitea"} - - {:else if page === "files"} - - {:else if page === "terminal"} - - {/if} +
+ +
+
+ {#if page === "dashboard"} + + {:else if page === "docker"} + + {:else if page === "gitea"} + + {:else if page === "files"} + + {:else if page === "terminal"} + + {/if} +
diff --git a/dashboard/frontend/src/app.css b/dashboard/frontend/src/app.css index f1d8c73..28e114e 100644 --- a/dashboard/frontend/src/app.css +++ b/dashboard/frontend/src/app.css @@ -1 +1,64 @@ @import "tailwindcss"; + +@theme { + --font-sans: "Inter", system-ui, -apple-system, sans-serif; + + --color-primary-50: #eef2ff; + --color-primary-100: #e0e7ff; + --color-primary-200: #c7d2fe; + --color-primary-300: #a5b4fc; + --color-primary-400: #818cf8; + --color-primary-500: #6366f1; + --color-primary-600: #4f46e5; + --color-primary-700: #4338ca; + + --color-surface-50: #f8fafc; + --color-surface-100: #f1f5f9; + --color-surface-200: #e2e8f0; + --color-surface-300: #cbd5e1; + --color-surface-400: #94a3b8; + --color-surface-500: #64748b; + --color-surface-600: #475569; + --color-surface-700: #334155; + --color-surface-800: #1e293b; + --color-surface-900: #0f172a; + + --color-emerald-400: #34d399; + --color-emerald-500: #10b981; + --color-emerald-600: #059669; + --color-amber-400: #fbbf24; + --color-amber-500: #f59e0b; + --color-rose-400: #fb7185; + --color-rose-500: #f43f5e; + --color-sky-400: #38bdf8; + --color-sky-500: #0ea5e9; +} + +* { + box-sizing: border-box; +} + +html { + font-family: var(--font-sans); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +body { + margin: 0; + background: var(--color-surface-50); + color: var(--color-surface-800); +} + +/* Scrollbar styling */ +::-webkit-scrollbar { width: 6px; height: 6px; } +::-webkit-scrollbar-track { background: transparent; } +::-webkit-scrollbar-thumb { background: var(--color-surface-300); border-radius: 3px; } +::-webkit-scrollbar-thumb:hover { background: var(--color-surface-400); } + +/* Dark mode overrides */ +.dark body, +.dark { + background: var(--color-surface-900); + color: var(--color-surface-200); +} diff --git a/dashboard/frontend/src/components/Sidebar.svelte b/dashboard/frontend/src/components/Sidebar.svelte index fce0a0c..e0968ea 100644 --- a/dashboard/frontend/src/components/Sidebar.svelte +++ b/dashboard/frontend/src/components/Sidebar.svelte @@ -1,42 +1,106 @@ -