Files
hermes-config/skills/self-hosting/pocketbase-setup/templates/login.html
T
2026-07-12 10:17:17 -04:00

78 lines
4.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>Login — grajmedia</title>
<script src="https://unpkg.com/pocketbase@0.21.5/dist/pocketbase.umd.js"></script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: #0d1117; color: #e6edf3;
display: flex; align-items: center; justify-content: center; min-height: 100vh;
}
.card { background: #161b22; border: 1px solid #30363d; border-radius: 12px; padding: 40px; width: 100%; max-width: 400px; }
.card h1 { font-size: 24px; margin-bottom: 8px; text-align: center; }
.card p.subtitle { color: #8b949e; text-align: center; margin-bottom: 28px; font-size: 14px; }
.divider { display: flex; align-items: center; margin: 24px 0; color: #484f58; font-size: 13px; }
.divider::before, .divider::after { content: ''; flex: 1; border-bottom: 1px solid #30363d; }
.divider span { padding: 0 16px; }
.btn { display: block; width: 100%; padding: 12px; border-radius: 8px; font-size: 15px; font-weight: 600; cursor: pointer; transition: all 0.2s; text-align: center; }
.btn-google { background: #fff; color: #24292f; border-color: #d0d7de; }
.btn-google:hover { background: #f3f4f6; }
.btn-primary { background: #238636; color: #fff; border-color: #2ea043; margin-top: 16px; }
.btn-primary:hover { background: #2ea043; }
.field { margin-bottom: 16px; }
.field label { display: block; font-size: 13px; color: #8b949e; margin-bottom: 6px; }
.field input { width: 100%; padding: 10px 12px; border-radius: 6px; border: 1px solid #30363d; background: #0d1117; color: #e6edf3; font-size: 14px; }
.field input:focus { outline: none; border-color: #58a6ff; box-shadow: 0 0 0 2px rgba(88,166,255,0.3); }
.error { background: #490202; border: 1px solid #f85149; color: #f85149; padding: 10px; border-radius: 6px; margin-bottom: 16px; font-size: 13px; display: none; }
.error.show { display: block; }
</style>
</head>
<body>
<div class="card">
<div id="login-form">
<h1>🔐 grajmedia</h1>
<p class="subtitle">Sign in to continue</p>
<div class="error" id="error"></div>
<!-- Google OAuth -->
<button class="btn btn-google" onclick="loginGoogle()">Sign in with Google</button>
<div class="divider"><span>or</span></div>
<!-- Email / Password -->
<div class="field"><label>Email</label><input type="email" id="email" placeholder="you@example.com"></div>
<div class="field"><label>Password</label><input type="password" id="password" placeholder="••••••••"></div>
<button class="btn btn-primary" onclick="loginPassword()">Sign in with Email</button>
<div style="text-align:center;margin-top:20px;">
<a href="#" style="color:#58a6ff;font-size:13px;" onclick="showRegister()">Create account</a>
</div>
</div>
</div>
<script>
const pb = new PocketBase(window.location.origin);
function showError(msg) { const e = document.getElementById('error'); e.textContent = msg; e.classList.add('show'); setTimeout(() => e.classList.remove('show'), 5000); }
async function loginGoogle() {
try {
await pb.collection('users').authWithOAuth2({ provider: 'google' });
window.location.href = '/index.html';
} catch (err) { showError('Google login failed: ' + err.message); }
}
async function loginPassword() {
try {
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
await pb.collection('users').authWithPassword(email, password);
window.location.href = '/index.html';
} catch (err) { showError(err.message); }
}
</script>
</body>
</html>