Files
linearvoid/frontend/admin/login/index.html
T
zwitschi 6b494a34fe
CD / deploy (push) Failing after 27s
CI / test (push) Successful in 1m54s
CI / docker (push) Canceled after 0s
CI / release (push) Canceled after 0s
feat: add admin login page and authentication API
- Created a new login page for admin access at frontend/admin/login/index.html.
- Implemented form submission with error handling for login credentials.
- Updated frontend/index.html to mute the video player and removed unnecessary Alpine.js data binding.
- Enhanced manifest URL resolution in frontend/src/main.ts to include cache-busting parameters.
- Modified vite.config.ts to include the new admin login page in the build process.
- Updated nginx.conf to handle admin login routing, authentication, and API proxying for admin actions.
2026-08-03 17:19:05 +02:00

70 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>Linear Void Admin Login</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="../../src/style.css" />
</head>
<body class="min-h-screen bg-slate-950 text-slate-100 flex items-center justify-center px-6">
<main class="w-full max-w-md bg-slate-900 border border-slate-800 rounded-[2rem] shadow-2xl p-8">
<div class="mb-8">
<div class="text-xs uppercase tracking-[0.3em] text-slate-500 mb-3">Linear Void</div>
<h1 class="text-4xl font-semibold text-white mb-2">Admin Login</h1>
<p class="text-sm text-slate-400">Authenticate to access protected admin controls.</p>
</div>
<form id="login-form" class="space-y-4">
<label class="block text-sm">
<span class="block text-slate-400 mb-2">Username</span>
<input id="username" type="text" class="w-full bg-slate-950 border border-slate-700 rounded-xl px-4 py-3 focus:outline-none focus:border-blue-500" autocomplete="username" required />
</label>
<label class="block text-sm">
<span class="block text-slate-400 mb-2">Password</span>
<input id="password" type="password" class="w-full bg-slate-950 border border-slate-700 rounded-xl px-4 py-3 focus:outline-none focus:border-blue-500" autocomplete="current-password" required />
</label>
<button id="submit" type="submit" class="w-full bg-blue-600 hover:bg-blue-500 px-4 py-3 rounded-xl font-medium text-white">Sign in</button>
<div id="status" class="text-sm text-slate-400 min-h-6"></div>
</form>
</main>
<script>
const form = document.getElementById('login-form');
const username = document.getElementById('username');
const password = document.getElementById('password');
const submit = document.getElementById('submit');
const status = document.getElementById('status');
form.addEventListener('submit', async (event) => {
event.preventDefault();
submit.disabled = true;
status.textContent = 'Signing in...';
status.className = 'text-sm text-slate-400 min-h-6';
try {
const response = await fetch('/api/admin/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: username.value, password: password.value })
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
window.location.href = '/admin/';
} catch (error) {
console.error('Failed to sign in', error);
status.textContent = 'Login failed. Check your credentials.';
status.className = 'text-sm text-rose-400 min-h-6';
} finally {
submit.disabled = false;
}
});
</script>
</body>
</html>