v4
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<q-page class="flex column items-center justify-between">
|
||||
<q-page class="flex column items-center justify-center">
|
||||
|
||||
<q-card
|
||||
id="login_block"
|
||||
flat
|
||||
@@ -10,22 +11,37 @@
|
||||
:style="{ alignItems: 'flex-end' }"
|
||||
/>
|
||||
|
||||
<div class = "q-ma-md flex column input-login">
|
||||
<div class="q-ma-md flex column input-login">
|
||||
<q-input
|
||||
v-model="login"
|
||||
autofocus
|
||||
dense
|
||||
filled
|
||||
class = "q-mb-md"
|
||||
:label = "$t('login__email')"
|
||||
class="q-mb-sm"
|
||||
:label="$t('login__email')"
|
||||
:rules="validationRules.email"
|
||||
lazy-rules="ondemand"
|
||||
no-error-icon
|
||||
@focus="emailInput?.resetValidation()"
|
||||
@blur="delayValidity('login')"
|
||||
ref="emailInput"
|
||||
/>
|
||||
|
||||
<q-input
|
||||
v-model="password"
|
||||
dense
|
||||
filled
|
||||
:label = "$t('login__password')"
|
||||
class = "q-mb-md"
|
||||
:label="$t('login__password')"
|
||||
class="q-mb-none q-mt-xs"
|
||||
:type="isPwd ? 'password' : 'text'"
|
||||
hide-hint
|
||||
:hint="passwordHint"
|
||||
:rules="validationRules.password"
|
||||
lazy-rules="ondemand"
|
||||
no-error-icon
|
||||
@focus="passwordInput?.resetValidation()"
|
||||
@blur="delayValidity('password')"
|
||||
ref="passwordInput"
|
||||
>
|
||||
<template #append>
|
||||
<q-icon
|
||||
@@ -35,24 +51,25 @@
|
||||
@click="isPwd = !isPwd"
|
||||
/>
|
||||
</template>
|
||||
|
||||
</q-input>
|
||||
|
||||
<div class="self-end">
|
||||
<q-btn
|
||||
@click="forgotPwd"
|
||||
@click.prevent="forgotPwd"
|
||||
flat
|
||||
no-caps
|
||||
dense
|
||||
class="text-grey"
|
||||
>
|
||||
{{$t('login__forgot_password')}}
|
||||
{{$t('login__forgot_password')}}
|
||||
</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
<q-btn
|
||||
@click="sendAuth"
|
||||
@click="sendAuth()"
|
||||
color="primary"
|
||||
:disabled="!acceptTermsOfUse"
|
||||
:disabled="!acceptTermsOfUse || !isEmailValid || !isPasswordValid"
|
||||
>
|
||||
{{$t('login__sign_in')}}
|
||||
</q-btn>
|
||||
@@ -62,7 +79,7 @@
|
||||
sm
|
||||
no-caps
|
||||
color="primary"
|
||||
@click="createAccount()"
|
||||
@click="createAccount"
|
||||
>
|
||||
{{$t('login__register')}}
|
||||
</q-btn>
|
||||
@@ -83,7 +100,7 @@
|
||||
sm
|
||||
no-caps
|
||||
color="primary"
|
||||
:disabled="!acceptTermsOfUse"
|
||||
:disabled="!acceptTermsOfUse || !isEmailValid || !isPasswordValid"
|
||||
@click="handleTelegramLogin"
|
||||
>
|
||||
<div class="flex items-center text-blue">
|
||||
@@ -100,7 +117,10 @@
|
||||
</div>
|
||||
</q-card>
|
||||
|
||||
<div id="term-of-use" class="q-py-lg text-white q-flex row">
|
||||
<div
|
||||
id="term-of-use"
|
||||
class="absolute-bottom q-py-lg text-white flex justify-center row"
|
||||
>
|
||||
<q-checkbox
|
||||
v-model="acceptTermsOfUse"
|
||||
checked-icon="task_alt"
|
||||
@@ -110,24 +130,31 @@
|
||||
keep-color
|
||||
/>
|
||||
<span class="q-px-xs">
|
||||
{{$t('login__accept_terms_of_use') + ' '}}
|
||||
{{ $t('login__accept_terms_of_use') + ' ' }}
|
||||
</span>
|
||||
<span class="text-cyan-12">
|
||||
{{$t('login__terms_of_use') }}
|
||||
<span
|
||||
@click="router.push('terms-of-use')"
|
||||
style="text-decoration: underline;"
|
||||
>
|
||||
{{ $t('login__terms_of_use') }}
|
||||
</span>
|
||||
</div>
|
||||
</q-page>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, inject } from 'vue'
|
||||
import { ref, computed, inject, onUnmounted } from 'vue'
|
||||
import { useQuasar } from 'quasar'
|
||||
import { useRouter } from 'vue-router'
|
||||
import loginLogo from 'components/admin/login-page/loginLogo.vue'
|
||||
import loginLogo from 'components/login-page/loginLogo.vue'
|
||||
import { useI18n } from "vue-i18n"
|
||||
import { useAuthStore } from 'src/stores/auth'
|
||||
import type { WebApp } from '@twa-dev/types'
|
||||
import { QInput } from 'quasar'
|
||||
import type { ServerError } from 'boot/axios'
|
||||
|
||||
type ValidationRule = (val: string) => boolean | string
|
||||
|
||||
const tg = inject('tg') as WebApp
|
||||
const tgUser = tg.initDataUnsafe.user
|
||||
|
||||
@@ -141,9 +168,50 @@
|
||||
const isPwd = ref<boolean>(true)
|
||||
const acceptTermsOfUse = ref<boolean>(true)
|
||||
|
||||
function onErrorLogin () {
|
||||
const emailInput = ref<InstanceType<typeof QInput>>()
|
||||
const passwordInput = ref<InstanceType<typeof QInput>>()
|
||||
|
||||
const validationRules = {
|
||||
email: [(val: string) => /.+@.+\..+/.test(val) || t('login__incorrect_email')] as [ValidationRule],
|
||||
password: [(val: string) => val.length >= 8 || t('login__password_require')] as [ValidationRule]
|
||||
}
|
||||
|
||||
const isEmailValid = computed(() =>
|
||||
validationRules.email.every(f => f(login.value) === true)
|
||||
)
|
||||
|
||||
const isPasswordValid = computed(() =>
|
||||
validationRules.password.every(f => f(password.value) === true)
|
||||
)
|
||||
|
||||
const passwordHint = computed(() => {
|
||||
const result = validationRules.password[0](password.value)
|
||||
return typeof result === 'string' ? result : ''
|
||||
})
|
||||
|
||||
// fix validity problem with router.push
|
||||
type Field = 'login' | 'password'
|
||||
|
||||
const validateTimerId = ref<Record<Field, ReturnType<typeof setTimeout> | null>>({
|
||||
login: null,
|
||||
password: null
|
||||
})
|
||||
|
||||
const delayValidity = (type: Field) => {
|
||||
validateTimerId.value[type] = setTimeout(() => {
|
||||
void (async () => {
|
||||
if (validateTimerId.value[type] !== null) {
|
||||
clearTimeout(validateTimerId.value[type])
|
||||
}
|
||||
if (type === 'login') await emailInput.value?.validate()
|
||||
if (type === 'password') await passwordInput.value?.validate()
|
||||
})()
|
||||
}, 300)
|
||||
}
|
||||
|
||||
function onErrorLogin (error: ServerError) {
|
||||
$q.notify({
|
||||
message: t('login__incorrect_login_data'),
|
||||
message: t(error.message) + ' (' + t('code') + ':' + error.code + ')',
|
||||
type: 'negative',
|
||||
position: 'bottom',
|
||||
timeout: 2000,
|
||||
@@ -152,18 +220,22 @@
|
||||
}
|
||||
|
||||
async function sendAuth() {
|
||||
console.log('1')
|
||||
try { void await authStore.loginWithCredentials(login.value, password.value) }
|
||||
catch (error) {
|
||||
console.log(error)
|
||||
onErrorLogin(error as ServerError)
|
||||
}
|
||||
await router.push({ name: 'projects' })
|
||||
}
|
||||
|
||||
|
||||
async function forgotPwd() {
|
||||
await router.push({
|
||||
name: 'recovery_password',
|
||||
query: { email: login.value }
|
||||
})
|
||||
sessionStorage.setItem('pendingLogin', login.value)
|
||||
await router.push({ name: 'recovery_password' })
|
||||
}
|
||||
|
||||
async function createAccount() {
|
||||
sessionStorage.setItem('pendingLogin', login.value)
|
||||
await router.push({ name: 'create_account' })
|
||||
}
|
||||
|
||||
@@ -181,6 +253,10 @@ async function handleTelegramLogin () {
|
||||
const initData = window.Telegram.WebApp.initData
|
||||
await authStore.loginWithTelegram(initData)
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
Object.values(validateTimerId.value).forEach(timer => timer && clearTimeout(timer))
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user