mirror of
https://github.com/andrey271192/vps_monitoring.git
synced 2026-09-20 11:55:34 +00:00
feat: add light/dark theme, RU/EN i18n, instructions page, green/red monitoring
- Light and dark theme toggle with localStorage persistence - Russian and English language support (full i18n) - Instructions & cheat sheet modal with install/SSH/API/commands - Green pulsing dot for online, red for offline servers - Color-coded metrics: green (ok), yellow (warn >70%), red (crit >90%) - Top bar on server cards: green=online, red=offline Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
:root {
|
||||
/* Dark Theme (default) */
|
||||
:root, [data-theme="dark"] {
|
||||
--bg-primary: #0f0f23;
|
||||
--bg-secondary: #1a1a3e;
|
||||
--bg-card: #1e1e4a;
|
||||
@@ -6,12 +7,36 @@
|
||||
--text-secondary: #a0a0cc;
|
||||
--accent: #6366f1;
|
||||
--accent-hover: #818cf8;
|
||||
--success: #4ade80;
|
||||
--danger: #f87171;
|
||||
--warning: #fbbf24;
|
||||
--success: #22c55e;
|
||||
--success-bg: rgba(34, 197, 94, 0.12);
|
||||
--danger: #ef4444;
|
||||
--danger-bg: rgba(239, 68, 68, 0.12);
|
||||
--warning: #f59e0b;
|
||||
--warning-bg: rgba(245, 158, 11, 0.12);
|
||||
--border: rgba(255, 255, 255, 0.08);
|
||||
--radius: 12px;
|
||||
--shadow: 0 4px 24px rgba(0, 0, 0, 0.3);
|
||||
--input-bg: #0f0f23;
|
||||
}
|
||||
|
||||
/* Light Theme */
|
||||
[data-theme="light"] {
|
||||
--bg-primary: #f8fafc;
|
||||
--bg-secondary: #ffffff;
|
||||
--bg-card: #ffffff;
|
||||
--text-primary: #1e293b;
|
||||
--text-secondary: #64748b;
|
||||
--accent: #4f46e5;
|
||||
--accent-hover: #6366f1;
|
||||
--success: #16a34a;
|
||||
--success-bg: rgba(22, 163, 74, 0.1);
|
||||
--danger: #dc2626;
|
||||
--danger-bg: rgba(220, 38, 38, 0.1);
|
||||
--warning: #d97706;
|
||||
--warning-bg: rgba(217, 119, 6, 0.1);
|
||||
--border: rgba(0, 0, 0, 0.08);
|
||||
--shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
|
||||
--input-bg: #f1f5f9;
|
||||
}
|
||||
|
||||
* {
|
||||
@@ -25,6 +50,7 @@ body {
|
||||
background: var(--bg-primary);
|
||||
color: var(--text-primary);
|
||||
min-height: 100vh;
|
||||
transition: background 0.3s, color 0.3s;
|
||||
}
|
||||
|
||||
/* Login Page */
|
||||
@@ -33,7 +59,6 @@ body {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #0f0f23 0%, #1a1a3e 100%);
|
||||
}
|
||||
|
||||
.login-container {
|
||||
@@ -81,7 +106,7 @@ body {
|
||||
.form-group input, .form-group select, .form-group textarea {
|
||||
width: 100%;
|
||||
padding: 10px 14px;
|
||||
background: var(--bg-primary);
|
||||
background: var(--input-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
color: var(--text-primary);
|
||||
@@ -114,8 +139,8 @@ body {
|
||||
.error-msg {
|
||||
margin-top: 12px;
|
||||
padding: 10px;
|
||||
background: rgba(248, 113, 113, 0.1);
|
||||
border: 1px solid rgba(248, 113, 113, 0.3);
|
||||
background: var(--danger-bg);
|
||||
border: 1px solid rgba(239, 68, 68, 0.3);
|
||||
border-radius: 8px;
|
||||
color: var(--danger);
|
||||
font-size: 13px;
|
||||
@@ -142,6 +167,7 @@ header {
|
||||
.header-right {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
@@ -156,10 +182,29 @@ header {
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
transition: background 0.2s;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.btn-icon:hover {
|
||||
background: var(--accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.lang-btn {
|
||||
padding: 4px 10px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--bg-card);
|
||||
color: var(--text-primary);
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.lang-btn:hover {
|
||||
background: var(--accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Main Content */
|
||||
@@ -183,6 +228,11 @@ main {
|
||||
border-radius: var(--radius);
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.stat-item:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.stat-item .stat-label {
|
||||
@@ -204,6 +254,9 @@ main {
|
||||
/* Toolbar */
|
||||
.toolbar {
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toolbar .btn-primary {
|
||||
@@ -211,6 +264,22 @@ main {
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
.toolbar .btn-secondary {
|
||||
padding: 10px 20px;
|
||||
background: var(--bg-card);
|
||||
color: var(--text-primary);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.toolbar .btn-secondary:hover {
|
||||
background: var(--accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Server Grid */
|
||||
.servers-grid {
|
||||
display: grid;
|
||||
@@ -225,6 +294,25 @@ main {
|
||||
padding: 20px;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.server-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
.server-card.online::before {
|
||||
background: var(--success);
|
||||
}
|
||||
|
||||
.server-card.offline::before {
|
||||
background: var(--danger);
|
||||
}
|
||||
|
||||
.server-card:hover {
|
||||
@@ -255,18 +343,50 @@ main {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.status-badge.online {
|
||||
background: rgba(74, 222, 128, 0.15);
|
||||
background: var(--success-bg);
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
.status-badge.offline {
|
||||
background: rgba(248, 113, 113, 0.15);
|
||||
background: var(--danger-bg);
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.status-dot.online {
|
||||
background: var(--success);
|
||||
box-shadow: 0 0 8px var(--success);
|
||||
animation: pulse-green 2s infinite;
|
||||
}
|
||||
|
||||
.status-dot.offline {
|
||||
background: var(--danger);
|
||||
box-shadow: 0 0 8px var(--danger);
|
||||
animation: pulse-red 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse-green {
|
||||
0%, 100% { box-shadow: 0 0 4px var(--success); }
|
||||
50% { box-shadow: 0 0 12px var(--success); }
|
||||
}
|
||||
|
||||
@keyframes pulse-red {
|
||||
0%, 100% { box-shadow: 0 0 4px var(--danger); }
|
||||
50% { box-shadow: 0 0 12px var(--danger); }
|
||||
}
|
||||
|
||||
.metrics-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
@@ -288,6 +408,7 @@ main {
|
||||
.metric-item .value {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
.metric-item .value.warn { color: var(--warning); }
|
||||
@@ -335,6 +456,7 @@ main {
|
||||
.server-card-actions button:hover {
|
||||
background: var(--accent);
|
||||
border-color: var(--accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.server-card-actions button.danger:hover {
|
||||
@@ -374,6 +496,10 @@ main {
|
||||
height: 80vh;
|
||||
}
|
||||
|
||||
.modal-content.modal-wide {
|
||||
max-width: 700px;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -401,6 +527,7 @@ main {
|
||||
|
||||
.btn-close:hover {
|
||||
background: var(--danger);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.modal-content h3 {
|
||||
@@ -411,6 +538,59 @@ main {
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
/* Instructions */
|
||||
.instructions-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.instr-card {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.instr-card h4 {
|
||||
font-size: 14px;
|
||||
margin-bottom: 8px;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.instr-card p {
|
||||
font-size: 13px;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.instr-card code {
|
||||
display: block;
|
||||
margin-top: 8px;
|
||||
padding: 8px 12px;
|
||||
background: var(--bg-primary);
|
||||
border-radius: 6px;
|
||||
font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
|
||||
font-size: 12px;
|
||||
color: var(--success);
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.instr-card .cmd-list {
|
||||
list-style: none;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.instr-card .cmd-list li {
|
||||
padding: 6px 12px;
|
||||
background: var(--bg-primary);
|
||||
border-radius: 4px;
|
||||
margin-bottom: 4px;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* Terminal */
|
||||
#terminal-container {
|
||||
width: 100%;
|
||||
@@ -426,4 +606,5 @@ main {
|
||||
.servers-grid { grid-template-columns: 1fr; }
|
||||
.stats-bar { flex-direction: column; gap: 8px; }
|
||||
header { padding: 12px 16px; }
|
||||
.header-right { gap: 4px; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user