115 lines
4.1 KiB
Svelte
115 lines
4.1 KiB
Svelte
<script>
|
||
import { goto } from '$app/navigation';
|
||
|
||
let username = '';
|
||
let password = '';
|
||
let error = '';
|
||
let isLoading = false;
|
||
|
||
async function handleLogin() {
|
||
if (!username || !password) {
|
||
error = 'Please enter both username and password';
|
||
return;
|
||
}
|
||
|
||
isLoading = true;
|
||
error = '';
|
||
|
||
// login request
|
||
try {
|
||
const response = await fetch('http://127.0.0.1:8000/api/login', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
username: username,
|
||
password: password
|
||
}),
|
||
credentials: 'include' // For session/cookie based auth
|
||
});
|
||
|
||
if (!response.ok) {
|
||
const errorData = await response.json();
|
||
throw new Error(errorData.message || 'Login failed');
|
||
}
|
||
|
||
const data = await response.json();
|
||
|
||
// Store token if using JWT
|
||
if (data.access) {
|
||
localStorage.setItem('accessToken', data.access);
|
||
if (data.refresh) {
|
||
localStorage.setItem('refreshToken', data.refresh);
|
||
}
|
||
}
|
||
|
||
goto('/'); // Redirect after successful login
|
||
} catch (err) {
|
||
error = err.message || 'Invalid credentials';
|
||
} finally {
|
||
isLoading = false;
|
||
}
|
||
}
|
||
</script>
|
||
|
||
|
||
<main class="container pt-3">
|
||
<div class="text-center mt-5 mb-4">
|
||
<img src="/logo-lg.svg" alt="ООО ЯКС" width="300" class="rounded-3" />
|
||
<h2 class="text-center mt-4 mb-5">Стратосферные полеты | ООО ЯКС</h2>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-12 col-md-6 col-lg-4 offset-md-3 offset-lg-4">
|
||
<div class="card">
|
||
<div class="card-body">
|
||
<h5 class="card-title">Вход в учетную запись</h5>
|
||
|
||
{#if error}
|
||
<div class="alert alert-danger mb-4" role="alert">{error}</div>
|
||
{/if}
|
||
|
||
<form on:submit|preventDefault={handleLogin} class="mt-4">
|
||
<div class="form-floating mb-3">
|
||
<input
|
||
type="text"
|
||
class="form-control"
|
||
id="username"
|
||
placeholder="Имя пользователя"
|
||
bind:value={username}
|
||
required
|
||
/>
|
||
<label for="username">Имя пользователя</label>
|
||
</div>
|
||
<div class="form-floating mb-3">
|
||
<input
|
||
type="password"
|
||
class="form-control"
|
||
id="password"
|
||
placeholder="Пароль"
|
||
bind:value={password}
|
||
required
|
||
/>
|
||
<label for="password">Пароль</label>
|
||
</div>
|
||
<button
|
||
type="submit"
|
||
class="btn btn-primary w-100"
|
||
disabled={isLoading}
|
||
>
|
||
{#if isLoading}
|
||
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
||
Вход...
|
||
{:else}
|
||
Войти
|
||
{/if}
|
||
</button>
|
||
<a href="/predict" class="btn btn-secondary mt-3 w-100">Назад</a>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
|