upend/webui/src/lib/components/LoginModal.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>