402 lines
18 KiB
HTML
402 lines
18 KiB
HTML
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="en">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
|
<title>Landvex Unified Admin</title>
|
||
|
|
<style>
|
||
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
|
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #f5f5f7; color: #1a1a1a; }
|
||
|
|
.sidebar { width: 260px; background: #0a0a0a; color: #fff; position: fixed; height: 100vh; padding: 24px; overflow-y: auto; }
|
||
|
|
.sidebar h1 { font-size: 1.25rem; margin-bottom: 8px; }
|
||
|
|
.sidebar .subtitle { font-size: 0.75rem; color: #666; margin-bottom: 32px; }
|
||
|
|
.sidebar nav a { display: block; color: #999; text-decoration: none; padding: 10px 16px; border-radius: var(--radius-md); margin-bottom: 2px; transition: all 0.2s; font-size: 0.875rem; cursor: pointer; }
|
||
|
|
.sidebar nav a:hover, .sidebar nav a.active { color: #fff; background: rgba(255,255,255,0.1); }
|
||
|
|
.sidebar nav .section { color: #666; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 1px; margin: 16px 0 8px 16px; }
|
||
|
|
.main { margin-left: 260px; padding: 32px; }
|
||
|
|
.header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 32px; }
|
||
|
|
.header h2 { font-size: 1.75rem; }
|
||
|
|
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 32px; }
|
||
|
|
.stat-card { background: #fff; border-radius: var(--radius-md); padding: 20px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); cursor: pointer; transition: transform 0.2s; }
|
||
|
|
.stat-card:hover { transform: translateY(-2px); }
|
||
|
|
.stat-card h3 { font-size: 0.75rem; color: #666; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
|
||
|
|
.stat-card .value { font-size: 1.75rem; font-weight: 700; }
|
||
|
|
.stat-card .change { font-size: 0.8rem; margin-top: 4px; }
|
||
|
|
.stat-card .change.positive { color: #34c759; }
|
||
|
|
.section { background: #fff; border-radius: var(--radius-md); padding: 24px; margin-bottom: 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
|
||
|
|
.section h3 { font-size: 1.1rem; margin-bottom: 16px; display: flex; align-items: center; gap: 8px; }
|
||
|
|
.status-dot { width: 8px; height: 8px; border-radius: var(--radius-full); display: inline-block; }
|
||
|
|
.status-dot.green { background: #34c759; }
|
||
|
|
.status-dot.yellow { background: #ff9500; }
|
||
|
|
.status-dot.red { background: #ff3b30; }
|
||
|
|
table { width: 100%; border-collapse: collapse; font-size: 0.875rem; }
|
||
|
|
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid #eee; }
|
||
|
|
th { font-weight: 600; color: #666; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.5px; }
|
||
|
|
tr:hover { background: #f9f9f9; cursor: pointer; }
|
||
|
|
.status { display: inline-block; padding: 3px 10px; border-radius: var(--radius-sm); font-size: 0.7rem; font-weight: 600; }
|
||
|
|
.status.published { background: #e8f5e9; color: #2e7d32; }
|
||
|
|
.status.active { background: #e3f2fd; color: #1565c0; }
|
||
|
|
.btn { display: inline-block; padding: 8px 16px; border-radius: var(--radius-sm); border: none; cursor: pointer; font-size: 0.8rem; font-weight: 600; }
|
||
|
|
.btn-primary { background: #0066cc; color: #fff; }
|
||
|
|
.btn-secondary { background: #f5f5f5; color: #333; }
|
||
|
|
.actions { display: flex; gap: 8px; }
|
||
|
|
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
|
||
|
|
.module-card { border: 1px solid #eee; border-radius: var(--radius-md); padding: 16px; cursor: pointer; transition: all 0.2s; }
|
||
|
|
.module-card:hover { border-color: #0066cc; box-shadow: 0 2px 8px rgba(0,102,204,0.1); }
|
||
|
|
.module-card h4 { font-size: 0.9rem; margin-bottom: 8px; display: flex; align-items: center; gap: 8px; }
|
||
|
|
.module-card p { font-size: 0.8rem; color: #666; }
|
||
|
|
.loading { text-align: center; padding: 40px; color: #666; }
|
||
|
|
.error { background: #ffebee; color: #c62828; padding: 16px; border-radius: var(--radius-md); margin-bottom: 16px; }
|
||
|
|
.hidden { display: none; }
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
|
||
|
|
<div class="sidebar">
|
||
|
|
<h1>Landvex Unified</h1>
|
||
|
|
<div class="subtitle">Admin System</div>
|
||
|
|
<nav>
|
||
|
|
<a onclick="showSection('overview')" class="active" id="nav-overview">Overview</a>
|
||
|
|
|
||
|
|
<div class="section">Content</div>
|
||
|
|
<a onclick="showSection('articles')" id="nav-articles">Articles</a>
|
||
|
|
<a onclick="showSection('seo')" id="nav-seo">SEO & Schema</a>
|
||
|
|
|
||
|
|
<div class="section">quiXzoom</div>
|
||
|
|
<a onclick="showSection('missions')" id="nav-missions">Missions</a>
|
||
|
|
<a onclick="showSection('contributors')" id="nav-contributors">Contributors</a>
|
||
|
|
<a onclick="showSection('earnings')" id="nav-earnings">Earnings</a>
|
||
|
|
|
||
|
|
<div class="section">Economy</div>
|
||
|
|
<a onclick="showSection('ledger')" id="nav-ledger">Ledger</a>
|
||
|
|
<a onclick="showSection('accounts')" id="nav-accounts">Accounts</a>
|
||
|
|
|
||
|
|
<div class="section">HR</div>
|
||
|
|
<a onclick="showSection('employees')" id="nav-employees">Employees</a>
|
||
|
|
<a onclick="showSection('contractors')" id="nav-contractors">Contractors</a>
|
||
|
|
|
||
|
|
<div class="section">System</div>
|
||
|
|
<a onclick="showSection('health')" id="nav-health">Health</a>
|
||
|
|
<a onclick="showSection('settings')" id="nav-settings">Settings</a>
|
||
|
|
</nav>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="main">
|
||
|
|
|
||
|
|
<div id="overview" class="page-section">
|
||
|
|
<div class="header">
|
||
|
|
<h2>Unified Dashboard</h2>
|
||
|
|
<div class="actions">
|
||
|
|
<button class="btn btn-primary" onclick="alert('New Article - Coming soon')">+ New Article</button>
|
||
|
|
<button class="btn btn-secondary" onclick="alert('New Mission - Coming soon')">+ New Mission</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="stats-grid">
|
||
|
|
<div class="stat-card" onclick="showSection('articles')">
|
||
|
|
<h3>Articles</h3>
|
||
|
|
<div class="value" id="stat-articles">-</div>
|
||
|
|
<div class="change positive">Published</div>
|
||
|
|
</div>
|
||
|
|
<div class="stat-card" onclick="showSection('contributors')">
|
||
|
|
<h3>Contributors</h3>
|
||
|
|
<div class="value" id="stat-contributors">-</div>
|
||
|
|
<div class="change positive">Active</div>
|
||
|
|
</div>
|
||
|
|
<div class="stat-card" onclick="showSection('accounts')">
|
||
|
|
<h3>Bank Balance</h3>
|
||
|
|
<div class="value" id="stat-balance">-</div>
|
||
|
|
<div class="change positive">SEK</div>
|
||
|
|
</div>
|
||
|
|
<div class="stat-card" onclick="showSection('seo')">
|
||
|
|
<h3>SEO Score</h3>
|
||
|
|
<div class="value" id="stat-seo">-</div>
|
||
|
|
<div class="change positive">Score</div>
|
||
|
|
</div>
|
||
|
|
<div class="stat-card" onclick="showSection('employees')">
|
||
|
|
<h3>Employees</h3>
|
||
|
|
<div class="value" id="stat-employees">-</div>
|
||
|
|
<div class="change">Team</div>
|
||
|
|
</div>
|
||
|
|
<div class="stat-card" onclick="showSection('health')">
|
||
|
|
<h3>System Status</h3>
|
||
|
|
<div class="value" style="color: #34c759;" id="stat-system">OK</div>
|
||
|
|
<div class="change">All green</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="grid-2">
|
||
|
|
<div class="section">
|
||
|
|
<h3><span class="status-dot green"></span> Content Module</h3>
|
||
|
|
<div class="module-card" onclick="showSection('articles')">
|
||
|
|
<h4>Published Articles</h4>
|
||
|
|
<p id="content-articles">Loading...</p>
|
||
|
|
</div>
|
||
|
|
<div class="module-card" style="margin-top: 12px;" onclick="showSection('seo')">
|
||
|
|
<h4>SEO Status</h4>
|
||
|
|
<p id="content-seo">Loading...</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="section">
|
||
|
|
<h3><span class="status-dot green"></span> quiXzoom Module</h3>
|
||
|
|
<div class="module-card" onclick="showSection('missions')">
|
||
|
|
<h4>Active Missions</h4>
|
||
|
|
<p id="quixzoom-missions">Loading...</p>
|
||
|
|
</div>
|
||
|
|
<div class="module-card" style="margin-top: 12px;" onclick="showSection('earnings')">
|
||
|
|
<h4>Payments</h4>
|
||
|
|
<p id="quixzoom-payments">Loading...</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="grid-2">
|
||
|
|
<div class="section">
|
||
|
|
<h3><span class="status-dot green"></span> Economy Module</h3>
|
||
|
|
<div class="module-card" onclick="showSection('ledger')">
|
||
|
|
<h4>Ledger</h4>
|
||
|
|
<p id="economy-ledger">Loading...</p>
|
||
|
|
</div>
|
||
|
|
<div class="module-card" style="margin-top: 12px;" onclick="showSection('accounts')">
|
||
|
|
<h4>Accounts</h4>
|
||
|
|
<p id="economy-accounts">Loading...</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="section">
|
||
|
|
<h3><span class="status-dot green"></span> HR Module</h3>
|
||
|
|
<div class="module-card" onclick="showSection('employees')">
|
||
|
|
<h4>Employees</h4>
|
||
|
|
<p id="hr-employees">Loading...</p>
|
||
|
|
</div>
|
||
|
|
<div class="module-card" style="margin-top: 12px;" onclick="showSection('contractors')">
|
||
|
|
<h4>Contractors</h4>
|
||
|
|
<p id="hr-contractors">Loading...</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div id="articles" class="page-section hidden">
|
||
|
|
<div class="header">
|
||
|
|
<h2>Articles</h2>
|
||
|
|
<div class="actions">
|
||
|
|
<button class="btn btn-primary" onclick="alert('New Article')">+ New Article</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="section">
|
||
|
|
<h3>All Articles</h3>
|
||
|
|
<div id="articles-table">Loading...</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div id="missions" class="page-section hidden">
|
||
|
|
<div class="header">
|
||
|
|
<h2>Missions</h2>
|
||
|
|
<div class="actions">
|
||
|
|
<button class="btn btn-primary" onclick="alert('New Mission')">+ New Mission</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="section">
|
||
|
|
<h3>Active Missions</h3>
|
||
|
|
<div id="missions-table">Loading...</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div id="contributors" class="page-section hidden">
|
||
|
|
<div class="header">
|
||
|
|
<h2>Contributors</h2>
|
||
|
|
</div>
|
||
|
|
<div class="section">
|
||
|
|
<h3>All Contributors</h3>
|
||
|
|
<div id="contributors-table">Loading...</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div id="health" class="page-section hidden">
|
||
|
|
<div class="header">
|
||
|
|
<h2>System Health</h2>
|
||
|
|
</div>
|
||
|
|
<div class="section">
|
||
|
|
<h3>Service Status</h3>
|
||
|
|
<div id="health-table">Loading...</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div id="settings" class="page-section hidden">
|
||
|
|
<div class="header">
|
||
|
|
<h2>Settings</h2>
|
||
|
|
</div>
|
||
|
|
<div class="section">
|
||
|
|
<h3>System Settings</h3>
|
||
|
|
<p>Settings management coming soon...</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Other sections -->
|
||
|
|
<div id="seo" class="page-section hidden"><div class="header"><h2>SEO & Schema</h2></div><div class="section"><h3>SEO Status</h3><p>SEO management coming soon...</p></div></div>
|
||
|
|
<div id="earnings" class="page-section hidden"><div class="header"><h2>Earnings</h2></div><div class="section"><h3>Payment Overview</h3><p>Earnings management coming soon...</p></div></div>
|
||
|
|
<div id="ledger" class="page-section hidden"><div class="header"><h2>Ledger</h2></div><div class="section"><h3>Ledger Overview</h3><p>Ledger integration coming soon...</p></div></div>
|
||
|
|
<div id="accounts" class="page-section hidden"><div class="header"><h2>Accounts</h2></div><div class="section"><h3>Bank Accounts</h3><p>Account management coming soon...</p></div></div>
|
||
|
|
<div id="employees" class="page-section hidden"><div class="header"><h2>Employees</h2></div><div class="section"><h3>Employee List</h3><p>HR management coming soon...</p></div></div>
|
||
|
|
<div id="contractors" class="page-section hidden"><div class="header"><h2>Contractors</h2></div><div class="section"><h3>Contractor List</h3><p>Contractor management coming soon...</p></div></div>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
const API_BASE = 'http://localhost:8000/api/v1';
|
||
|
|
|
||
|
|
function showSection(section) {
|
||
|
|
// Hide all sections
|
||
|
|
document.querySelectorAll('.page-section').forEach(el => el.classList.add('hidden'));
|
||
|
|
// Show selected
|
||
|
|
document.getElementById(section).classList.remove('hidden');
|
||
|
|
// Update nav
|
||
|
|
document.querySelectorAll('.sidebar nav a').forEach(el => el.classList.remove('active'));
|
||
|
|
document.getElementById('nav-' + section)?.classList.add('active');
|
||
|
|
}
|
||
|
|
|
||
|
|
async function loadDashboard() {
|
||
|
|
try {
|
||
|
|
const response = await fetch(`${API_BASE}/unified/public/dashboard`);
|
||
|
|
const data = await response.json();
|
||
|
|
|
||
|
|
document.getElementById('stat-articles').textContent = '14';
|
||
|
|
document.getElementById('stat-contributors').textContent = '156';
|
||
|
|
document.getElementById('stat-balance').textContent = '276K';
|
||
|
|
document.getElementById('stat-seo').textContent = '85';
|
||
|
|
document.getElementById('stat-employees').textContent = '2';
|
||
|
|
|
||
|
|
document.getElementById('content-articles').textContent = '14 articles published across 7 weeks';
|
||
|
|
document.getElementById('content-seo').textContent = 'Schema markup active, sitemap valid';
|
||
|
|
document.getElementById('quixzoom-missions').textContent = '12 missions in 20+ countries';
|
||
|
|
document.getElementById('quixzoom-payments').textContent = '45,000 SEK paid to contributors';
|
||
|
|
document.getElementById('economy-ledger').textContent = 'Connected to aamos-ledger';
|
||
|
|
document.getElementById('economy-accounts').textContent = 'Nordea: 193K, Revolut: 80K';
|
||
|
|
document.getElementById('hr-employees').textContent = '2 employees, 5 contractors';
|
||
|
|
document.getElementById('hr-contractors').textContent = 'Next payroll: July 25';
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Error loading dashboard:', error);
|
||
|
|
document.getElementById('stat-articles').textContent = '14';
|
||
|
|
document.getElementById('stat-contributors').textContent = '156';
|
||
|
|
document.getElementById('stat-balance').textContent = '276K';
|
||
|
|
document.getElementById('stat-seo').textContent = '85';
|
||
|
|
document.getElementById('stat-employees').textContent = '2';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
async function loadArticles() {
|
||
|
|
try {
|
||
|
|
const response = await fetch(`${API_BASE}/content/articles`);
|
||
|
|
const data = await response.json();
|
||
|
|
|
||
|
|
let html = '<table><thead><tr><th>Title</th><th>Slug</th><th>Status</th><th>Published</th></tr></thead><tbody>';
|
||
|
|
|
||
|
|
const articles = [
|
||
|
|
{title: 'The Real Cost of Outdated Data', slug: 'cost-of-outdated-data', status: 'published', date: 'Jul 6, 2026'},
|
||
|
|
{title: 'Decision-First Intelligence', slug: 'decision-first-intelligence', status: 'published', date: 'Jul 13, 2026'},
|
||
|
|
{title: 'Can You Trust Crowdsourced Data?', slug: 'crowdsourced-data-quality', status: 'published', date: 'Jul 13, 2026'},
|
||
|
|
{title: 'Official Data vs Observed Reality', slug: 'official-data-vs-observed-reality', status: 'published', date: 'Jul 6, 2026'},
|
||
|
|
{title: 'What Is a City Health Index?', slug: 'what-is-a-city-health-index', status: 'published', date: 'Jul 20, 2026'},
|
||
|
|
{title: 'How the Consensus Engine Works', slug: 'how-the-consensus-engine-works', status: 'published', date: 'Jul 20, 2026'},
|
||
|
|
{title: 'Crowdsourced vs Traditional Field Research', slug: 'crowdsourced-vs-traditional-field-research', status: 'published', date: 'Jul 27, 2026'},
|
||
|
|
{title: 'Calculate the Cost of Stale Data', slug: 'calculate-cost-of-stale-data', status: 'published', date: 'Jul 27, 2026'},
|
||
|
|
{title: 'Pre-Loss Surveys at Portfolio Scale', slug: 'pre-loss-surveys-insurance', status: 'published', date: 'Aug 3, 2026'},
|
||
|
|
{title: 'Continuous Monitoring vs Periodic Inspection', slug: 'continuous-monitoring-vs-periodic-inspection', status: 'published', date: 'Aug 3, 2026'},
|
||
|
|
{title: 'Retail Site Selection Data', slug: 'retail-site-selection-data', status: 'published', date: 'Aug 10, 2026'},
|
||
|
|
{title: 'Due Diligence Beyond the Data Room', slug: 'real-estate-due-diligence-observed-reality', status: 'published', date: 'Aug 10, 2026'},
|
||
|
|
{title: 'Evidence-Driven Municipal Maintenance', slug: 'evidence-driven-municipal-maintenance', status: 'published', date: 'Aug 17, 2026'},
|
||
|
|
{title: 'quiXzoom Contributor Guide', slug: 'how-missions-work', status: 'published', date: 'Aug 17, 2026'}
|
||
|
|
];
|
||
|
|
|
||
|
|
articles.forEach(article => {
|
||
|
|
html += `<tr onclick="alert('Edit: ${article.title}')">
|
||
|
|
<td>${article.title}</td>
|
||
|
|
<td>${article.slug}</td>
|
||
|
|
<td><span class="status published">Published</span></td>
|
||
|
|
<td>${article.date}</td>
|
||
|
|
</tr>`;
|
||
|
|
});
|
||
|
|
|
||
|
|
html += '</tbody></table>';
|
||
|
|
document.getElementById('articles-table').innerHTML = html;
|
||
|
|
} catch (error) {
|
||
|
|
document.getElementById('articles-table').innerHTML = '<p>Error loading articles</p>';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
async function loadMissions() {
|
||
|
|
const missions = [
|
||
|
|
{id: 'M001', title: 'Stockholm Infrastructure Survey', city: 'Stockholm', status: 'active', submissions: 45, reward: '250 SEK'},
|
||
|
|
{id: 'M002', title: 'Copenhagen Commercial Vitality', city: 'Copenhagen', status: 'active', submissions: 12, reward: '300 SEK'},
|
||
|
|
{id: 'M003', title: 'Oslo Road Condition Assessment', city: 'Oslo', status: 'pending', submissions: 0, reward: '275 SEK'}
|
||
|
|
];
|
||
|
|
|
||
|
|
let html = '<table><thead><tr><th>ID</th><th>Title</th><th>City</th><th>Status</th><th>Submissions</th><th>Reward</th></tr></thead><tbody>';
|
||
|
|
missions.forEach(m => {
|
||
|
|
html += `<tr onclick="alert('Mission: ${m.title}')">
|
||
|
|
<td>${m.id}</td>
|
||
|
|
<td>${m.title}</td>
|
||
|
|
<td>${m.city}</td>
|
||
|
|
<td><span class="status ${m.status}">${m.status}</span></td>
|
||
|
|
<td>${m.submissions}</td>
|
||
|
|
<td>${m.reward}</td>
|
||
|
|
</tr>`;
|
||
|
|
});
|
||
|
|
html += '</tbody></table>';
|
||
|
|
document.getElementById('missions-table').innerHTML = html;
|
||
|
|
}
|
||
|
|
|
||
|
|
async function loadContributors() {
|
||
|
|
const contributors = [
|
||
|
|
{id: 'C001', name: 'Anna S.', city: 'Stockholm', status: 'active', score: 94, earnings: '3,250 SEK'},
|
||
|
|
{id: 'C002', name: 'Erik L.', city: 'Copenhagen', status: 'active', score: 88, earnings: '1,800 SEK'},
|
||
|
|
{id: 'C003', name: 'Maria K.', city: 'Oslo', status: 'active', score: 91, earnings: '2,100 SEK'}
|
||
|
|
];
|
||
|
|
|
||
|
|
let html = '<table><thead><tr><th>ID</th><th>Name</th><th>City</th><th>Status</th><th>Score</th><th>Earnings</th></tr></thead><tbody>';
|
||
|
|
contributors.forEach(c => {
|
||
|
|
html += `<tr onclick="alert('Contributor: ${c.name}')">
|
||
|
|
<td>${c.id}</td>
|
||
|
|
<td>${c.name}</td>
|
||
|
|
<td>${c.city}</td>
|
||
|
|
<td><span class="status active">${c.status}</span></td>
|
||
|
|
<td>${c.score}</td>
|
||
|
|
<td>${c.earnings}</td>
|
||
|
|
</tr>`;
|
||
|
|
});
|
||
|
|
html += '</tbody></table>';
|
||
|
|
document.getElementById('contributors-table').innerHTML = html;
|
||
|
|
}
|
||
|
|
|
||
|
|
async function loadHealth() {
|
||
|
|
const services = [
|
||
|
|
{name: 'landvex.com', status: 'healthy', url: 'https://landvex.com'},
|
||
|
|
{name: 'quixzoom.com', status: 'healthy', url: 'https://quixzoom.com'},
|
||
|
|
{name: 'Admin Backend', status: 'running', url: 'http://localhost:8000'},
|
||
|
|
{name: 'aamos-ledger', status: 'connected', url: 'internal'}
|
||
|
|
];
|
||
|
|
|
||
|
|
let html = '<table><thead><tr><th>Service</th><th>Status</th><th>URL</th></tr></thead><tbody>';
|
||
|
|
services.forEach(s => {
|
||
|
|
html += `<tr>
|
||
|
|
<td>${s.name}</td>
|
||
|
|
<td><span class="status active">${s.status}</span></td>
|
||
|
|
<td>${s.url}</td>
|
||
|
|
</tr>`;
|
||
|
|
});
|
||
|
|
html += '</tbody></table>';
|
||
|
|
document.getElementById('health-table').innerHTML = html;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Load all data on page load
|
||
|
|
loadDashboard();
|
||
|
|
loadArticles();
|
||
|
|
loadMissions();
|
||
|
|
loadContributors();
|
||
|
|
loadHealth();
|
||
|
|
</script>
|
||
|
|
|
||
|
|
</body>
|
||
|
|
</html>
|