196 lines
5.0 KiB
HTML
196 lines
5.0 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>Task Manager</title>
|
||
<script src="/static/htmx.min.js"></script>
|
||
<style>
|
||
:root {
|
||
--bg-color: #121212;
|
||
--text-color: #e0e0e0;
|
||
--accent-color: #007bff;
|
||
--danger-color: #dc3545;
|
||
--table-bg: #1e1e1e;
|
||
--hover-bg: #2a2a2a;
|
||
--border-color: #333;
|
||
}
|
||
|
||
body {
|
||
font-family: Arial, sans-serif;
|
||
background-color: var(--bg-color);
|
||
color: var(--text-color);
|
||
margin: 2rem;
|
||
}
|
||
|
||
.page-title {
|
||
text-align: center;
|
||
font-size: 2.8rem;
|
||
margin: 2rem 0 1rem 0;
|
||
font-weight: bold;
|
||
letter-spacing: 1px;
|
||
background: linear-gradient(to right, #00c6ff, #00e6aa);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
text-shadow: 0 0 5px rgba(0,0,0,0.5);
|
||
}
|
||
|
||
.card {
|
||
background-color: #1e1e2f; /* dark card background */
|
||
border-radius: 12px;
|
||
padding: 20px;
|
||
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.5);
|
||
margin: 3rem auto; /* vertical margin + horizontal centering */
|
||
max-width: 900px; /* limits width */
|
||
color: #e0e0ff;
|
||
}
|
||
table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
background-color: var(--table-bg);
|
||
box-shadow: 0 0 15px rgba(0, 0, 0, 0.3);
|
||
margin-top: 1rem;
|
||
color: var(--text-color);
|
||
}
|
||
|
||
th, td {
|
||
padding: 10px 15px;
|
||
border-bottom: 1px solid var(--border-color);
|
||
text-align: left;
|
||
font-size: 14px;
|
||
}
|
||
|
||
th {
|
||
background-color: var(--accent-color);
|
||
color: white;
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 1;
|
||
}
|
||
|
||
tr:hover {
|
||
background-color: var(--hover-bg);
|
||
}
|
||
|
||
button {
|
||
padding: 5px 10px;
|
||
background-color: var(--danger-color);
|
||
color: white;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
button:hover {
|
||
background-color: #c82333;
|
||
}
|
||
|
||
a {
|
||
color: #80dfff;
|
||
text-decoration: none;
|
||
}
|
||
|
||
a:hover {
|
||
text-decoration: underline;
|
||
}
|
||
.usage-bar {
|
||
position: relative;
|
||
background-color: #333;
|
||
border-radius: 8px;
|
||
height: 20px;
|
||
width: 100%;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.usage-fill {
|
||
height: 100%;
|
||
width: 0%;
|
||
background-color: #00e676; /* initial */
|
||
transition: width 0.5s ease, background-color 0.4s ease;
|
||
border-radius: 8px 0 0 8px;
|
||
}
|
||
|
||
.usage-text {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
font-weight: bold;
|
||
color: #fff;
|
||
font-size: 14px;
|
||
line-height: 20px;
|
||
user-select: none;
|
||
text-shadow: 0 0 5px rgba(0,0,0,0.7);
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div id="system-stats" class="card" style="margin-bottom: 1.5rem;">
|
||
<div>
|
||
<label>CPU Usage</label>
|
||
<div class="usage-bar">
|
||
<div id="cpu-bar" class="usage-fill"></div>
|
||
<span id="cpu-percent" class="usage-text">0%</span>
|
||
</div>
|
||
</div>
|
||
<div style="margin-top: 1rem;">
|
||
<label>Memory Usage</label>
|
||
<div class="usage-bar">
|
||
<div id="mem-bar" class="usage-fill"></div>
|
||
<span id="mem-percent" class="usage-text">0%</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<h1 class="page-title">🧠 Task Manager</h1>
|
||
<div id="process-table" class="card">
|
||
{{template "table.html" .}}
|
||
</div>
|
||
</body>
|
||
<script>
|
||
function updateUsage() {
|
||
fetch("/taskmanager/usage")
|
||
.then(res => res.json())
|
||
.then(data => {
|
||
const cpu = Math.round(data.cpu);
|
||
const mem = Math.round(data.mem);
|
||
|
||
updateBar('cpu-bar', 'cpu-percent', cpu);
|
||
updateBar('mem-bar', 'mem-percent', mem);
|
||
})
|
||
.catch(console.error);
|
||
}
|
||
|
||
function updateBar(barId, textId, percent) {
|
||
const bar = document.getElementById(barId);
|
||
const text = document.getElementById(textId);
|
||
|
||
bar.style.width = percent + '%';
|
||
text.textContent = percent + '%';
|
||
|
||
// Set interpolated color from green to red
|
||
bar.style.backgroundColor = getInterpolatedColor(percent);
|
||
}
|
||
|
||
function getInterpolatedColor(percent) {
|
||
// Clamp between 0–100
|
||
percent = Math.max(0, Math.min(100, percent));
|
||
|
||
let r, g;
|
||
|
||
if (percent <= 50) {
|
||
// green (0%) to yellow (50%)
|
||
r = Math.floor(255 * (percent / 50)); // 0 → 255
|
||
g = 230; // stay green
|
||
} else {
|
||
// yellow (50%) to red (100%)
|
||
r = 255;
|
||
g = Math.floor(230 - 230 * ((percent - 50) / 50)); // 230 → 0
|
||
}
|
||
|
||
return `rgb(${r},${g},0)`;
|
||
}
|
||
|
||
setInterval(updateUsage, 5000);
|
||
updateUsage();
|
||
</script>
|
||
</html>
|