finnow/web-app/src/pages/LoginPage.vue

106 lines
3.1 KiB
Vue

<script setup lang="ts">
import { AuthApiClient } from '@/api/auth';
import { ApiError } from '@/api/base';
import AppButton from '@/components/AppButton.vue';
import AppForm from '@/components/form/AppForm.vue';
import FormControl from '@/components/form/FormControl.vue';
import FormGroup from '@/components/form/FormGroup.vue';
import { useAuthStore } from '@/stores/auth-store';
import { showAlert } from '@/util/alert';
import { hideLoader, showLoader } from '@/util/loader';
import { ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
const router = useRouter()
const route = useRoute()
const authStore = useAuthStore()
const apiClient = new AuthApiClient()
const isDev = import.meta.env.DEV
const username = ref('')
const password = ref('')
const disableForm = ref(false)
async function doLogin() {
disableForm.value = true
showLoader()
try {
const token = await apiClient.login(username.value, password.value)
authStore.onUserLoggedIn(username.value, token)
hideLoader()
if ('next' in route.query && typeof (route.query.next) === 'string') {
await router.replace(route.query.next)
} else {
await router.replace('/')
}
} catch (err) {
hideLoader()
if (err instanceof ApiError) {
await showAlert(err.message)
} else {
await showAlert('Request failed: ' + JSON.stringify(err))
}
} finally {
disableForm.value = false
}
}
async function doRegister() {
disableForm.value = true
showLoader()
try {
await apiClient.register(username.value, password.value)
await doLogin()
} catch (err) {
hideLoader()
if (err instanceof ApiError) {
await showAlert(err.message)
} else {
await showAlert('Request failed: ' + JSON.stringify(err))
}
} finally {
disableForm.value = false
}
}
function isDataValid() {
return username.value.length > 0 && password.value.length >= 8
}
function generateSampleData() {
fetch(import.meta.env.VITE_API_BASE_URL + '/sample-data', {
method: 'POST'
})
}
</script>
<template>
<div class="app-login-panel">
<h1 style="text-align: center;">Login to <span style="font-family: 'PlaywriteNL';">Finnow</span></h1>
<AppForm @submit="doLogin()">
<FormGroup>
<FormControl label="Username">
<input type="text" v-model="username" :disabled="disableForm" />
</FormControl>
<FormControl label="Password">
<input id="password-input" type="password" v-model="password" :disabled="disableForm" />
</FormControl>
</FormGroup>
<div style="display: flex; margin-left: 1rem; margin-right: 1rem;">
<AppButton type="submit" :disabled="disableForm || !isDataValid()" style="flex-grow: 1;">Login
</AppButton>
<AppButton button-type="button" button-style="secondary" :disabled="disableForm || !isDataValid()"
@click="doRegister()">Register</AppButton>
</div>
<div v-if="isDev">
<AppButton button-type="button" @click="generateSampleData()">Generate Sample Data</AppButton>
</div>
</AppForm>
</div>
</template>
<style lang="css">
.app-login-panel {
max-width: 40ch;
margin: 0 auto;
}
</style>