74 lines
2.8 KiB
HTML
74 lines
2.8 KiB
HTML
|
|
<!doctype html>
|
||
|
|
<html lang="en">
|
||
|
|
<head>
|
||
|
|
<meta charset="utf-8" />
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
|
|
<title>Sign in · fleet-platform</title>
|
||
|
|
<style>
|
||
|
|
:root {
|
||
|
|
--bg: #0f172a;
|
||
|
|
--panel: #1e293b;
|
||
|
|
--text: #f1f5f9;
|
||
|
|
--muted: #94a3b8;
|
||
|
|
--accent: #10b981;
|
||
|
|
--bad: #ef4444;
|
||
|
|
}
|
||
|
|
* { box-sizing: border-box; }
|
||
|
|
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--text);
|
||
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif; }
|
||
|
|
body { display: grid; place-items: center; }
|
||
|
|
.card { background: var(--panel); padding: 28px 32px; border-radius: 10px; width: 320px; }
|
||
|
|
h1 { margin: 0 0 4px; font-size: 14px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); }
|
||
|
|
h2 { margin: 0 0 24px; font-size: 22px; font-weight: 600; }
|
||
|
|
label { display: block; font-size: 11px; text-transform: uppercase; color: var(--muted); letter-spacing: 0.06em; margin: 12px 0 4px; }
|
||
|
|
input { width: 100%; background: #0b1220; color: var(--text); border: 1px solid #0b1220; border-radius: 5px; padding: 9px 10px; font-size: 14px; }
|
||
|
|
button { width: 100%; margin-top: 18px; background: var(--accent); color: #062a1f; border: 0; border-radius: 5px; padding: 10px; font-size: 14px; font-weight: 600; cursor: pointer; }
|
||
|
|
button:disabled { opacity: 0.6; cursor: progress; }
|
||
|
|
.error { margin-top: 12px; color: var(--bad); font-size: 12px; min-height: 1em; }
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<form class="card" id="login">
|
||
|
|
<h1>fleet-platform</h1>
|
||
|
|
<h2>Sign in</h2>
|
||
|
|
|
||
|
|
<label for="username">Username</label>
|
||
|
|
<input id="username" name="username" autocomplete="username" required />
|
||
|
|
|
||
|
|
<label for="password">Password</label>
|
||
|
|
<input id="password" name="password" type="password" autocomplete="current-password" required />
|
||
|
|
|
||
|
|
<button type="submit" id="submit">Sign in</button>
|
||
|
|
<div class="error" id="error"></div>
|
||
|
|
</form>
|
||
|
|
|
||
|
|
<script type="module">
|
||
|
|
import { authClient } from '/fleet-core.js';
|
||
|
|
|
||
|
|
if (authClient.isAuthenticated()) {
|
||
|
|
window.location.href = '/index-live.html';
|
||
|
|
}
|
||
|
|
|
||
|
|
const form = document.getElementById('login');
|
||
|
|
const btn = document.getElementById('submit');
|
||
|
|
const errEl = document.getElementById('error');
|
||
|
|
|
||
|
|
form.addEventListener('submit', async (e) => {
|
||
|
|
e.preventDefault();
|
||
|
|
errEl.textContent = '';
|
||
|
|
btn.disabled = true;
|
||
|
|
try {
|
||
|
|
const username = document.getElementById('username').value.trim();
|
||
|
|
const password = document.getElementById('password').value;
|
||
|
|
await authClient.login(username, password);
|
||
|
|
window.location.href = '/index-live.html';
|
||
|
|
} catch (err) {
|
||
|
|
errEl.textContent = err.message || 'Sign in failed';
|
||
|
|
} finally {
|
||
|
|
btn.disabled = false;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
</body>
|
||
|
|
</html>
|