91 lines
1.7 KiB
Svelte
91 lines
1.7 KiB
Svelte
<script lang="ts">
|
|
import { i18n } from '$lib/i18n';
|
|
import Icon from '$lib/components/utils/Icon.svelte';
|
|
import { login } from '$lib/api';
|
|
|
|
let username = '';
|
|
let password = '';
|
|
let error: string | undefined;
|
|
let authenticating = false;
|
|
|
|
async function submit() {
|
|
error = undefined;
|
|
try {
|
|
authenticating = true;
|
|
await login({ username, password });
|
|
} catch (e) {
|
|
error = (e as object).toString();
|
|
} finally {
|
|
authenticating = false;
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<div class="modal-container">
|
|
<div class="modal" class:authenticating>
|
|
<h2>
|
|
<Icon name="lock" />
|
|
{$i18n.t('Authorization required')}
|
|
</h2>
|
|
<form on:submit|preventDefault={submit}>
|
|
<input placeholder={$i18n.t('Username')} type="text" bind:value={username} required />
|
|
<input placeholder={$i18n.t('Password')} type="password" bind:value={password} required />
|
|
<button type="submit"> <Icon plain name="log-in" /> {$i18n.t('Login')}</button>
|
|
</form>
|
|
{#if error}
|
|
<div class="error">{error}</div>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
|
|
<style lang="scss">
|
|
@use '$lib/styles/colors';
|
|
|
|
.modal-container {
|
|
position: fixed;
|
|
left: 0;
|
|
top: 0;
|
|
width: 100vw;
|
|
height: 100vh;
|
|
background: rgba(0, 0, 0, 0.66);
|
|
color: var(--foreground);
|
|
|
|
z-index: 9;
|
|
}
|
|
|
|
.modal {
|
|
position: fixed;
|
|
left: 50%;
|
|
top: 50%;
|
|
transform: translate(-50%, -50%);
|
|
background: var(--background);
|
|
color: var(--foreground);
|
|
border-radius: 5px;
|
|
border: 1px solid var(--foreground);
|
|
padding: 2rem;
|
|
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 1rem;
|
|
|
|
&.authenticating {
|
|
filter: brightness(0.66);
|
|
pointer-events: none;
|
|
}
|
|
}
|
|
|
|
h2 {
|
|
text-align: center;
|
|
margin: 0 0 1rem 0;
|
|
}
|
|
|
|
form {
|
|
display: contents;
|
|
}
|
|
|
|
.error {
|
|
color: colors.$red;
|
|
text-align: center;
|
|
}
|
|
</style>
|