added initial roadmap and implementation
This commit is contained in:
169
web/index.html
Normal file
169
web/index.html
Normal file
@@ -0,0 +1,169 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>MadBase Admin Dashboard</title>
|
||||
<style>
|
||||
body { font-family: system-ui, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
|
||||
h1, h2 { border-bottom: 1px solid #ccc; padding-bottom: 10px; }
|
||||
.card { border: 1px solid #eee; padding: 15px; margin-bottom: 15px; border-radius: 4px; }
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
th, td { text-align: left; padding: 8px; border-bottom: 1px solid #eee; }
|
||||
button { background: #ff4444; color: white; border: none; padding: 5px 10px; cursor: pointer; border-radius: 4px; }
|
||||
button:hover { background: #cc0000; }
|
||||
pre { background: #f5f5f5; padding: 10px; overflow: auto; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>MadBase Admin Dashboard</h1>
|
||||
|
||||
<div class="card">
|
||||
<h2>Projects</h2>
|
||||
<table id="projects-table">
|
||||
<thead><tr><th>ID</th><th>Name</th><th>Status</th><th>Action</th></tr></thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<div style="margin-top: 10px;">
|
||||
<input type="text" id="new-project-name" placeholder="New Project Name">
|
||||
<button onclick="createProject()" style="background: #44cc44;">Create Project</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Features</h2>
|
||||
<button onclick="testDB()" style="background: #0088cc;">Test DB Connection</button>
|
||||
<button onclick="fetchBuckets()" style="background: #ffaa00;">List Storage Buckets</button>
|
||||
<div id="feature-output" style="margin-top: 10px; padding: 10px; background: #eee; min-height: 50px;"></div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Users (Global)</h2>
|
||||
<table id="users-table">
|
||||
<thead><tr><th>ID</th><th>Email</th><th>Created At</th><th>Action</th></tr></thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>System Metrics</h2>
|
||||
<pre id="metrics-output">Loading...</pre>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const API_BASE = '/platform/v1';
|
||||
|
||||
async function testDB() {
|
||||
// Check health
|
||||
try {
|
||||
const res = await fetch('/');
|
||||
const text = await res.text();
|
||||
document.getElementById('feature-output').innerHTML = `Gateway Status: ${text}`;
|
||||
} catch (e) {
|
||||
document.getElementById('feature-output').innerHTML = `<span style="color:red">Connection Failed</span>`;
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchBuckets() {
|
||||
// Needs Auth... but this is Admin Dashboard.
|
||||
// Admin API doesn't expose Storage listing directly yet.
|
||||
// We can add a proxy or just check health for now.
|
||||
document.getElementById('feature-output').innerHTML = "Storage Browser: Requires authenticated user context (Not implemented in Admin UI yet)";
|
||||
}
|
||||
|
||||
async function rotateKey(id) {
|
||||
if (!confirm('Rotate keys for this project? Old keys will stop working.')) return;
|
||||
try {
|
||||
await fetch(`${API_BASE}/projects/${id}/keys`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({})
|
||||
});
|
||||
fetchProjects();
|
||||
alert('Keys rotated!');
|
||||
} catch (e) { alert('Error rotating keys'); }
|
||||
}
|
||||
|
||||
async function fetchProjects() {
|
||||
try {
|
||||
const res = await fetch(`${API_BASE}/projects`);
|
||||
const projects = await res.json();
|
||||
const tbody = document.querySelector('#projects-table tbody');
|
||||
tbody.innerHTML = projects.map(p => `
|
||||
<tr>
|
||||
<td>${p.id}</td>
|
||||
<td>${p.name}</td>
|
||||
<td>${p.status}</td>
|
||||
<td>
|
||||
<button onclick="deleteProject('${p.id}')">Delete</button>
|
||||
<button onclick="rotateKey('${p.id}')" style="background:orange;">Rotate Key</button>
|
||||
</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
} catch (e) { console.error(e); }
|
||||
}
|
||||
|
||||
async function createProject() {
|
||||
const name = document.getElementById('new-project-name').value;
|
||||
if (!name) return;
|
||||
try {
|
||||
await fetch(`${API_BASE}/projects`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name, owner_id: null })
|
||||
});
|
||||
document.getElementById('new-project-name').value = '';
|
||||
fetchProjects();
|
||||
} catch (e) { alert('Error creating project'); }
|
||||
}
|
||||
|
||||
async function deleteProject(id) {
|
||||
if (!confirm('Are you sure?')) return;
|
||||
try {
|
||||
await fetch(`${API_BASE}/projects/${id}`, { method: 'DELETE' });
|
||||
fetchProjects();
|
||||
} catch (e) { alert('Error deleting project'); }
|
||||
}
|
||||
|
||||
async function fetchUsers() {
|
||||
try {
|
||||
const res = await fetch(`${API_BASE}/users`);
|
||||
const users = await res.json();
|
||||
const tbody = document.querySelector('#users-table tbody');
|
||||
tbody.innerHTML = users.map(u => `
|
||||
<tr>
|
||||
<td>${u.id}</td>
|
||||
<td>${u.email}</td>
|
||||
<td>${new Date(u.created_at).toLocaleString()}</td>
|
||||
<td><button onclick="deleteUser('${u.id}')">Delete</button></td>
|
||||
</tr>
|
||||
`).join('');
|
||||
} catch (e) { console.error(e); }
|
||||
}
|
||||
|
||||
async function deleteUser(id) {
|
||||
if (!confirm('Are you sure?')) return;
|
||||
try {
|
||||
await fetch(`${API_BASE}/users/${id}`, { method: 'DELETE' });
|
||||
fetchUsers();
|
||||
} catch (e) { alert('Error deleting user'); }
|
||||
}
|
||||
|
||||
async function fetchMetrics() {
|
||||
try {
|
||||
const res = await fetch('/metrics');
|
||||
const text = await res.text();
|
||||
// Show only madbase metrics or summary
|
||||
document.getElementById('metrics-output').textContent = text.split('\n').filter(l => !l.startsWith('#') && l.trim()).slice(0, 10).join('\n') + '\n...';
|
||||
} catch (e) {
|
||||
document.getElementById('metrics-output').textContent = 'Error loading metrics';
|
||||
}
|
||||
}
|
||||
|
||||
fetchProjects();
|
||||
fetchUsers();
|
||||
fetchMetrics();
|
||||
setInterval(fetchMetrics, 5000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user