This commit is contained in:
2025-04-30 13:11:35 +03:00
parent c8f3c9801f
commit cda54b1e95
60 changed files with 1054 additions and 651 deletions

View File

@@ -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>