diff options
Diffstat (limited to 'code/app/src/routes/(main)/(public)/sign-in/+page.svelte')
| -rw-r--r-- | code/app/src/routes/(main)/(public)/sign-in/+page.svelte | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/code/app/src/routes/(main)/(public)/sign-in/+page.svelte b/code/app/src/routes/(main)/(public)/sign-in/+page.svelte new file mode 100644 index 0000000..908e2ba --- /dev/null +++ b/code/app/src/routes/(main)/(public)/sign-in/+page.svelte @@ -0,0 +1,133 @@ +<script lang="ts"> + import { goto } from "$app/navigation"; + import { login } from "$lib/api/user"; + import { Button, Checkbox, Input, Alert } from "$lib/components"; + import LL from "$lib/i18n/i18n-svelte"; + import type { ErrorResult } from "$lib/models/ErrorResult"; + import type { LoginPayload } from "$lib/models/LoginPayload"; + import pwKey from "$actions/pwKey"; + import { onMount } from "svelte"; + import { messageQueryKey, signInPageTestKeys, type Message } from "."; + + let loading = false; + let messageType: Message | undefined = undefined; + + const data = { + username: "", + password: "", + persist: true, + } as LoginPayload; + + let errorData = { + text: "", + title: "", + } as ErrorResult; + $: showErrorAlert = (errorData?.text.length ?? 0 + errorData?.title.length ?? 0) > 0; + + onMount(() => { + const searcher = new URLSearchParams(window.location.search); + if (searcher.get(messageQueryKey)) { + messageType = searcher.get(messageQueryKey) as Message; + searcher.delete(messageQueryKey); + history.replaceState(null, "", window.location.origin + window.location.pathname); + } + }); + + async function submitFormAsync() { + errorData = { text: "", title: "" }; + loading = true; + data.persist = !data.persist; + const loginResponse = await login(data); + if (loginResponse.ok) { + await goto("/home"); + } else { + errorData.title = loginResponse.data.title; + errorData.text = loginResponse.data.text; + } + loading = false; + } +</script> + +<div class="min-h-full flex flex-col justify-center py-12 sm:px-6 lg:px-8"> + {#if messageType} + <div class="sm:max-w-md sm:mx-auto sm:w-full"> + {#if messageType === "after-password-reset"} + <Alert + title={$LL.signInPage.yourNewPasswordIsApplied()} + _pwKey={signInPageTestKeys.afterPasswordResetAlert} + message={$LL.signInPage.signInBelow()} + closeable + /> + {:else if messageType === "user-disabled"} + <Alert + title={$LL.signInPage.yourAccountIsDisabled()} + _pwKey={signInPageTestKeys.userDisabledAlert} + message={$LL.signInPage.contactYourAdminIfDisabled()} + closeable + /> + {:else if messageType === "user-inactivity"} + <Alert + title={$LL.signInPage.youHaveReachedInactivityLimit()} + _pwKey={signInPageTestKeys.userInactivityAlert} + message={$LL.signInPage.feelFreeToSignInAgain()} + closeable + /> + {/if} + </div> + {/if} + <div class="sm:mx-auto sm:w-full p-2 sm:p-0 sm:max-w-md"> + <h2 class="mt-6 text-3xl tracking-tight font-bold text-gray-900"> + {$LL.signInPage.signIn()} + </h2> + <p class="mt-2 text-sm text-gray-600"> + {$LL.or().toLowerCase()} + <a href="/sign-up" use:pwKey={signInPageTestKeys.signUpAnchor} class="link">{$LL.createANewAccount().toLowerCase()}</a> + </p> + </div> + <div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md"> + <div class="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10"> + {#if showErrorAlert} + <Alert title={errorData.title} message={errorData.text} type="error" _pwKey={signInPageTestKeys.formErrorAlert} /> + {/if} + <form class="space-y-6" use:pwKey={signInPageTestKeys.signInForm} on:submit|preventDefault={submitFormAsync}> + <Input + id="username" + _pwKey={signInPageTestKeys.usernameInput} + name="username" + type="email" + label={$LL.emailAddress()} + required + bind:value={data.username} + /> + + <Input + id="password" + name="password" + type="password" + label={$LL.password()} + _pwKey={signInPageTestKeys.passwordInput} + autocomplete="current-password" + required + bind:value={data.password} + /> + + <div class="flex items-center justify-between"> + <Checkbox + id="remember-me" + _pwKey={signInPageTestKeys.rememberMeCheckbox} + name="remember-me" + bind:checked={data.persist} + label={$LL.signInPage.notMyComputer()} + /> + <div class="text-sm"> + <a href="/reset-password" class="link" use:pwKey={signInPageTestKeys.resetPasswordAnchor}> + {$LL.signInPage.resetPassword()} + </a> + </div> + </div> + + <Button text={$LL.submit()} fullWidth type="submit" {loading} /> + </form> + </div> + </div> +</div> |
