174 lines
8.7 KiB
Text
174 lines
8.7 KiB
Text
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Kasane Teto - Neural Dashboard</title>
|
|
<link rel="stylesheet" href="/style.css">
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<header>
|
|
<div class="logo">
|
|
<div class="logo-icon">04</div>
|
|
<div>
|
|
<h1>Kasane Teto - Neural Dashboard</h1>
|
|
<p class="subtitle"><span class="status-dot"></span> What are you looking at, baka?! Just kidding, welcome!</p>
|
|
</div>
|
|
</div>
|
|
<div class="user-info">
|
|
<span>User: <%= user.username %>#<%= user.discriminator %></span>
|
|
<a href="/logout" class="logout-btn">Logout</a>
|
|
</div>
|
|
</header>
|
|
|
|
<nav>
|
|
<a href="#" class="nav-item active">Overview</a>
|
|
<a href="#" class="nav-item">Memory Explorer</a>
|
|
<a href="#" class="nav-item">Server Analytics</a>
|
|
<a href="#" class="nav-item">Archives</a>
|
|
<a href="#" class="nav-item">My Profile</a>
|
|
</nav>
|
|
|
|
<main>
|
|
<div class="widget-grid">
|
|
<div class="widget large-widget">
|
|
<h3>Live Neural Activity <span class="processing-dot">●</span> Processing...</h3>
|
|
<div class="log-box" id="activity-log">
|
|
<% activityLog.forEach(log => { %>
|
|
<p><%- log.message.replace(/(\[[^\]]+\])/, '<span class="timestamp">$1</span>') %></p>
|
|
<% }) %>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="widget">
|
|
<h3>Recent Actions <span class="timeframe">12 in last hour</span></h3>
|
|
<div class="actions-box">
|
|
<% let i = 0; %>
|
|
<% actionsLog.forEach(action => { %>
|
|
<% const time = i === 0 ? '5 min ago' : i === 1 ? '12 min ago' : '30 min ago'; i++; %>
|
|
<div class="action-item">
|
|
<div class="action-details">
|
|
<span><%= action.message %> <span class="channel"><%= action.channel %></span></span>
|
|
<span class="action-time"><%= time %></span>
|
|
</div>
|
|
<span class="action-icon"><%= action.icon %></span>
|
|
</div>
|
|
<% }) %>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="widget">
|
|
<h3>System Resources <span class="status-online">●</span> Online</h3>
|
|
<div class="resource-box">
|
|
<div class="metric">
|
|
<div class="metric-header">
|
|
<span><strong><%= systemResources.memory.percentage %>%</strong></span>
|
|
<span class="metric-label">Memory Usage</span>
|
|
</div>
|
|
<div class="progress-bar-container">
|
|
<div class="progress-bar memory" style="width: <%= systemResources.memory.percentage %>%;"></div>
|
|
</div>
|
|
<span class="metric-details">RAM: <%= systemResources.memory.used %>GB / <%= systemResources.memory.total %>GB</span>
|
|
</div>
|
|
<div class="metric">
|
|
<div class="metric-header">
|
|
<span><strong><%= systemResources.vram.percentage %>%</strong></span>
|
|
<span class="metric-label">VRAM Usage</span>
|
|
</div>
|
|
<div class="progress-bar-container">
|
|
<div class="progress-bar vram" style="width: <%= systemResources.vram.percentage %>%;"></div>
|
|
</div>
|
|
<span class="metric-details">VRAM: <%= systemResources.vram.used %>GB / <%= systemResources.vram.total %>GB</span>
|
|
</div>
|
|
<div class="metric response-times">
|
|
<div class="metric-header">
|
|
<span><strong><%= systemResources.avgResponse %>ms</strong></span>
|
|
<span class="metric-label">Average Response</span>
|
|
</div>
|
|
<div class="response-bar"><span>Input Processing</span> <div class="bar-container"><div class="bar" style="width: 20%;"></div></div> <span>4ms</span></div>
|
|
<div class="response-bar"><span>Memory Retrieval</span> <div class="bar-container"><div class="bar" style="width: 60%;"></div></div> <span>12ms</span></div>
|
|
<div class="response-bar"><span>Neural Processing</span> <div class="bar-container"><div class="bar" style="width: 60%;"></div></div> <span>12ms</span></div>
|
|
<div class="response-bar"><span>Response Generation</span> <div class="bar-container"><div class="bar" style="width: 20%;"></div></div> <span>4ms</span></div>
|
|
</div>
|
|
<div class="metric shutdown-metric">
|
|
<div class="metric-header">
|
|
<span><strong><%= systemResources.shutdown %></strong></span>
|
|
<span class="metric-label">Until Shutdown</span>
|
|
</div>
|
|
<div class="progress-bar-container">
|
|
<div class="progress-bar shutdown" style="width: 80%;"></div>
|
|
</div>
|
|
<span class="metric-details">Session ends: <%= systemResources.sessionEnd %></span>
|
|
</div>
|
|
<div class="maintenance">
|
|
<span>⚠</span> Planned maintenance cycle
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
<script>
|
|
// 1. Establish the connection
|
|
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
|
|
const socket = new WebSocket(`${protocol}://${window.location.host}`);
|
|
|
|
function connectWS() {
|
|
socket.onopen = () => {
|
|
console.log('WebSocket connection established');
|
|
};
|
|
}
|
|
connectWS();
|
|
|
|
// 2. Listen for messages from the server
|
|
socket.onmessage = (event) => {
|
|
const data = JSON.parse(event.data);
|
|
// --- This is our client-side message router ---
|
|
switch (data.type) {
|
|
case 'activityLogUpdate':
|
|
handleActivityLogUpdate(data.payload);
|
|
break;
|
|
case 'systemResourcesUpdate':
|
|
handleSystemResourceUpdate(data.payload);
|
|
break;
|
|
// Add more cases here for other real-time updates
|
|
default:
|
|
console.log('Received unknown message type:', data.type);
|
|
}
|
|
};
|
|
|
|
function handleActivityLogUpdate(payload) {
|
|
const activityLog = document.getElementById('activity-log');
|
|
if (!activityLog || !payload.message) return;
|
|
|
|
const newLogItem = document.createElement('p');
|
|
const styledMessage = payload.message.replace(/(\[[^\]]+\])/, '<span class="timestamp">$1</span>');
|
|
newLogItem.innerHTML = styledMessage;
|
|
|
|
activityLog.prepend(newLogItem);
|
|
|
|
while (activityLog.children.length > 20) {
|
|
activityLog.lastChild.remove();
|
|
}
|
|
}
|
|
|
|
function handleSystemResourceUpdate(payload) {
|
|
// Conceptual: Find the memory percentage element and update its text and style
|
|
const memPercentage = document.querySelector('.metric-header strong'); // Simplified selector
|
|
const memProgressBar = document.querySelector('.progress-bar.memory'); // Simplified selector
|
|
|
|
if(memPercentage) memPercentage.textContent = `${payload.memory.percentage}%`;
|
|
if(memProgressBar) memProgressBar.style.width = `${payload.memory.percentage}%`;
|
|
|
|
console.log('System resources updated!', payload);
|
|
}
|
|
|
|
socket.onclose = () => {
|
|
console.log('WebSocket connection closed. Attempting to reconnect...');
|
|
connectWS();
|
|
};
|
|
</script>
|
|
</body>
|
|
</html>
|