Redesign dashboard metrics: surface Redirect/Streaming hosts, fix Needs Attention status color, add marketing-site accent palette
This commit is contained in:
@@ -113,8 +113,13 @@ function renderDashboard() {
|
||||
$("#dash-proxy-detail").textContent = healthCopy(data.proxies, "routes");
|
||||
$("#dash-tls-total").textContent = data.tlsDomains;
|
||||
$("#dash-tls-detail").textContent = data.certificates.total ? `${data.certificates.healthy} healthy · ${data.certificates.pending} not detected` : "No TLS domains";
|
||||
$("#dash-redirect-total").textContent = state.redirects?.length || 0;
|
||||
$("#dash-stream-total").textContent = state.streams?.length || 0;
|
||||
$("#dash-attention-total").textContent = data.attention.length;
|
||||
$("#dash-attention-detail").textContent = data.attention.length ? `${data.attention.length} item${data.attention.length === 1 ? "" : "s"} to review` : "No current issues";
|
||||
$("#dash-attention-chip").classList.toggle("accent-warning", data.attention.length > 0);
|
||||
$("#dash-attention-chip").classList.toggle("accent-green", data.attention.length === 0);
|
||||
$("#dash-attention-icon").textContent = data.attention.length > 0 ? "!" : "✓";
|
||||
const hasErrors = data.attention.length > 0, isChecking = [data.gateway, data.services.http, data.services.https].some(service => service.status === "checking"), hasNothingRunning = !data.hosted.running && !data.proxies.running;
|
||||
const overall = $("#overall-health");
|
||||
overall.className = `health-badge ${hasErrors ? "error" : isChecking || hasNothingRunning ? "warning" : "healthy"}`;
|
||||
|
||||
@@ -74,10 +74,14 @@
|
||||
</header>
|
||||
<section id="dashboard-view" class="dashboard-view" aria-label="Gateway dashboard">
|
||||
<div class="metric-grid">
|
||||
<button class="metric-card" data-target="hosted"><span class="metric-label">Hosted sites</span><strong id="dash-hosted-total">0</strong><span id="dash-hosted-detail">None configured</span></button>
|
||||
<button class="metric-card" data-target="proxies"><span class="metric-label">Proxy hosts</span><strong id="dash-proxy-total">0</strong><span id="dash-proxy-detail">None configured</span></button>
|
||||
<button class="metric-card" data-target="certificates"><span class="metric-label">Certificates</span><strong id="dash-tls-total">0</strong><span id="dash-tls-detail">No TLS domains</span></button>
|
||||
<div class="metric-card attention"><span class="metric-label">Needs attention</span><strong id="dash-attention-total">0</strong><span id="dash-attention-detail">No current issues</span></div>
|
||||
<button class="metric-card accent-green" data-target="hosted"><span class="metric-label">Hosted sites</span><strong id="dash-hosted-total">0</strong><span id="dash-hosted-detail">None configured</span></button>
|
||||
<button class="metric-card accent-blue" data-target="proxies"><span class="metric-label">Proxy hosts</span><strong id="dash-proxy-total">0</strong><span id="dash-proxy-detail">None configured</span></button>
|
||||
<button class="metric-card accent-blue" data-target="certificates"><span class="metric-label">Certificates</span><strong id="dash-tls-total">0</strong><span id="dash-tls-detail">No TLS domains</span></button>
|
||||
</div>
|
||||
<div class="metric-strip">
|
||||
<button class="metric-chip accent-amber" data-target="redirects"><span class="chip-icon">↗</span><span class="chip-copy"><span class="metric-label">Redirect hosts</span><strong id="dash-redirect-total">0</strong></span></button>
|
||||
<button class="metric-chip accent-purple" data-target="streaming"><span class="chip-icon">▤</span><span class="chip-copy"><span class="metric-label">Streaming hosts</span><strong id="dash-stream-total">0</strong></span></button>
|
||||
<div class="metric-chip" id="dash-attention-chip"><span class="chip-icon" id="dash-attention-icon">◈</span><span class="chip-copy"><span class="metric-label">Needs attention</span><strong id="dash-attention-total">0</strong><small id="dash-attention-detail">No current issues</small></span></div>
|
||||
</div>
|
||||
<div class="dashboard-columns">
|
||||
<section class="dashboard-panel">
|
||||
|
||||
@@ -22,10 +22,10 @@ main{padding-top:24px}.utility-bar{display:flex;align-items:center;justify-conte
|
||||
.dialog-card input:not([type="checkbox"]):not([type="file"]),.dialog-card select{font:inherit;width:100%;height:44px;min-height:44px;padding:0 12px;line-height:42px;border-width:1px}.aside-footer strong{color:var(--text);font-weight:750}
|
||||
|
||||
/* Dashboard */
|
||||
.mobile-nav{display:none}.dashboard-view{margin-top:38px}.metric-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px}.metric-card{min-width:0;padding:20px;border:1px solid var(--line);border-radius:15px;background:linear-gradient(145deg,rgba(20,33,54,.95),rgba(13,23,39,.95));color:var(--text);text-align:left}.metric-card:is(button){cursor:pointer;transition:.2s}.metric-card:is(button):hover{transform:translateY(-2px);border-color:#3b5275}.metric-card .metric-label,.metric-card>span:last-child{display:block}.metric-card .metric-label{color:var(--muted);font-size:.78rem;font-weight:700}.metric-card strong{display:block;margin:13px 0 7px;font-size:2rem;line-height:1}.metric-card>span:last-child{color:var(--muted);font-size:.76rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.metric-card.attention strong{color:var(--warning)}.dashboard-columns{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:18px}.dashboard-columns.lower{align-items:start}.dashboard-panel{min-width:0;padding:22px;border:1px solid var(--line);border-radius:16px;background:rgba(16,26,43,.76)}.panel-heading{display:flex;align-items:center;justify-content:space-between;gap:15px;margin-bottom:20px}.panel-heading .eyebrow{margin-bottom:5px}.panel-heading h2{margin:0;font-size:1.2rem}.health-badge{padding:6px 9px;border-radius:999px;font-size:.7rem;font-weight:800}.health-badge.healthy{background:rgba(98,230,167,.12);color:var(--green)}.health-badge.warning{background:rgba(255,191,105,.12);color:var(--warning)}.health-badge.error{background:rgba(255,113,133,.12);color:var(--danger)}.health-list{display:grid;gap:3px}.health-list>div{display:flex;align-items:center;gap:13px;padding:13px 3px;border-top:1px solid var(--line)}.health-list>div:first-child{border-top:0}.health-list span:last-child,.dashboard-list-item span:last-child{display:grid;gap:3px}.health-list small,.dashboard-list-item small{color:var(--muted);font-size:.75rem}.system-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;margin:0}.system-grid div{min-width:0}.system-grid dt{color:var(--muted);font-size:.72rem}.system-grid dd{margin:6px 0 0;font-size:.9rem;font-weight:750;overflow:hidden;text-overflow:ellipsis}.dashboard-list{display:grid}.dashboard-list-item{display:flex;align-items:flex-start;gap:12px;padding:13px 3px;border-top:1px solid var(--line)}.dashboard-list-item:first-child{border-top:0}.dashboard-list-item strong{font-size:.82rem}.dashboard-list-item .status-dot{margin-top:4px;flex:0 0 auto}.activity-mark{display:grid;place-items:center;width:20px;height:20px;border-radius:50%;background:rgba(98,230,167,.12);color:var(--green);font-size:.7rem;font-weight:900}.quiet-state{color:var(--muted);font-size:.82rem;margin:3px 0}
|
||||
.mobile-nav{display:none}.dashboard-view{margin-top:38px}.metric-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}.metric-card{min-width:0;padding:20px;border:1px solid var(--line);border-radius:15px;background:linear-gradient(145deg,rgba(20,33,54,.95),rgba(13,23,39,.95));color:var(--text);text-align:left;position:relative;overflow:hidden}.metric-card::before{content:"";position:absolute;inset:0 0 auto 0;height:3px;background:var(--card-accent,var(--green));opacity:.85}.metric-card:focus{outline:none}.metric-card:focus-visible{outline:2px solid var(--green);outline-offset:-2px}.metric-card:is(button){cursor:pointer;transition:.2s}.metric-card:is(button):hover{transform:translateY(-2px);border-color:#3b5275;box-shadow:0 16px 40px rgba(0,0,0,.22)}.metric-card.accent-green{--card-accent:var(--green)}.metric-card.accent-blue{--card-accent:var(--blue)}.metric-card .metric-label,.metric-card>span:last-child{display:block}.metric-card .metric-label{color:var(--muted);font-size:.78rem;font-weight:700}.metric-card strong{display:block;margin:13px 0 7px;font-size:2rem;line-height:1}.metric-card>span:last-child{color:var(--muted);font-size:.76rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.metric-card.attention strong{color:var(--warning)}.metric-strip{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-top:12px}.metric-chip{display:flex;align-items:center;gap:12px;min-width:0;padding:13px 16px;border:1px solid var(--line);border-radius:13px;background:rgba(16,26,43,.76);color:var(--text);text-align:left;position:relative;overflow:hidden;transition:.2s}.metric-chip::before{content:"";position:absolute;inset:0 auto 0 0;width:3px;background:var(--card-accent,var(--muted));opacity:.9}.metric-chip:is(button){cursor:pointer}.metric-chip:is(button):hover{transform:translateY(-1px);border-color:#3b5275}.metric-chip:focus{outline:none}.metric-chip:focus-visible{outline:2px solid var(--green);outline-offset:-2px}.metric-chip .chip-icon{flex:0 0 auto;width:32px;height:32px;display:grid;place-items:center;border-radius:9px;background:color-mix(in srgb,var(--card-accent,var(--muted)) 20%,transparent);color:var(--card-accent,var(--muted));font-size:.85rem;font-weight:800}.metric-chip .chip-copy{display:flex;flex-direction:column;gap:2px;min-width:0}.metric-chip .metric-label{color:var(--muted);font-size:.72rem;font-weight:700}.metric-chip strong{font-size:1.3rem;line-height:1.1}.metric-chip small{color:var(--muted);font-size:.68rem}.metric-chip.accent-amber{--card-accent:var(--warning)}.metric-chip.accent-purple{--card-accent:#b59cff}.metric-chip.accent-warning{--card-accent:var(--warning)}.metric-chip.accent-warning strong{color:var(--warning)}.metric-chip.accent-green{--card-accent:var(--green)}.metric-chip.accent-green strong{color:var(--green)}.dashboard-columns{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:18px}.dashboard-columns.lower{align-items:start}.dashboard-panel{min-width:0;padding:22px;border:1px solid var(--line);border-radius:16px;background:rgba(16,26,43,.76)}.panel-heading{display:flex;align-items:center;justify-content:space-between;gap:15px;margin-bottom:20px}.panel-heading .eyebrow{margin-bottom:5px}.panel-heading h2{margin:0;font-size:1.2rem}.health-badge{padding:6px 9px;border-radius:999px;font-size:.7rem;font-weight:800}.health-badge.healthy{background:rgba(98,230,167,.12);color:var(--green)}.health-badge.warning{background:rgba(255,191,105,.12);color:var(--warning)}.health-badge.error{background:rgba(255,113,133,.12);color:var(--danger)}.health-list{display:grid;gap:3px}.health-list>div{display:flex;align-items:center;gap:13px;padding:13px 3px;border-top:1px solid var(--line)}.health-list>div:first-child{border-top:0}.health-list span:last-child,.dashboard-list-item span:last-child{display:grid;gap:3px}.health-list small,.dashboard-list-item small{color:var(--muted);font-size:.75rem}.system-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;margin:0}.system-grid div{min-width:0}.system-grid dt{color:var(--muted);font-size:.72rem}.system-grid dd{margin:6px 0 0;font-size:.9rem;font-weight:750;overflow:hidden;text-overflow:ellipsis}.dashboard-list{display:grid}.dashboard-list-item{display:flex;align-items:flex-start;gap:12px;padding:13px 3px;border-top:1px solid var(--line)}.dashboard-list-item:first-child{border-top:0}.dashboard-list-item strong{font-size:.82rem}.dashboard-list-item .status-dot{margin-top:4px;flex:0 0 auto}.activity-mark{display:grid;place-items:center;width:20px;height:20px;border-radius:50%;background:rgba(98,230,167,.12);color:var(--green);font-size:.7rem;font-weight:900}.quiet-state{color:var(--muted);font-size:.82rem;margin:3px 0}
|
||||
:root[data-theme="light"] .metric-card{background:linear-gradient(145deg,#fff,#f6f9fc)}:root[data-theme="light"] .dashboard-panel{background:rgba(255,255,255,.82)}
|
||||
@media(max-width:1100px){.metric-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.system-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
||||
@media(max-width:760px){.mobile-nav{display:grid;grid-template-columns:repeat(5,1fr);gap:5px;margin:0 0 30px;padding:4px;border:1px solid var(--line);border-radius:12px;background:var(--panel)}.mobile-nav button{justify-content:center;text-align:center;padding:9px 5px;font-size:.72rem}.dashboard-view{margin-top:30px}.metric-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.metric-card{padding:16px}.metric-card strong{font-size:1.65rem}.dashboard-columns{grid-template-columns:1fr}.system-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
||||
@media(max-width:1100px){.metric-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.system-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:1100px){.metric-strip{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
||||
@media(max-width:760px){.mobile-nav{display:grid;grid-template-columns:repeat(5,1fr);gap:5px;margin:0 0 30px;padding:4px;border:1px solid var(--line);border-radius:12px;background:var(--panel)}.mobile-nav button{justify-content:center;text-align:center;padding:9px 5px;font-size:.72rem}.dashboard-view{margin-top:30px}.metric-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.metric-card{padding:16px}.metric-card strong{font-size:1.65rem}.dashboard-columns{grid-template-columns:1fr}.system-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.metric-strip{grid-template-columns:1fr}.metric-chip{padding:11px 14px}}
|
||||
|
||||
.upstream-copy{margin:10px 0 0;color:var(--green);font-size:.72rem}.upstream-copy.bad{color:var(--danger)}.activity-mark.bad{background:rgba(255,113,133,.12);color:var(--danger)}.feature-view{margin-top:38px}.feature-summary{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;margin-bottom:18px}.feature-summary>div{padding:18px;border:1px solid var(--line);border-radius:14px;background:var(--panel)}.feature-summary strong,.feature-summary span{display:block}.feature-summary strong{font-size:1.55rem}.feature-summary span{margin-top:5px;color:var(--muted);font-size:.76rem}.data-list{border:1px solid var(--line);border-radius:16px;background:var(--panel);overflow:hidden}.data-row{display:grid;grid-template-columns:auto minmax(160px,1.3fr) repeat(2,minmax(150px,1fr));align-items:center;gap:16px;padding:17px 20px;border-top:1px solid var(--line)}.data-row:first-child{border-top:0}.data-row>div{display:grid;gap:4px;min-width:0}.data-row strong{overflow:hidden;text-overflow:ellipsis}.data-row small{color:var(--muted)}.log-toolbar{display:flex;align-items:end;justify-content:space-between;gap:16px}.log-toolbar label{margin:0;min-width:250px}.feature-note{margin:16px 0}.table-wrap{overflow:auto;border:1px solid var(--line);border-radius:15px;background:var(--panel)}.log-table{width:100%;border-collapse:collapse;font-size:.82rem}.log-table th,.log-table td{padding:13px 15px;text-align:left;border-top:1px solid var(--line);white-space:nowrap}.log-table thead th{border-top:0;color:var(--muted);font-size:.7rem;text-transform:uppercase;letter-spacing:.06em}.http-status{color:var(--green);font-weight:800}.http-status.bad{color:var(--danger)}.log-activity{margin-top:18px}
|
||||
@media(max-width:760px){.data-row{grid-template-columns:auto 1fr}.data-row>div:nth-of-type(n+2){grid-column:2}.feature-summary{gap:8px}.feature-summary>div{padding:13px}.log-toolbar{align-items:stretch;flex-direction:column}.log-toolbar label{min-width:0}}
|
||||
|
||||
Reference in New Issue
Block a user