hdwposxy/src/pages/login.vue

196 lines
5.4 KiB
Vue
Executable File

<!-- Errors in the form are set on line 60 -->
<script setup lang="ts">
import { VForm } from 'vuetify/components/VForm'
import { useGenerateImageVariant } from '@core/composable/useGenerateImageVariant'
import authV2LoginIllustrationBorderedDark from '@images/pages/auth-v2-login-illustration-bordered-dark.png'
import authV2LoginIllustrationBorderedLight from '@images/pages/auth-v2-login-illustration-bordered-light.png'
import authV2LoginIllustrationDark from '@images/pages/auth-v2-login-illustration-dark.png'
import authV2LoginIllustrationLight from '@images/pages/auth-v2-login-illustration-light.png'
import authV2MaskDark from '@images/pages/misc-mask-dark.png'
import authV2MaskLight from '@images/pages/misc-mask-light.png'
import { VNodeRenderer } from '@layouts/components/VNodeRenderer'
import { userStore } from '@stores/user.store'
import { themeConfig } from '@themeConfig'
const authThemeImg = useGenerateImageVariant(authV2LoginIllustrationLight, authV2LoginIllustrationDark, authV2LoginIllustrationBorderedLight, authV2LoginIllustrationBorderedDark, true)
const authThemeMask = useGenerateImageVariant(authV2MaskLight, authV2MaskDark)
definePage({
meta: {
layout: 'blank',
unauthenticatedOnly: true,
},
})
const isPasswordVisible = ref(false)
const route = useRoute()
const router = useRouter()
const ability = useAbility()
const errors = ref<Record<string, string | undefined>>({
username: undefined,
password: undefined,
})
const refVForm = ref<VForm>()
const credentials = ref({
username: '',
password: '',
})
const rememberMe = ref(false)
const isSnackbarVisibility = ref(false)
const useUserStore = userStore()
const login = async () => {
try {
await useUserStore.login(credentials.value.username, credentials.value.password, ability)
// Redirect to `to` query if exist or redirect to index route
// ❗ nextTick is required to wait for DOM updates and later redirect
await nextTick(() => {
router.replace(route.query.to ? String(route.query.to) : '/')
})
}
catch (err) {
// ❗ show invalid credentials error
isSnackbarVisibility.value = true
}
}
const onSubmit = () => {
refVForm.value?.validate()
.then(({ valid: isValid }) => {
if (isValid)
login()
})
}
</script>
<template>
<VRow
no-gutters
class="auth-wrapper bg-surface"
>
<VCol
lg="8"
class="d-none d-lg-flex"
>
<div class="position-relative bg-background rounded-lg w-100 ma-8 me-0">
<div class="d-flex align-center justify-center w-100 h-100">
<VImg
max-width="505"
:src="authThemeImg"
class="auth-illustration mt-16 mb-2"
/>
</div>
<VImg
:src="authThemeMask"
class="auth-footer-mask"
/>
</div>
</VCol>
<VCol
cols="12"
lg="4"
class="auth-card-v2 d-flex align-center justify-center"
>
<VCard
flat
:max-width="500"
class="mt-12 mt-sm-0 pa-4"
>
<VCardText>
<VNodeRenderer
:nodes="themeConfig.app.logo"
class="mb-6"
/>
<h4 class="text-h4 mb-1">
Welcome to <span class="text-capitalize"> {{ themeConfig.app.title }} </span>! 👋🏻
</h4>
<p class="mb-0">
Please sign-in to your account and start the adventure
</p>
</VCardText>
<VCardText>
<VForm
ref="refVForm"
@submit.prevent="onSubmit"
>
<VRow>
<!-- username -->
<VCol cols="12">
<AppTextField
v-model="credentials.username"
label="Username"
placeholder="First name"
type="username"
autofocus
:rules="[requiredValidator]"
:error-messages="errors.username"
/>
</VCol>
<!-- password -->
<VCol cols="12">
<AppTextField
v-model="credentials.password"
label="Password"
placeholder="············"
:rules="[requiredValidator]"
:type="isPasswordVisible ? 'text' : 'password'"
:error-messages="errors.password"
:append-inner-icon="isPasswordVisible ? 'tabler-eye-off' : 'tabler-eye'"
@click:append-inner="isPasswordVisible = !isPasswordVisible"
/>
<div class="d-flex align-center flex-wrap justify-space-between mt-1 mb-4">
<VCheckbox
v-model="rememberMe"
label="Remember me"
/>
</div>
<VBtn
block
type="submit"
>
Login
</VBtn>
</VCol>
</VRow>
</VForm>
</VCardText>
</VCard>
</VCol>
</VRow>
<!-- Snackbar -->
<VSnackbar
v-model="isSnackbarVisibility"
location="center"
>
Incorrect username or password ...
<template #actions>
<VBtn
color="error"
@click="isSnackbarVisibility = false"
>
Close
</VBtn>
</template>
</VSnackbar>
</template>
<style lang="scss">
@use "@core/scss/template/pages/page-auth.scss";
</style>