Files
Project-Monitor/frontend/src/routes/login/+page.svelte
Sami Abuzakuk c957d839dd Small fixes
2025-11-01 16:15:35 +01:00

91 lines
2.5 KiB
Svelte

<script lang="ts">
import { goto } from '$app/navigation';
import { API_URL } from '$lib/api';
// Login form state
let loginUsername = $state('');
let loginPassword = $state('');
let loginError: string | null = $state(null);
let loginLoading = $state(false);
async function handleLogin(e: Event) {
e.preventDefault();
loginError = null;
loginLoading = true;
try {
const form = new FormData();
form.append('username', loginUsername);
form.append('password', loginPassword);
const response = await fetch(`${API_URL}/login`, {
method: 'POST',
body: form
});
if (!response.ok) {
const data = await response.json();
loginError = data.detail || 'Login failed';
loginLoading = false;
return;
}
const data = await response.json();
localStorage.setItem('token', data.access_token);
goto('/').then(() => location.reload());
} catch (err) {
loginError = 'Network error - ' + err;
} finally {
loginLoading = false;
}
}
</script>
<div class="flex flex-col items-center justify-center min-h-screen bg-gray-50">
<form
class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4 w-full max-w-sm"
onsubmit={handleLogin}
>
<h2 class="text-2xl font-bold mb-6 text-center">Login</h2>
{#if loginError}
<div class="mb-4 text-red-600 text-sm">{loginError}</div>
{/if}
<div class="mb-4">
<label class="block text-gray-700 text-sm font-bold mb-2" for="username"> Username </label>
<input
id="username"
type="text"
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
bind:value={loginUsername}
required
autocomplete="username"
/>
</div>
<div class="mb-6">
<label class="block text-gray-700 text-sm font-bold mb-2" for="password"> Password </label>
<input
id="password"
type="password"
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline"
bind:value={loginPassword}
required
autocomplete="current-password"
/>
</div>
<div class="flex items-center justify-between">
<button
type="submit"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
disabled={loginLoading}
>
{loginLoading ? 'Logging in...' : 'Login'}
</button>
<a
href="/register"
class="inline-block align-baseline font-bold text-sm text-blue-500 hover:text-blue-800 ml-4"
>
Create an account
</a>
</div>
</form>
</div>