Arag / static /admin.html
AuthorBot
Restructure project for HF Spaces deployment
772f852
Raw
History Blame
4.92 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AuthorBot Admin</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: #0d0f1a; color: #e2e8f0; min-height: 100vh; padding: 32px 20px;
}
.wrap { max-width: 720px; margin: 0 auto; }
h1 { font-size: 1.75rem; margin-bottom: 8px; }
.sub { color: #94a3b8; margin-bottom: 28px; }
.panel {
background: #13161f; border: 1px solid rgba(255,255,255,0.08);
border-radius: 16px; padding: 24px; margin-bottom: 20px;
}
label { display: block; font-size: 13px; color: #94a3b8; margin-bottom: 6px; }
input {
width: 100%; padding: 10px 12px; border-radius: 8px; border: 1px solid rgba(255,255,255,0.12);
background: #0d0f1a; color: #e2e8f0; margin-bottom: 12px;
}
button, a.btn {
display: inline-block; padding: 10px 18px; border-radius: 8px; border: none;
background: #6366f1; color: white; font-weight: 600; cursor: pointer; text-decoration: none;
}
button:hover, a.btn:hover { background: #4f46e5; }
.links { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
.links a { color: #a5b4fc; text-decoration: none; font-size: 14px; }
.msg { margin-top: 12px; font-size: 14px; color: #4ade80; }
.err { color: #f87171; }
#dashboard { display: none; }
</style>
</head>
<body>
<div class="wrap">
<h1>AuthorBot Admin</h1>
<p class="sub">Manage books, uploads, and settings via the API.</p>
<div class="panel" id="login-panel">
<h2 style="margin-bottom:16px;font-size:1.1rem">Sign in</h2>
<label>Email</label>
<input id="email" type="email" placeholder="you@example.com">
<label>Password</label>
<input id="password" type="password" placeholder="Password">
<button type="button" id="login-btn">Login</button>
<p id="login-msg"></p>
<p style="margin-top:12px;font-size:13px;color:#64748b">
No account? Register via <a href="/docs#/Authentication/register_api_v1_auth_register_post" style="color:#a5b4fc">API docs</a>.
</p>
</div>
<div class="panel" id="dashboard">
<p class="msg" id="welcome"></p>
<div class="links">
<a href="/ui">Open chat UI</a>
<a href="/widget">Open widget</a>
<a href="/docs">API docs</a>
<a href="/health">Health</a>
</div>
<div class="links" style="margin-top:20px">
<a href="#" id="books-link">List books (JSON)</a>
<a href="#" id="logout-link">Logout</a>
</div>
<pre id="output" style="margin-top:16px;background:#0d0f1a;padding:12px;border-radius:8px;overflow:auto;font-size:12px;display:none"></pre>
</div>
</div>
<script>
const API = window.location.origin + '/api/v1';
const token = localStorage.getItem('access_token');
function showDashboard(email) {
document.getElementById('login-panel').style.display = 'none';
document.getElementById('dashboard').style.display = 'block';
document.getElementById('welcome').textContent = 'Signed in as ' + email;
}
if (token) showDashboard(localStorage.getItem('user_email') || 'author');
document.getElementById('login-btn').onclick = async () => {
const msg = document.getElementById('login-msg');
msg.textContent = '';
msg.className = '';
try {
const res = await fetch(API + '/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: document.getElementById('email').value,
password: document.getElementById('password').value,
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data.detail || 'Login failed');
localStorage.setItem('access_token', data.access_token);
localStorage.setItem('refresh_token', data.refresh_token);
localStorage.setItem('user_email', document.getElementById('email').value);
showDashboard(document.getElementById('email').value);
} catch (e) {
msg.textContent = e.message;
msg.className = 'err';
}
};
document.getElementById('books-link').onclick = async (e) => {
e.preventDefault();
const out = document.getElementById('output');
out.style.display = 'block';
const res = await fetch(API + '/books/', {
headers: { Authorization: 'Bearer ' + localStorage.getItem('access_token') },
});
out.textContent = JSON.stringify(await res.json(), null, 2);
};
document.getElementById('logout-link').onclick = (e) => {
e.preventDefault();
localStorage.clear();
location.reload();
};
</script>
</body>
</html>