Files
speech.capital/admin.html

78 lines
3.1 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Schema Admin</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-900 text-gray-200 font-mono min-h-screen p-8">
<div class="max-w-4xl mx-auto space-y-6">
<h1 class="text-xl font-bold">D1 Schema Management</h1>
<div class="space-y-2">
<label for="adminPass" class="block text-sm font-medium">Admin Password:</label>
<input id="adminPass" type="password" class="bg-gray-800 border border-gray-600 rounded w-full px-3 py-2 focus:ring-blue-500 focus:border-blue-500">
</div>
<div class="flex gap-4">
<button id="getSchema" class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded">Get Schema</button>
<button id="createSchema" class="bg-green-600 hover:bg-green-700 px-4 py-2 rounded">Create/Verify Schema</button>
<button id="deleteSchema" class="bg-red-600 hover:bg-red-700 px-4 py-2 rounded">Delete Schema</button>
</div>
<div class="space-y-4 pt-4 border-t border-gray-700">
<h2 class="text-lg font-bold">User Role Management</h2>
<div class="flex items-end gap-4">
<div class="flex-grow">
<label for="username" class="block text-sm font-medium">Username:</label>
<input id="username" type="text" class="bg-gray-800 border border-gray-600 rounded w-full px-3 py-2">
</div>
<div>
<label for="role" class="block text-sm font-medium">Role:</label>
<select id="role" class="bg-gray-800 border border-gray-600 rounded px-3 py-2">
<option>user</option><option>mod</option><option>admin</option><option>owner</option>
</select>
</div>
<button id="setRole" class="bg-yellow-600 hover:bg-yellow-700 px-4 py-2 rounded">Set Role</button>
</div>
</div>
<div>
<h2 class="text-lg mb-2">Output:</h2>
<pre id="output" class="bg-black p-4 rounded-lg text-sm whitespace-pre-wrap break-all min-h-[200px]"></pre>
</div>
</div>
<script>
const el = id => document.getElementById(id);
const out = el('output'), pass = el('adminPass'), user = el('username'), role = el('role');
const exec = async (action, payload = {}) => {
out.textContent = `Executing "${action}"...`;
try {
const res = await fetch('/api/schema', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action, password: pass.value, ...payload })
});
const data = await res.json();
out.textContent = JSON.stringify(data, null, 2);
if (!res.ok) throw new Error(`HTTP ${res.status}: ${data.error?.message || data.error}`);
} catch (e) {
out.textContent = `Error: ${e.message}`;
}
};
el('getSchema').addEventListener('click', () => exec('get'));
el('createSchema').addEventListener('click', () => exec('create'));
el('setRole').addEventListener('click', () => user.value && exec('set_role', { username: user.value, role: role.value }));
el('deleteSchema').addEventListener('click', () => {
if (confirm('DELETE ALL TABLES? This is irreversible.')) exec('delete');
});
</script>
</body>
</html>