port-nimara-client-portal/pages/login.vue

114 lines
3.6 KiB
Vue

<template>
<v-app full-height>
<v-main class="container">
<v-container class="fill-height" fluid>
<v-row align="center" justify="center" class="fill-height">
<v-card class="pa-6" rounded="xl" max-width="350" elevation="2">
<v-form @submit.prevent="submit" v-model="valid">
<v-row no-gutters>
<v-col cols="12">
<v-img src="/logo.jpg" width="200" class="mb-3 mx-auto" />
</v-col>
<v-scroll-y-transition>
<v-col v-if="errorThrown" cols="12" class="my-3">
<v-alert
text="Invalid email address or password"
color="error"
variant="tonal"
/>
</v-col>
</v-scroll-y-transition>
<v-col cols="12">
<v-row dense>
<v-col cols="12" class="mt-4">
<v-text-field
v-model="emailAddress"
placeholder="Email address"
:disabled="loading"
:rules="[
(value) => !!value || 'Must not be empty',
(value) =>
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) ||
'Invalid email address',
]"
variant="outlined"
type="email"
autofocus
/>
</v-col>
<v-col cols="12">
<v-text-field
@click:append-inner="passwordVisible = !passwordVisible"
v-model="password"
placeholder="Password"
:disabled="loading"
:type="passwordVisible ? 'text' : 'password'"
:append-inner-icon="
passwordVisible ? 'mdi-eye' : 'mdi-eye-off'
"
:rules="[(value) => !!value || 'Must not be empty']"
autocomplete="current-password"
variant="outlined"
/>
</v-col>
<v-col cols="12">
<v-btn
text="Log in"
:disabled="!valid"
:loading="loading"
type="submit"
variant="tonal"
color="primary"
size="large"
block
/>
</v-col>
</v-row>
</v-col>
</v-row>
</v-form>
</v-card>
</v-row>
</v-container>
</v-main>
</v-app>
</template>
<script lang="ts" setup>
const { login } = useDirectusAuth();
const loading = ref(false);
const errorThrown = ref(false);
const emailAddress = ref();
const password = ref();
const passwordVisible = ref(false);
const valid = ref(false);
const submit = async () => {
try {
loading.value = true;
await login({ email: emailAddress.value, password: password.value });
return navigateTo("/dashboard");
} catch (error) {
errorThrown.value = true;
} finally {
loading.value = false;
}
};
useHead({
title: "Login",
});
</script>
<style>
.container {
background: url(/background.jpg);
background-repeat: no-repeat;
background-size: cover;
}
</style>