78 lines
4.1 KiB
HTML
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>
|