diff options
| author | bndw <ben@bdw.to> | 2026-02-14 14:14:56 -0800 |
|---|---|---|
| committer | bndw <ben@bdw.to> | 2026-02-14 14:14:56 -0800 |
| commit | 4a99f5dae75636cffdf88f850c46b9e5aad43e69 (patch) | |
| tree | 8d19f59133bfbf8af3b2b1414dd028885a26827d /internal | |
| parent | 75fb3a583cf4e8a7ca34bedb3322d309bb170ed4 (diff) | |
style: restyle dashboard to match index page aesthetic
Transform metrics dashboard from dark modern theme to classic beige
theme matching the index page.
Changes:
- Background: dark (#0a0a0a) → beige (#f5f0e8)
- Font: sans-serif → Courier New (monospace)
- Colors: vibrant gradients → simple black/brown
- Cards: dark (#1a1a1a) → white with black borders
- Layout: max-width 1200px → 960px (matches index)
- Typography: modern sizing → classic smaller fonts
- Logo: Add muxstr SVG logo matching index page
- Dividers: Add horizontal rules for section breaks
- Status badge: Green gradient → orange/brown (#c97556)
- Removed: Color coding (success/error/warning classes)
Result: Clean, classic, brutalist aesthetic consistent with index page.
The dashboard now feels like part of the same relay, not a separate app.
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/metrics/dashboard.html | 152 |
1 files changed, 89 insertions, 63 deletions
diff --git a/internal/metrics/dashboard.html b/internal/metrics/dashboard.html index 63b42ed..489327e 100644 --- a/internal/metrics/dashboard.html +++ b/internal/metrics/dashboard.html | |||
| @@ -5,91 +5,116 @@ | |||
| 5 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | 5 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 6 | <title>Nostr Relay Metrics</title> | 6 | <title>Nostr Relay Metrics</title> |
| 7 | <style> | 7 | <style> |
| 8 | * { margin: 0; padding: 0; box-sizing: border-box; } | ||
| 9 | body { | 8 | body { |
| 10 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; | 9 | font-family: 'Courier New', Courier, monospace; |
| 11 | background: #0a0a0a; | 10 | background: #f5f0e8; |
| 12 | color: #e0e0e0; | 11 | color: #000; |
| 13 | padding: 2rem; | 12 | max-width: 960px; |
| 13 | margin: 40px auto; | ||
| 14 | padding: 0 20px; | ||
| 14 | line-height: 1.6; | 15 | line-height: 1.6; |
| 15 | } | 16 | } |
| 16 | .container { max-width: 1200px; margin: 0 auto; } | ||
| 17 | h1 { | 17 | h1 { |
| 18 | font-size: 2rem; | 18 | font-size: 18px; |
| 19 | margin-bottom: 0.5rem; | 19 | font-weight: normal; |
| 20 | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | 20 | margin: 20px 0 10px 0; |
| 21 | -webkit-background-clip: text; | 21 | } |
| 22 | -webkit-text-fill-color: transparent; | 22 | h2 { |
| 23 | background-clip: text; | 23 | font-size: 14px; |
| 24 | font-weight: normal; | ||
| 25 | margin: 20px 0 5px 0; | ||
| 26 | text-transform: uppercase; | ||
| 27 | letter-spacing: 0.05em; | ||
| 28 | } | ||
| 29 | .logo-container { | ||
| 30 | margin: 20px 0 30px 0; | ||
| 31 | } | ||
| 32 | .logo-container svg { | ||
| 33 | width: 100%; | ||
| 34 | height: auto; | ||
| 35 | display: block; | ||
| 36 | } | ||
| 37 | hr { | ||
| 38 | border: none; | ||
| 39 | border-top: 1px solid #000; | ||
| 40 | margin: 30px 0; | ||
| 24 | } | 41 | } |
| 25 | .subtitle { color: #888; margin-bottom: 2rem; font-size: 0.9rem; } | ||
| 26 | .grid { | 42 | .grid { |
| 27 | display: grid; | 43 | display: grid; |
| 28 | grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); | 44 | grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); |
| 29 | gap: 1.5rem; | 45 | gap: 20px; |
| 30 | margin-bottom: 2rem; | 46 | margin: 20px 0; |
| 31 | } | 47 | } |
| 32 | .card { | 48 | .card { |
| 33 | background: #1a1a1a; | 49 | background: #fff; |
| 34 | border: 1px solid #333; | 50 | border: 1px solid #000; |
| 35 | border-radius: 8px; | 51 | padding: 15px; |
| 36 | padding: 1.5rem; | ||
| 37 | } | ||
| 38 | .card h2 { | ||
| 39 | font-size: 0.875rem; | ||
| 40 | text-transform: uppercase; | ||
| 41 | letter-spacing: 0.05em; | ||
| 42 | color: #888; | ||
| 43 | margin-bottom: 1rem; | ||
| 44 | } | 52 | } |
| 45 | .metric { | 53 | .metric { |
| 46 | display: flex; | 54 | display: flex; |
| 47 | justify-content: space-between; | 55 | justify-content: space-between; |
| 48 | align-items: baseline; | 56 | align-items: baseline; |
| 49 | margin-bottom: 0.75rem; | 57 | margin-bottom: 8px; |
| 58 | font-size: 13px; | ||
| 59 | } | ||
| 60 | .metric-label { | ||
| 61 | color: #666; | ||
| 50 | } | 62 | } |
| 51 | .metric-label { color: #aaa; font-size: 0.9rem; } | ||
| 52 | .metric-value { | 63 | .metric-value { |
| 53 | font-size: 1.5rem; | 64 | font-weight: bold; |
| 54 | font-weight: 600; | 65 | font-size: 16px; |
| 55 | color: #fff; | 66 | } |
| 67 | .metric-value.large { | ||
| 68 | font-size: 24px; | ||
| 69 | } | ||
| 70 | .metric-unit { | ||
| 71 | font-size: 11px; | ||
| 72 | color: #666; | ||
| 73 | margin-left: 3px; | ||
| 56 | } | 74 | } |
| 57 | .metric-value.large { font-size: 2.5rem; } | ||
| 58 | .metric-value.success { color: #10b981; } | ||
| 59 | .metric-value.warning { color: #f59e0b; } | ||
| 60 | .metric-value.error { color: #ef4444; } | ||
| 61 | .metric-unit { font-size: 0.875rem; color: #666; margin-left: 0.25rem; } | ||
| 62 | .status { | 75 | .status { |
| 63 | display: inline-block; | 76 | display: inline-block; |
| 64 | padding: 0.25rem 0.75rem; | 77 | padding: 2px 8px; |
| 65 | border-radius: 12px; | 78 | border: 1px solid #000; |
| 66 | font-size: 0.75rem; | 79 | font-size: 11px; |
| 67 | font-weight: 600; | 80 | } |
| 81 | .status.online { | ||
| 82 | background: #c97556; | ||
| 83 | color: #f5f0e8; | ||
| 68 | } | 84 | } |
| 69 | .status.online { background: #10b98120; color: #10b981; } | ||
| 70 | .status.offline { background: #ef444420; color: #ef4444; } | ||
| 71 | .refresh-info { | 85 | .refresh-info { |
| 72 | text-align: center; | 86 | text-align: center; |
| 73 | color: #666; | 87 | color: #666; |
| 74 | font-size: 0.8rem; | 88 | font-size: 11px; |
| 75 | margin-top: 2rem; | 89 | margin-top: 30px; |
| 76 | } | 90 | } |
| 77 | .error-msg { | 91 | .error-msg { |
| 78 | background: #ef444420; | 92 | background: #fff; |
| 79 | border: 1px solid #ef4444; | 93 | border: 1px solid #000; |
| 80 | color: #ef4444; | 94 | padding: 15px; |
| 81 | padding: 1rem; | 95 | margin-bottom: 20px; |
| 82 | border-radius: 8px; | 96 | color: #000; |
| 83 | margin-bottom: 1rem; | 97 | } |
| 98 | a { | ||
| 99 | color: #00e; | ||
| 100 | text-decoration: underline; | ||
| 84 | } | 101 | } |
| 85 | </style> | 102 | </style> |
| 86 | </head> | 103 | </head> |
| 87 | <body> | 104 | <body> |
| 88 | <div class="container"> | 105 | <div class="logo-container"> |
| 89 | <h1>Nostr Relay Metrics</h1> | 106 | <svg viewBox="0 0 1120 300" xmlns="http://www.w3.org/2000/svg"> |
| 90 | <p class="subtitle">Real-time relay statistics and performance metrics</p> | 107 | <rect width="1120" height="300" fill="#c97556"/> |
| 108 | <text x="560" y="200" font-family="Arial, Helvetica, sans-serif" font-size="180" font-weight="bold" fill="#f5f0e8" text-anchor="middle">muxstr</text> | ||
| 109 | </svg> | ||
| 110 | </div> | ||
| 111 | |||
| 112 | <h1>Relay Metrics</h1> | ||
| 113 | <p>Real-time statistics and performance data. Auto-refreshes every 5 seconds.</p> | ||
| 114 | |||
| 115 | <div id="error"></div> | ||
| 91 | 116 | ||
| 92 | <div id="error"></div> | 117 | <hr> |
| 93 | 118 | ||
| 94 | <div class="grid"> | 119 | <div class="grid"> |
| 95 | <div class="card"> | 120 | <div class="card"> |
| @@ -108,7 +133,7 @@ | |||
| 108 | <h2>Connections</h2> | 133 | <h2>Connections</h2> |
| 109 | <div class="metric"> | 134 | <div class="metric"> |
| 110 | <span class="metric-label">Active</span> | 135 | <span class="metric-label">Active</span> |
| 111 | <span class="metric-value large success" id="active_connections">0</span> | 136 | <span class="metric-value large" id="active_connections">0</span> |
| 112 | </div> | 137 | </div> |
| 113 | <div class="metric"> | 138 | <div class="metric"> |
| 114 | <span class="metric-label">Total</span> | 139 | <span class="metric-label">Total</span> |
| @@ -132,11 +157,11 @@ | |||
| 132 | </div> | 157 | </div> |
| 133 | <div class="metric"> | 158 | <div class="metric"> |
| 134 | <span class="metric-label">Success</span> | 159 | <span class="metric-label">Success</span> |
| 135 | <span class="metric-value success" id="success_requests">0</span> | 160 | <span class="metric-value" id="success_requests">0</span> |
| 136 | </div> | 161 | </div> |
| 137 | <div class="metric"> | 162 | <div class="metric"> |
| 138 | <span class="metric-label">Errors</span> | 163 | <span class="metric-label">Errors</span> |
| 139 | <span class="metric-value error" id="error_requests">0</span> | 164 | <span class="metric-value" id="error_requests">0</span> |
| 140 | </div> | 165 | </div> |
| 141 | </div> | 166 | </div> |
| 142 | 167 | ||
| @@ -144,11 +169,11 @@ | |||
| 144 | <h2>Authentication</h2> | 169 | <h2>Authentication</h2> |
| 145 | <div class="metric"> | 170 | <div class="metric"> |
| 146 | <span class="metric-label">Success</span> | 171 | <span class="metric-label">Success</span> |
| 147 | <span class="metric-value success" id="auth_success">0</span> | 172 | <span class="metric-value" id="auth_success">0</span> |
| 148 | </div> | 173 | </div> |
| 149 | <div class="metric"> | 174 | <div class="metric"> |
| 150 | <span class="metric-label">Failed</span> | 175 | <span class="metric-label">Failed</span> |
| 151 | <span class="metric-value error" id="auth_failure">0</span> | 176 | <span class="metric-value" id="auth_failure">0</span> |
| 152 | </div> | 177 | </div> |
| 153 | </div> | 178 | </div> |
| 154 | 179 | ||
| @@ -156,7 +181,7 @@ | |||
| 156 | <h2>Rate Limiting</h2> | 181 | <h2>Rate Limiting</h2> |
| 157 | <div class="metric"> | 182 | <div class="metric"> |
| 158 | <span class="metric-label">Blocked</span> | 183 | <span class="metric-label">Blocked</span> |
| 159 | <span class="metric-value warning" id="rate_limit_hits">0</span> | 184 | <span class="metric-value" id="rate_limit_hits">0</span> |
| 160 | </div> | 185 | </div> |
| 161 | </div> | 186 | </div> |
| 162 | 187 | ||
| @@ -185,8 +210,9 @@ | |||
| 185 | </div> | 210 | </div> |
| 186 | </div> | 211 | </div> |
| 187 | 212 | ||
| 188 | <p class="refresh-info">Auto-refreshing every 5 seconds</p> | 213 | <hr> |
| 189 | </div> | 214 | |
| 215 | <p class="refresh-info">Auto-refreshing every 5 seconds</p> | ||
| 190 | 216 | ||
| 191 | <script> | 217 | <script> |
| 192 | let processStartTime = null; | 218 | let processStartTime = null; |
