Compare commits

...

2 Commits

Author SHA1 Message Date
devmatrix 9aa36bb608 Replace all emojis with clean SVG icons 2026-02-20 17:48:30 +00:00
devmatrix 3f42b2dd5f Replace emojis with clean SVG icons 2026-02-20 17:44:33 +00:00
2 changed files with 28 additions and 29 deletions

View File

@ -1,9 +1,5 @@
INFO: Started server process [33302] INFO: Started server process [36170]
INFO: Waiting for application startup. INFO: Waiting for application startup.
INFO: Application startup complete. INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: 127.0.0.1:44708 - "GET / HTTP/1.1" 200 OK INFO: 127.0.0.1:49684 - "GET / HTTP/1.1" 200 OK
INFO: 192.168.5.30:64440 - "GET /login HTTP/1.1" 200 OK
INFO: 192.168.5.30:56562 - "GET /favicon.ico HTTP/1.1" 200 OK
INFO: 192.168.5.30:49401 - "POST /api/setup/test-ipmi HTTP/1.1" 200 OK
INFO: 192.168.5.30:49401 - "GET /favicon.ico HTTP/1.1" 200 OK

View File

@ -276,7 +276,10 @@ def get_html(theme="dark"):
transition: all 0.2s; transition: all 0.2s;
}} }}
.status-item:hover {{ transform: translateY(-2px); }} .status-item:hover {{ transform: translateY(-2px); }}
.status-item .icon {{ font-size: 1.5rem; margin-bottom: 5px; }} .status-item .icon {{ width: 32px; height: 32px; margin: 0 auto 8px; }}
.status-item .icon svg {{ width: 100%; height: 100%; }}
.icon-svg {{ width: 16px; height: 16px; display: inline-block; vertical-align: middle; margin-right: 6px; }}
.icon-svg svg {{ width: 100%; height: 100%; fill: currentColor; }}
.status-item .label {{ font-size: 0.75rem; color: var(--text-secondary); margin-bottom: 3px; }} .status-item .label {{ font-size: 0.75rem; color: var(--text-secondary); margin-bottom: 3px; }}
.status-item .value {{ font-size: 1.1rem; font-weight: bold; }} .status-item .value {{ font-size: 1.1rem; font-weight: bold; }}
.status-item .value.good {{ color: var(--accent-success); }} .status-item .value.good {{ color: var(--accent-success); }}
@ -473,37 +476,37 @@ def get_html(theme="dark"):
<div class="container"> <div class="container">
<header> <header>
<div class="header-top"> <div class="header-top">
<h1>🌡 IPMI Controller</h1> <h1><span class="icon-svg"><svg viewBox="0 0 24 24"><path d="M12 2a2 2 0 012 2v.35a7 7 0 015.65 6.65 1 1 0 01-2 0 5 5 0 00-10 0 1 1 0 01-2 0A7 7 0 019.35 4.35 2 2 0 0112 2zm0 6a4 4 0 00-4 4v7h8v-7a4 4 0 00-4-4z"/></svg></span>IPMI Controller</h1>
<div class="header-actions"> <div class="header-actions">
<button class="secondary small" onclick="toggleTheme()">🌓 Theme</button> <button class="secondary small" onclick="toggleTheme()"><span class="icon-svg"><svg viewBox="0 0 24 24"><path d="M12 4a1 1 0 011 1v2a1 1 0 11-2 0V5a1 1 0 011-1zm0 14a5 5 0 100-10 5 5 0 000 10zm0-2a3 3 0 110-6 3 3 0 010 6zM4.93 4.93a1 1 0 011.41 0l1.42 1.42a1 1 0 11-1.41 1.41L4.93 6.34a1 1 0 010-1.41zm0 14.14a1 1 0 010-1.41l1.42-1.42a1 1 0 111.41 1.41l-1.42 1.42a1 1 0 01-1.41 0zM19.07 4.93a1 1 0 010 1.41l-1.42 1.42a1 1 0 11-1.41-1.41l1.42-1.42a1 1 0 011.41 0zM12 18a1 1 0 011 1v2a1 1 0 11-2 0v-2a1 1 0 011-1z"/></svg></span>Theme</button>
<button class="secondary small" onclick="showPasswordModal()">🔑 Password</button> <button class="secondary small" onclick="showPasswordModal()"><span class="icon-svg"><svg viewBox="0 0 24 24"><path d="M12 2a5 5 0 00-5 5v2H6a2 2 0 00-2 2v9a2 2 0 002 2h12a2 2 0 002-2v-9a2 2 0 00-2-2h-1V7a5 5 0 00-5-5zm-3 5a3 3 0 116 0v2H9V7zm3 7a1 1 0 01-1 1v2a1 1 0 112 0v-2a1 1 0 01-1-1z"/></svg></span>Password</button>
<button class="secondary small" onclick="logout()">🚪 Logout</button> <button class="secondary small" onclick="logout()"><span class="icon-svg"><svg viewBox="0 0 24 24"><path d="M10 3H6a2 2 0 00-2 2v14a2 2 0 002 2h4M17 16l4-4m0 0l-4-4m4 4H10"/></svg></span>Logout</button>
</div> </div>
</div> </div>
<div class="status-bar"> <div class="status-bar">
<div class="status-item" id="status-ipmi"> <div class="status-item" id="status-ipmi">
<div class="icon">🖥</div> <div class="icon"><svg viewBox="0 0 24 24"><path d="M4 4h16v12H4V4zm2 2v8h12V6H6zm-2 12h16v2H4v-2zm4-10h2v6H8V8zm4 0h2v6h-2V8zm4 0h2v6h-2V8z"/></svg></div>
<div class="label">IPMI</div> <div class="label">IPMI</div>
<div class="value" id="val-ipmi">-</div> <div class="value" id="val-ipmi">-</div>
</div> </div>
<div class="status-item" id="status-mode"> <div class="status-item" id="status-mode">
<div class="icon"></div> <div class="icon"><svg viewBox="0 0 24 24"><path d="M12 2a10 10 0 100 20 10 10 0 000-20zm0 18a8 8 0 110-16 8 8 0 010 16zm1-8h4v2h-6V7h2v5z"/></svg></div>
<div class="label">Mode</div> <div class="label">Mode</div>
<div class="value" id="val-mode">-</div> <div class="value" id="val-mode">-</div>
</div> </div>
<div class="status-item" id="status-temp"> <div class="status-item" id="status-temp">
<div class="icon">🌡</div> <div class="icon"><svg viewBox="0 0 24 24"><path d="M12 2a2 2 0 012 2v.35a7 7 0 015.65 6.65 1 1 0 01-2 0 5 5 0 00-10 0 1 1 0 01-2 0A7 7 0 019.35 4.35 2 2 0 0112 2zm0 6a4 4 0 00-4 4v7h8v-7a4 4 0 00-4-4z"/></svg></div>
<div class="label">Max Temp</div> <div class="label">Max Temp</div>
<div class="value" id="val-temp">-</div> <div class="value" id="val-temp">-</div>
</div> </div>
<div class="status-item" id="status-fans"> <div class="status-item" id="status-fans">
<div class="icon">🌬</div> <div class="icon"><svg viewBox="0 0 24 24"><path d="M12 2a5 5 0 00-5 5v3H5a2 2 0 00-2 2v8a2 2 0 002 2h14a2 2 0 002-2v-8a2 2 0 00-2-2h-2V7a5 5 0 00-5-5zm-3 5a3 3 0 116 0v3H9V7zm6 7a1 1 0 01-1 1 1 1 0 01-1-1 1 1 0 011-1 1 1 0 011 1z"/></svg></div>
<div class="label">Fan Speed</div> <div class="label">Fan Speed</div>
<div class="value" id="val-fans">-</div> <div class="value" id="val-fans">-</div>
</div> </div>
<div class="status-item" id="status-sensors"> <div class="status-item" id="status-sensors">
<div class="icon">📊</div> <div class="icon"><svg viewBox="0 0 24 24"><path d="M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"/></svg></div>
<div class="label">Sensors</div> <div class="label">Sensors</div>
<div class="value" id="val-sensors">-</div> <div class="value" id="val-sensors">-</div>
</div> </div>
@ -512,12 +515,12 @@ def get_html(theme="dark"):
<!-- Quick Controls --> <!-- Quick Controls -->
<div class="card"> <div class="card">
<h2>🎛 Quick Controls</h2> <h2><span class="icon-svg"><svg viewBox="0 0 24 24"><path d="M12 2a10 10 0 100 20 10 10 0 000-20zm0 18a8 8 0 110-16 8 8 0 010 16zm1-8h4v2h-6V7h2v5z"/></svg></span>Quick Controls</h2>
<div style="display:flex;gap:10px;flex-wrap:wrap;margin-bottom:15px;"> <div style="display:flex;gap:10px;flex-wrap:wrap;margin-bottom:15px;">
<button class="success" onclick="setAuto(true)"> Auto On</button> <button class="success" onclick="setAuto(true)">Start Auto</button>
<button class="danger" onclick="setAuto(false)"> Auto Off</button> <button class="danger" onclick="setAuto(false)">Stop Auto</button>
<button class="primary" onclick="testConnection()">🔄 Test</button> <button class="primary" onclick="testConnection()">Test Connection</button>
<button class="secondary" onclick="showIdentifyModal()">🔍 Identify Fan</button> <button class="secondary" onclick="showIdentifyModal()">Identify Fan</button>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -530,7 +533,7 @@ def get_html(theme="dark"):
<!-- Temperatures --> <!-- Temperatures -->
<div class="card"> <div class="card">
<h2>🌡 Temperatures</h2> <h2><span class="icon-svg"><svg viewBox="0 0 24 24"><path d="M12 2a2 2 0 012 2v.35a7 7 0 015.65 6.65 1 1 0 01-2 0 5 5 0 00-10 0 1 1 0 01-2 0A7 7 0 019.35 4.35 2 2 0 0112 2zm0 6a4 4 0 00-4 4v7h8v-7a4 4 0 00-4-4z"/></svg></span>Temperatures</h2>
<div class="temp-grid" id="temp-grid"> <div class="temp-grid" id="temp-grid">
<div class="temp-item"><span>Loading...</span></div> <div class="temp-item"><span>Loading...</span></div>
</div> </div>
@ -538,7 +541,7 @@ def get_html(theme="dark"):
<!-- Fans --> <!-- Fans -->
<div class="card"> <div class="card">
<h2>🌬 Fans</h2> <h2><span class="icon-svg"><svg viewBox="0 0 24 24"><path d="M12 2a5 5 0 00-5 5v3H5a2 2 0 00-2 2v8a2 2 0 002 2h14a2 2 0 002-2v-8a2 2 0 00-2-2h-2V7a5 5 0 00-5-5zm-3 5a3 3 0 116 0v3H9V7z"/></svg></span>Fans</h2>
<div class="fan-grid" id="fan-grid"> <div class="fan-grid" id="fan-grid">
<div class="fan-card">Loading...</div> <div class="fan-card">Loading...</div>
</div> </div>
@ -547,10 +550,10 @@ def get_html(theme="dark"):
<!-- Settings --> <!-- Settings -->
<div class="card"> <div class="card">
<div class="tabs"> <div class="tabs">
<button class="tab active" onclick="showTab('ipmi')">🖥 IPMI</button> <button class="tab active" onclick="showTab('ipmi')"><span class="icon-svg"><svg viewBox="0 0 24 24"><path d="M4 4h16v12H4V4zm2 2v8h12V6H6zm-2 12h16v2H4v-2z"/></svg></span>IPMI</button>
<button class="tab" onclick="showTab('http')">🌐 HTTP</button> <button class="tab" onclick="showTab('http')">🌐 HTTP</button>
<button class="tab" onclick="showTab('control')"> Control</button> <button class="tab" onclick="showTab('control')"> Control</button>
<button class="tab" onclick="showTab('fans')">🌬 Fans</button> <button class="tab" onclick="showTab('fans')"><span class="icon-svg"><svg viewBox="0 0 24 24"><path d="M12 2a5 5 0 00-5 5v3H5a2 2 0 00-2 2v8a2 2 0 002 2h14a2 2 0 002-2v-8a2 2 0 00-2-2h-2V7a5 5 0 00-5-5zm-3 5a3 3 0 116 0v3H9V7z"/></svg></span>Fans</button>
<button class="tab" onclick="showTab('curves')">📈 Curves</button> <button class="tab" onclick="showTab('curves')">📈 Curves</button>
<button class="tab" onclick="showTab('logs')">📝 Logs</button> <button class="tab" onclick="showTab('logs')">📝 Logs</button>
</div> </div>
@ -683,7 +686,7 @@ def get_html(theme="dark"):
<div class="modal" id="identify-modal"> <div class="modal" id="identify-modal">
<div class="modal-content"> <div class="modal-content">
<h3>🔍 Identify Fan</h3> <h3><span class="icon-svg"><svg viewBox="0 0 24 24"><path d="M10 2a8 8 0 105.29 14.29l4.91 4.91a1 1 0 001.41-1.41l-4.91-4.91A8 8 0 0010 2zm0 2a6 6 0 110 12 6 6 0 010-12z"/></svg></span>Identify Fan</h3>
<p style="margin-bottom:15px;color:var(--text-secondary);">Select a fan to identify it (sets that fan to 100%, others to 0%)</p> <p style="margin-bottom:15px;color:var(--text-secondary);">Select a fan to identify it (sets that fan to 100%, others to 0%)</p>
<div id="identify-fan-list"></div> <div id="identify-fan-list"></div>
<div style="display:flex;gap:10px;margin-top:15px;"> <div style="display:flex;gap:10px;margin-top:15px;">
@ -738,7 +741,7 @@ def get_html(theme="dark"):
function updateUI() {{ function updateUI() {{
// Status bar // Status bar
const conn = currentStatus.connected; const conn = currentStatus.connected;
document.getElementById('val-ipmi').textContent = conn ? '' : ''; document.getElementById('val-ipmi').textContent = conn ? 'Connected' : 'Disconnected';
document.getElementById('val-ipmi').className = 'value ' + (conn ? 'good' : 'danger'); document.getElementById('val-ipmi').className = 'value ' + (conn ? 'good' : 'danger');
const mode = currentStatus.enabled ? 'AUTO' : (currentStatus.manual_mode ? 'MANUAL' : 'BIOS'); const mode = currentStatus.enabled ? 'AUTO' : (currentStatus.manual_mode ? 'MANUAL' : 'BIOS');
@ -877,7 +880,7 @@ def get_html(theme="dark"):
const res = await api('/api/test', {{method: 'POST'}}); const res = await api('/api/test', {{method: 'POST'}});
if (!res) return; if (!res) return;
const data = await res.json(); const data = await res.json();
log(data.success ? 'IPMI Connected' : 'IPMI Failed: ' + data.error, data.success ? 'success' : 'error'); log(data.success ? 'IPMI Connected' : 'IPMI Failed: ' + data.error, data.success ? 'success' : 'error');
}} }}
async function setAuto(enabled) {{ async function setAuto(enabled) {{
@ -1098,7 +1101,7 @@ LOGIN_HTML = '''<!DOCTYPE html>
</head> </head>
<body> <body>
<div class="login-box"> <div class="login-box">
<h1>🌡 IPMI Controller</h1> <h1><span class="icon-svg"><svg viewBox="0 0 24 24"><path d="M12 2a2 2 0 012 2v.35a7 7 0 015.65 6.65 1 1 0 01-2 0 5 5 0 00-10 0 1 1 0 01-2 0A7 7 0 019.35 4.35 2 2 0 0112 2zm0 6a4 4 0 00-4 4v7h8v-7a4 4 0 00-4-4z"/></svg></span>IPMI Controller</h1>
<div class="error" id="error"></div> <div class="error" id="error"></div>
<form id="login-form"> <form id="login-form">
<div class="form-group"> <div class="form-group">