website/src/pages/account/login/index.vue
2025-04-25 21:26:27 -04:00

90 lines
2.4 KiB
Vue

<script setup lang="ts">
import { FetchError } from 'ofetch';
const route = useRoute();
const redirect = computed(() => route.query.redirect);
const registerURI = computed(() => `/account/register${redirect.value ? `?redirect=${redirect.value}` : ''}`);
const loginForm = reactive({ username: '', password: '' });
const errorMessage = ref<string | null>();
async function loginSubmission() {
await $fetch('/api/account/login', {
method: 'POST',
body: loginForm
}).catch((error: FetchError) => {
errorMessage.value = error.statusText;
setTimeout(() => { // TODO: this is not the best way to clear this out, but this is temporary! replace all toasts with input alerts in the future
errorMessage.value = null;
}, 5000);
return;
});
if (typeof redirect.value === 'string') {
await navigateTo(redirect.value);
} else {
await navigateTo('/account');
}
}
</script>
<template>
<div>
<div class="account-form-wrapper">
<form
class="account"
@submit.prevent="loginSubmission"
>
<h2>{{ $t("account.loginForm.login") }}</h2>
<p>{{ $t("account.loginForm.detailsPrompt") }}</p>
<div>
<label for="username">{{ $t("account.loginForm.username") }}</label>
<input
id="username"
v-model="loginForm.username"
name="username"
required
>
</div>
<div>
<label for="password">{{ $t("account.loginForm.password") }}</label>
<input
id="password"
v-model="loginForm.password"
name="password"
type="password"
required
>
<a
href="/account/forgot-password"
class="pwdreset"
>{{ $t("account.loginForm.forgotPassword") }}</a>
</div>
<div class="buttons">
<button type="submit">
<!-- TODO: loading state on button. ... style maybe? -->
{{ $t("account.loginForm.login") }}
</button>
<a
:href="registerURI"
class="register"
>{{ $t("account.loginForm.registerPrompt") }}</a>
</div>
</form>
</div>
<div
v-if="errorMessage"
class="banner-notice error"
>
<div>
<p>{{ errorMessage }}</p>
</div>
</div>
</div>
</template>
<style scoped>
@import "/assets/css/auth.css";
</style>