Redesign The Hub web UI: softer dark theme, sidebar nav, status widgets
Apply the approved "The Hub" redesign to the web admin while keeping every existing mechanic intact (polling, service-detail modals, Matrix and system password management, NWC wallet manager, update/rebuild/backup/security/ reboot flows, feature manager, onboarding, role handling). Layout (templates/index.html): - Old header bar + IP bar replaced by a sidebar + topbar app shell. Sidebar carries the brand (The Hub / Sovran_SystemsOS version), category navigation with live counts, the System actions (Update System, Tech Support, Manual Backup, Security, node-only Upgrade), Feature Manager / Preferences, and the role badge. - Topbar carries the page title, a service search box, the LAN | WAN network chip (external IP always visible, one line), Reboot and Sign Out. - New widgets row: Systems Operational summary (opens the new Systems Operational modal) and Bitcoin Core sync progress with block/ETA. - New Systems Operational modal: service counts, router port-forwarding steps (80/443 to this machine's LAN IP), the live domain diagnostics checklist, and which services use those ports. New static/js/dashboard.js (namespaced IIFE, no new globals) renders the nav, search filtering, widgets, and the Systems Operational modal; it is driven by the existing /api/services payloads via a window.dashboardServicesUpdated() hook called from buildTiles/updateTiles. Visual design (static/css/*): - New token set (softer dark surfaces, lifted contrast, Sovran green reserved for status and actions) with legacy variable names aliased so every secondary sheet re-skins automatically. - Tiles, dialogs, buttons, inputs, toggles, tables, forms, overlays and the login page restyled to the GNOME/libadwaita-flavored surfaces: 20px cards, 26px dialogs, pill buttons, libadwaita switches, mono value pills with Copy buttons, consistent modal anatomy. - Inline SVG symbol set for chrome/nav icons (monochrome, currentColor); service icons still load from /static/icons/*.svg as before. - Sidebar system buttons now use vector glyphs instead of emoji. Behavioral details: - Service detail modal header gains a status pill next to the version chip; credentials render with pre-wrap for multiline values. - First-login security banner now renders as a card inside the content area instead of a full-width strip above the app. - Search + category filtering hide/show sections and tiles without touching the polling or update logic. Onboarding and login pages rebranded to "The Hub" with aligned palette.
This commit is contained in:
@@ -5,34 +5,133 @@ button {
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
outline: none;
|
||||
transition: opacity 0.15s, box-shadow 0.15s, background-color 0.15s;
|
||||
transition: background 0.16s, border-color 0.16s, color 0.16s, transform 0.16s, filter 0.16s, opacity 0.15s;
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
opacity: 0.45;
|
||||
opacity: 0.55;
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 7px 16px;
|
||||
border-radius: var(--radius-btn);
|
||||
font-size: 0.88rem;
|
||||
font-weight: 600;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
border-radius: 99px;
|
||||
padding: 8px 18px;
|
||||
font-size: 0.84rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.01em;
|
||||
cursor: pointer;
|
||||
border: 1px solid transparent;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.btn svg { width: 15px; height: 15px; }
|
||||
.btn:active { transform: scale(0.97); }
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--accent-color);
|
||||
color: #0A1A10;
|
||||
background: linear-gradient(180deg, #3fd68e, #1ea263);
|
||||
color: #04220f;
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28), 0 6px 18px rgba(35, 199, 124, 0.22);
|
||||
}
|
||||
|
||||
.btn-primary:hover:not(:disabled) {
|
||||
opacity: 0.88;
|
||||
filter: brightness(1.08);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* Update System button: uses accent green by default */
|
||||
.btn-primary:active:not(:disabled) { transform: scale(0.97); }
|
||||
|
||||
/* Ghost — the default secondary action (legacy: btn-close-modal / btn-save) */
|
||||
.btn-ghost,
|
||||
.btn-close-modal,
|
||||
.btn-save {
|
||||
background: transparent;
|
||||
border-color: var(--border-strong);
|
||||
color: var(--text-2);
|
||||
}
|
||||
|
||||
.btn-ghost:hover:not(:disabled),
|
||||
.btn-close-modal:hover:not(:disabled),
|
||||
.btn-save:hover:not(:disabled) {
|
||||
color: var(--text);
|
||||
border-color: rgba(255, 255, 255, 0.26);
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
/* Amber — destructive-ish confirmations (restart, reboot, retry) */
|
||||
.btn-amber,
|
||||
.btn-reboot,
|
||||
.btn-restart-amber,
|
||||
.btn-warning {
|
||||
background: rgba(233, 182, 74, 0.10);
|
||||
border-color: rgba(233, 182, 74, 0.32);
|
||||
color: #f2c45e;
|
||||
}
|
||||
|
||||
.btn-amber:hover:not(:disabled),
|
||||
.btn-reboot:hover:not(:disabled),
|
||||
.btn-restart-amber:hover:not(:disabled),
|
||||
.btn-warning:hover:not(:disabled) {
|
||||
background: rgba(233, 182, 74, 0.18);
|
||||
border-color: rgba(233, 182, 74, 0.5);
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: rgba(246, 97, 81, 0.10);
|
||||
border-color: rgba(246, 97, 81, 0.35);
|
||||
color: #f8a39b;
|
||||
}
|
||||
|
||||
.btn-danger:hover:not(:disabled) {
|
||||
background: rgba(246, 97, 81, 0.18);
|
||||
border-color: rgba(246, 97, 81, 0.5);
|
||||
}
|
||||
|
||||
.btn-sm { padding: 6px 14px; font-size: 0.77rem; }
|
||||
|
||||
/* ── Header / topbar buttons ────────────────────────────────────── */
|
||||
|
||||
.btn-header-reboot {
|
||||
background: rgba(233, 182, 74, 0.10);
|
||||
border: 1px solid rgba(233, 182, 74, 0.32);
|
||||
color: #f2c45e;
|
||||
font-size: 0.77rem;
|
||||
font-weight: 700;
|
||||
padding: 6px 14px;
|
||||
border-radius: 99px;
|
||||
}
|
||||
|
||||
.btn-header-reboot:hover:not(:disabled) {
|
||||
background: rgba(233, 182, 74, 0.18);
|
||||
border-color: rgba(233, 182, 74, 0.5);
|
||||
}
|
||||
|
||||
.btn-logout {
|
||||
background: transparent;
|
||||
border: 1px solid var(--border-strong);
|
||||
color: var(--text-2);
|
||||
font-size: 0.77rem;
|
||||
font-weight: 700;
|
||||
padding: 6px 14px;
|
||||
border-radius: 99px;
|
||||
}
|
||||
|
||||
.btn-logout:hover {
|
||||
color: var(--text);
|
||||
border-color: rgba(255, 255, 255, 0.26);
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
/* ── Update System button (sidebar) ─────────────────────────────── */
|
||||
|
||||
.btn-update {
|
||||
background-color: #4A9474;
|
||||
color: #E0F2EA;
|
||||
background: transparent;
|
||||
border: 1px solid var(--border-strong);
|
||||
color: var(--text-2);
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -40,24 +139,22 @@ button:disabled {
|
||||
}
|
||||
|
||||
.btn-update:hover:not(:disabled) {
|
||||
opacity: 0.88;
|
||||
color: var(--text);
|
||||
border-color: rgba(255, 255, 255, 0.26);
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
/* Update System button: brighter green when updates are available */
|
||||
.btn-update.has-updates {
|
||||
background-color: #5EAD8A;
|
||||
color: #0A1A10;
|
||||
}
|
||||
|
||||
.btn-update.has-updates:hover:not(:disabled) {
|
||||
background-color: #78C8A2;
|
||||
background: rgba(66, 243, 154, 0.12);
|
||||
border-color: rgba(66, 243, 154, 0.4);
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.update-badge {
|
||||
display: none;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: var(--yellow);
|
||||
background-color: var(--amber);
|
||||
border-radius: 50%;
|
||||
animation: pulse-badge 1.4s ease-in-out infinite;
|
||||
}
|
||||
@@ -71,9 +168,11 @@ button:disabled {
|
||||
50% { opacity: 0.5; transform: scale(1.35); }
|
||||
}
|
||||
|
||||
/* ── Icon buttons ───────────────────────────────────────────────── */
|
||||
|
||||
.btn-icon {
|
||||
background: none;
|
||||
color: var(--text-secondary);
|
||||
color: var(--text-2);
|
||||
padding: 6px;
|
||||
border-radius: 50%;
|
||||
font-size: 1.1rem;
|
||||
@@ -81,6 +180,6 @@ button:disabled {
|
||||
}
|
||||
|
||||
.btn-icon:hover:not(:disabled) {
|
||||
background-color: var(--border-color);
|
||||
color: var(--text-primary);
|
||||
background-color: rgba(255, 255, 255, 0.06);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user