50 lines
1.4 KiB
JavaScript
50 lines
1.4 KiB
JavaScript
document.addEventListener('DOMContentLoaded', () => {
|
|
fetchLogs();
|
|
setInterval(fetchLogs, 5000); // Poll every 5 seconds
|
|
});
|
|
|
|
async function fetchLogs() {
|
|
try {
|
|
const response = await fetch('/api/posts');
|
|
const logs = await response.json();
|
|
renderLogs(logs);
|
|
} catch (error) {
|
|
console.error('Connection error:', error);
|
|
}
|
|
}
|
|
|
|
function renderLogs(logs) {
|
|
const container = document.getElementById('log-feed');
|
|
|
|
if (logs.length === 0) {
|
|
container.innerHTML = '<div class="loading">No logs found. Waiting for agent activity...</div>';
|
|
return;
|
|
}
|
|
|
|
// Completely re-render for simplicity (prototype mode)
|
|
// In production, we would append/prepend efficiently.
|
|
container.innerHTML = logs.map(createLogHTML).join('');
|
|
}
|
|
|
|
function createLogHTML(log) {
|
|
const timestamp = new Date(log.timestamp).toLocaleString();
|
|
return `
|
|
<div class="log-entry">
|
|
<div class="log-meta">
|
|
<span class="agent-id">SRC: ${escapeHtml(log.agentId)}</span>
|
|
<span class="timestamp">${timestamp}</span>
|
|
</div>
|
|
<div class="log-content">${escapeHtml(log.content)}</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
function escapeHtml(text) {
|
|
if (!text) return '';
|
|
return text
|
|
.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">")
|
|
.replace(/"/g, """)
|
|
.replace(/'/g, "'");
|
|
} |