somratpro commited on
Commit
85665cf
·
1 Parent(s): f6b2915

feat: enhance dashboard UI with dynamic status badges and server-side initial data rendering

Browse files
Files changed (1) hide show
  1. health-server.js +56 -12
health-server.js CHANGED
@@ -9,6 +9,7 @@ const GATEWAY_PORT = 7860;
9
  const GATEWAY_HOST = "127.0.0.1";
10
  const startTime = Date.now();
11
  const LLM_MODEL = process.env.LLM_MODEL || "Not Set";
 
12
  const TELEGRAM_ENABLED = !!process.env.TELEGRAM_BOT_TOKEN;
13
  const WHATSAPP_ENABLED = /^true$/i.test(process.env.WHATSAPP_ENABLED || "");
14
  const WHATSAPP_STATUS_FILE = "/tmp/huggingclaw-wa-status.json";
@@ -112,7 +113,33 @@ function readGuardianStatus() {
112
  return { configured: true, connected: false, pairing: false };
113
  }
114
 
115
- function renderDashboard() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  return `
117
  <!DOCTYPE html>
118
  <html lang="en">
@@ -464,29 +491,29 @@ function renderDashboard() {
464
  <div class="stats-grid">
465
  <div class="stat-card">
466
  <span class="stat-label">Model</span>
467
- <span class="stat-value" id="model-id">Loading...</span>
468
  </div>
469
  <div class="stat-card">
470
  <span class="stat-label">Uptime</span>
471
- <span class="stat-value" id="uptime">Loading...</span>
472
  </div>
473
  <div class="stat-card">
474
  <span class="stat-label">WhatsApp</span>
475
- <span id="wa-status">Loading...</span>
476
  </div>
477
  <div class="stat-card">
478
  <span class="stat-label">Telegram</span>
479
- <span id="tg-status">Loading...</span>
480
  </div>
481
- <a href="${DASHBOARD_APP_BASE}/" class="stat-btn">Open Control UI</a>
482
  </div>
483
 
484
  <div class="stat-card" style="width: 100%;">
485
  <span class="stat-label">Workspace Sync Status</span>
486
- <div id="sync-badge-container"></div>
487
  <div class="sync-info">
488
- Last Sync Activity: <span id="sync-time">Never</span>
489
- <span id="sync-msg">Initializing synchronization...</span>
490
  </div>
491
  </div>
492
 
@@ -532,9 +559,14 @@ function renderDashboard() {
532
  </div>
533
 
534
  <script>
 
 
 
 
 
535
  async function updateStats() {
536
  try {
537
- const res = await fetch('${DASHBOARD_STATUS_PATH}');
538
  const data = await res.json();
539
 
540
  document.getElementById('model-id').textContent = data.model;
@@ -624,7 +656,7 @@ function renderDashboard() {
624
  result.textContent = '';
625
 
626
  try {
627
- const res = await fetch('${DASHBOARD_UPTIMEROBOT_PATH}', {
628
  method: 'POST',
629
  headers: { 'Content-Type': 'application/json' },
630
  body: JSON.stringify({ apiKey })
@@ -944,8 +976,20 @@ const server = http.createServer((req, res) => {
944
  }
945
 
946
  if (isDashboardRoute(pathname)) {
 
 
 
 
 
 
 
 
 
 
 
 
947
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
948
- res.end(renderDashboard());
949
  return;
950
  }
951
 
 
9
  const GATEWAY_HOST = "127.0.0.1";
10
  const startTime = Date.now();
11
  const LLM_MODEL = process.env.LLM_MODEL || "Not Set";
12
+ const SPACE_HOST = process.env.SPACE_HOST || "";
13
  const TELEGRAM_ENABLED = !!process.env.TELEGRAM_BOT_TOKEN;
14
  const WHATSAPP_ENABLED = /^true$/i.test(process.env.WHATSAPP_ENABLED || "");
15
  const WHATSAPP_STATUS_FILE = "/tmp/huggingclaw-wa-status.json";
 
113
  return { configured: true, connected: false, pairing: false };
114
  }
115
 
116
+ function renderChannelBadge(channel, configuredLabel) {
117
+ if (channel && channel.connected) {
118
+ return '<div class="status-badge status-online"><div class="pulse"></div>Active</div>';
119
+ }
120
+ if (channel && channel.configured) {
121
+ return `<div class="status-badge status-syncing">${configuredLabel}</div>`;
122
+ }
123
+ return '<div class="status-badge status-offline">Disabled</div>';
124
+ }
125
+
126
+ function renderSyncBadge(syncData) {
127
+ let badgeClass = "status-offline";
128
+ let pulseHtml = "";
129
+
130
+ if (syncData.status === "success") {
131
+ badgeClass = "status-online";
132
+ pulseHtml = '<div class="pulse"></div>';
133
+ } else if (syncData.status === "syncing") {
134
+ badgeClass = "status-syncing";
135
+ pulseHtml = '<div class="pulse" style="background:#3b82f6"></div>';
136
+ }
137
+
138
+ return `<div class="status-badge ${badgeClass}">${pulseHtml}${String(syncData.status || "unknown").toUpperCase()}</div>`;
139
+ }
140
+
141
+ function renderDashboard(initialData) {
142
+ const controlUiHref = SPACE_HOST ? `https://${SPACE_HOST}` : `${DASHBOARD_APP_BASE}/`;
143
  return `
144
  <!DOCTYPE html>
145
  <html lang="en">
 
491
  <div class="stats-grid">
492
  <div class="stat-card">
493
  <span class="stat-label">Model</span>
494
+ <span class="stat-value" id="model-id">${initialData.model}</span>
495
  </div>
496
  <div class="stat-card">
497
  <span class="stat-label">Uptime</span>
498
+ <span class="stat-value" id="uptime">${initialData.uptime}</span>
499
  </div>
500
  <div class="stat-card">
501
  <span class="stat-label">WhatsApp</span>
502
+ <span id="wa-status">${renderChannelBadge(initialData.whatsapp, 'Ready to pair')}</span>
503
  </div>
504
  <div class="stat-card">
505
  <span class="stat-label">Telegram</span>
506
+ <span id="tg-status">${renderChannelBadge(initialData.telegram, 'Configured')}</span>
507
  </div>
508
+ <a href="${controlUiHref}" id="control-ui-link" class="stat-btn">Open Control UI</a>
509
  </div>
510
 
511
  <div class="stat-card" style="width: 100%;">
512
  <span class="stat-label">Workspace Sync Status</span>
513
+ <div id="sync-badge-container">${renderSyncBadge(initialData.sync)}</div>
514
  <div class="sync-info">
515
+ Last Sync Activity: <span id="sync-time">${initialData.sync.timestamp || "Never"}</span>
516
+ <span id="sync-msg">${initialData.sync.message || "Waiting for first sync..."}</span>
517
  </div>
518
  </div>
519
 
 
559
  </div>
560
 
561
  <script>
562
+ function getDashboardBase() {
563
+ const pathname = window.location.pathname || '${DASHBOARD_BASE}';
564
+ return pathname.endsWith('/') ? pathname.slice(0, -1) : pathname;
565
+ }
566
+
567
  async function updateStats() {
568
  try {
569
+ const res = await fetch(getDashboardBase() + '/status');
570
  const data = await res.json();
571
 
572
  document.getElementById('model-id').textContent = data.model;
 
656
  result.textContent = '';
657
 
658
  try {
659
+ const res = await fetch(getDashboardBase() + '/uptimerobot/setup', {
660
  method: 'POST',
661
  headers: { 'Content-Type': 'application/json' },
662
  body: JSON.stringify({ apiKey })
 
976
  }
977
 
978
  if (isDashboardRoute(pathname)) {
979
+ const guardianStatus = readGuardianStatus();
980
+ const initialData = {
981
+ model: LLM_MODEL,
982
+ whatsapp: {
983
+ configured: guardianStatus.configured,
984
+ connected: guardianStatus.connected,
985
+ pairing: guardianStatus.pairing,
986
+ },
987
+ telegram: normalizeChannelStatus(null, TELEGRAM_ENABLED),
988
+ sync: readSyncStatus(),
989
+ uptime: uptimeHuman,
990
+ };
991
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
992
+ res.end(renderDashboard(initialData));
993
  return;
994
  }
995