抽离登录对话框
This commit is contained in:
parent
d50bd58504
commit
92abcad0db
@ -1,9 +1,86 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import {ref, watch} from "vue";
|
||||||
|
import {useLocale} from "vuetify";
|
||||||
|
import {login} from "../../script/functions.ts";
|
||||||
|
|
||||||
|
const {t} = useLocale()
|
||||||
|
const showLoginDialog = defineModel<boolean>()
|
||||||
|
const username = ref('')
|
||||||
|
const password = ref('')
|
||||||
|
const passwordVisibleState = ref(false)
|
||||||
|
const loading = ref(false)
|
||||||
|
const loginDisabled = ref(false)
|
||||||
|
const loginIcon = ref<any>(null)
|
||||||
|
const isLoginFailed = ref(false)
|
||||||
|
watch(() => showLoginDialog.value, (value, oldValue) => {
|
||||||
|
if(oldValue === false && value === true) {
|
||||||
|
isLoginFailed.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
async function tryLogin() {
|
||||||
|
loading.value = true
|
||||||
|
isLoginFailed.value = false
|
||||||
|
const isSuccess = await login(username.value, password.value)
|
||||||
|
if (isSuccess) {
|
||||||
|
loginIcon.value = "mdi-check"
|
||||||
|
loading.value = false
|
||||||
|
loginDisabled.value = true
|
||||||
|
setTimeout(() => {
|
||||||
|
showLoginDialog.value = false
|
||||||
|
loginDisabled.value = false
|
||||||
|
loginIcon.value = null
|
||||||
|
}, 1500)
|
||||||
|
} else {
|
||||||
|
isLoginFailed.value = true
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetLoginError() {
|
||||||
|
isLoginFailed.value = false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<v-dialog v-model="showLoginDialog" persistent width="450">
|
||||||
|
<v-card prepend-icon="mdi-login" :title="t('$vuetify.login.title')" class="px-10">
|
||||||
|
<v-text-field class="login-dialog-input" flat prepend-inner-icon="mdi-account-outline"
|
||||||
|
:label="t('$vuetify.login.username')"
|
||||||
|
density="compact" @input="resetLoginError"
|
||||||
|
hide-details single-line rounded="lg" variant="solo-filled" v-model="username"></v-text-field>
|
||||||
|
<v-text-field class="login-dialog-input" flat prepend-inner-icon="mdi-lock-outline"
|
||||||
|
:label="t('$vuetify.login.password')"
|
||||||
|
density="compact" hide-details single-line v-model="password" rounded="lg" variant="solo-filled"
|
||||||
|
:type="passwordVisibleState ? 'text' :'password'" title="password" @input="resetLoginError"
|
||||||
|
:append-inner-icon="passwordVisibleState ? 'mdi-eye-off' : 'mdi-eye'"
|
||||||
|
@click:append-inner="passwordVisibleState = !passwordVisibleState"></v-text-field>
|
||||||
|
<v-alert class="text-medium-emphasis text-caption mb-2" type="warning" closable v-model="isLoginFailed">
|
||||||
|
{{ t('$vuetify.login.failedNote') }}
|
||||||
|
</v-alert>
|
||||||
|
<v-card color="surface-variant mt-5" variant="tonal">
|
||||||
|
<v-card-text class="text-medium-emphasis text-caption">
|
||||||
|
{{ t('$vuetify.login.agreement') }}
|
||||||
|
<v-label class="text-caption"><a href="/input" target="_blank">{{ t('$vuetify.login.termsOfService') }}</a>
|
||||||
|
</v-label>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
|
||||||
|
<v-checkbox class="login-dialog-input" :label="t('$vuetify.login.rememberMe')" hide-details
|
||||||
|
color="primary"></v-checkbox>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-btn :text="t('$vuetify.login.button.cancel')" @click="showLoginDialog = false"></v-btn>
|
||||||
|
<v-btn :loading="loading" color="primary" :text="t('$vuetify.login.button.login')" @click="tryLogin"
|
||||||
|
:icon="loginIcon"
|
||||||
|
:disabled="loginDisabled">
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.login-dialog-input {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref} from "vue";
|
import {ref, watch} from "vue";
|
||||||
import {useLocale} from "vuetify";
|
import {useLocale} from "vuetify";
|
||||||
import {register} from "../../script/functions.ts";
|
import {register} from "../../script/functions.ts";
|
||||||
|
|
||||||
@ -13,6 +13,11 @@ const registerFailedNote = ref('')
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const registerIcon = ref<any>(null)
|
const registerIcon = ref<any>(null)
|
||||||
const disableRegister = ref(false)
|
const disableRegister = ref(false)
|
||||||
|
watch(()=> showDialog.value, (value, oldValue) => {
|
||||||
|
if(oldValue === false && value === true) {
|
||||||
|
isRegisterFailed.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
async function tryRegister() {
|
async function tryRegister() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@ -69,8 +74,8 @@ function resetRegisterFailed() {
|
|||||||
</v-alert>
|
</v-alert>
|
||||||
<v-card color="surface-variant mt-5" variant="tonal">
|
<v-card color="surface-variant mt-5" variant="tonal">
|
||||||
<v-card-text class="text-medium-emphasis text-caption">
|
<v-card-text class="text-medium-emphasis text-caption">
|
||||||
{{ t('$vuetify.login.agreement') }}
|
{{ t('$vuetify.register.agreement') }}
|
||||||
<v-label class="text-caption"><a href="/input" target="_blank">{{ t('$vuetify.login.termsOfService') }}</a>
|
<v-label class="text-caption"><a href="/input" target="_blank">{{ t('$vuetify.register.termsOfService') }}</a>
|
||||||
</v-label>
|
</v-label>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
@ -1,46 +1,17 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref} from "vue";
|
import {ref} from "vue";
|
||||||
import {login, logout} from "../../script/functions";
|
import {logout} from "../../script/functions";
|
||||||
import {useUserinfoStore} from "../../stores/userinfo-store.ts";
|
import {useUserinfoStore} from "../../stores/userinfo-store.ts";
|
||||||
import {useLocale, useTheme} from "vuetify";
|
import {useLocale, useTheme} from "vuetify";
|
||||||
import RegisterDialog from "../items/RegisterDialog.vue";
|
import RegisterDialog from "../items/RegisterDialog.vue";
|
||||||
|
import LoginDialog from "../items/LoginDialog.vue";
|
||||||
|
|
||||||
const {t, current} = useLocale()
|
const {t, current} = useLocale()
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const userinfoStore = useUserinfoStore()
|
const userinfoStore = useUserinfoStore()
|
||||||
const showLoginDialog = ref(false)
|
const showLoginDialog = ref(false)
|
||||||
const username = ref('')
|
|
||||||
const password = ref('')
|
|
||||||
const passwordVisibleState = ref(false)
|
|
||||||
const loading = ref(false)
|
|
||||||
const loginDisabled = ref(false)
|
|
||||||
const loginIcon = ref<any>(null)
|
|
||||||
const isLoginFailed = ref(false)
|
|
||||||
const showRegisterDialog = ref(false)
|
const showRegisterDialog = ref(false)
|
||||||
|
|
||||||
async function tryLogin() {
|
|
||||||
loading.value = true
|
|
||||||
isLoginFailed.value = false
|
|
||||||
const isSuccess = await login(username.value, password.value)
|
|
||||||
if (isSuccess) {
|
|
||||||
loginIcon.value = "mdi-check"
|
|
||||||
loading.value = false
|
|
||||||
loginDisabled.value = true
|
|
||||||
setTimeout(() => {
|
|
||||||
showLoginDialog.value = false
|
|
||||||
loginDisabled.value = false
|
|
||||||
loginIcon.value = null
|
|
||||||
}, 1500)
|
|
||||||
} else {
|
|
||||||
isLoginFailed.value = true
|
|
||||||
loading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetLoginError() {
|
|
||||||
isLoginFailed.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleLocale() {
|
function toggleLocale() {
|
||||||
switch (current.value) {
|
switch (current.value) {
|
||||||
case 'en':
|
case 'en':
|
||||||
@ -86,7 +57,7 @@ function toggleTheme() {
|
|||||||
|
|
||||||
<v-menu open-on-hover activator="#avatar" open-delay="0" close-delay="500" location="bottom" width="150">
|
<v-menu open-on-hover activator="#avatar" open-delay="0" close-delay="500" location="bottom" width="150">
|
||||||
<v-list>
|
<v-list>
|
||||||
<v-list-item value="1" @click="showLoginDialog = true; isLoginFailed = false" v-if="!userinfoStore.isLogin"
|
<v-list-item value="1" @click="showLoginDialog = true" v-if="!userinfoStore.isLogin"
|
||||||
append-icon="mdi-login">
|
append-icon="mdi-login">
|
||||||
<v-list-item-title>{{ t('$vuetify.user.login') }}</v-list-item-title>
|
<v-list-item-title>{{ t('$vuetify.user.login') }}</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
@ -112,40 +83,7 @@ function toggleTheme() {
|
|||||||
</v-footer>
|
</v-footer>
|
||||||
</v-app>
|
</v-app>
|
||||||
</v-responsive>
|
</v-responsive>
|
||||||
<v-dialog v-model="showLoginDialog" persistent width="450">
|
<LoginDialog v-model="showLoginDialog"></LoginDialog>
|
||||||
<v-card prepend-icon="mdi-login" :title="t('$vuetify.login.title')" class="px-10">
|
|
||||||
<v-text-field class="login-dialog-input" flat prepend-inner-icon="mdi-account-outline"
|
|
||||||
:label="t('$vuetify.login.username')"
|
|
||||||
density="compact" @input="resetLoginError"
|
|
||||||
hide-details single-line rounded="lg" variant="solo-filled" v-model="username"></v-text-field>
|
|
||||||
<v-text-field class="login-dialog-input" flat prepend-inner-icon="mdi-lock-outline"
|
|
||||||
:label="t('$vuetify.login.password')"
|
|
||||||
density="compact" hide-details single-line v-model="password" rounded="lg" variant="solo-filled"
|
|
||||||
:type="passwordVisibleState ? 'text' :'password'" title="password" @input="resetLoginError"
|
|
||||||
:append-inner-icon="passwordVisibleState ? 'mdi-eye-off' : 'mdi-eye'"
|
|
||||||
@click:append-inner="passwordVisibleState = !passwordVisibleState"></v-text-field>
|
|
||||||
<v-alert class="text-medium-emphasis text-caption mb-2" type="warning" closable v-model="isLoginFailed">
|
|
||||||
{{ t('$vuetify.login.failedNote') }}
|
|
||||||
</v-alert>
|
|
||||||
<v-card color="surface-variant mt-5" variant="tonal">
|
|
||||||
<v-card-text class="text-medium-emphasis text-caption">
|
|
||||||
{{ t('$vuetify.login.agreement') }}
|
|
||||||
<v-label class="text-caption"><a href="/input" target="_blank">{{ t('$vuetify.login.termsOfService') }}</a>
|
|
||||||
</v-label>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
|
|
||||||
<v-checkbox class="login-dialog-input" :label="t('$vuetify.login.rememberMe')" hide-details
|
|
||||||
color="primary"></v-checkbox>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-btn :text="t('$vuetify.login.button.cancel')" @click="showLoginDialog = false"></v-btn>
|
|
||||||
<v-btn :loading="loading" color="primary" :text="t('$vuetify.login.button.login')" @click="tryLogin"
|
|
||||||
:icon="loginIcon"
|
|
||||||
:disabled="loginDisabled">
|
|
||||||
</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
<RegisterDialog v-model:showDialog="showRegisterDialog"></RegisterDialog>
|
<RegisterDialog v-model:showDialog="showRegisterDialog"></RegisterDialog>
|
||||||
</template>
|
</template>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -154,10 +92,6 @@ function toggleTheme() {
|
|||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-dialog-input {
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.home-menu-button {
|
.home-menu-button {
|
||||||
width: 120px;
|
width: 120px;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import RegisterDialog from "../items/RegisterDialog.vue";
|
import LoginDialog from "../items/LoginDialog.vue";
|
||||||
|
import {ref} from "vue";
|
||||||
|
|
||||||
|
const showDialog = ref(true)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<RegisterDialog></RegisterDialog>
|
<LoginDialog v-model="showDialog"></LoginDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@ -30,19 +30,18 @@ const en: LocaleInterface = {
|
|||||||
},
|
},
|
||||||
register: {
|
register: {
|
||||||
title: "REGISTER",
|
title: "REGISTER",
|
||||||
username: "USERNAME",
|
username: "USERNAME, letters and numbers, 4-16 characters",
|
||||||
password: "PASSWORD",
|
password: "PASSWORD, letters, numbers, underscores, 8-16 characters",
|
||||||
confirmPassword: "CONFIRM PASSWORD",
|
confirmPassword: "CONFIRM PASSWORD",
|
||||||
usernameInvalidNote: "Invalid username format",
|
usernameInvalidNote: "Invalid username format",
|
||||||
passwordInvalidNote: "Invalid password format",
|
passwordInvalidNote: "Invalid password format",
|
||||||
passwordConfirmInvalidNote: "Password confirmation does not match the password",
|
passwordConfirmInvalidNote: "Password confirmation does not match the password",
|
||||||
failedNote: "Register failed",
|
failedNote: "Register failed",
|
||||||
rememberMe: "string",
|
agreement: "PLEASE CONFIRM YOU HAVE READ AND AGREE TO THE",
|
||||||
agreement: "string",
|
termsOfService: "TERMS OF SERVICE",
|
||||||
termsOfService: "string",
|
|
||||||
button: {
|
button: {
|
||||||
register: "string",
|
register: "REGISTER",
|
||||||
cancel: "string"
|
cancel: "CANCEL"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,6 @@ export default interface LocaleInterface {
|
|||||||
passwordInvalidNote: string,
|
passwordInvalidNote: string,
|
||||||
passwordConfirmInvalidNote: string,
|
passwordConfirmInvalidNote: string,
|
||||||
failedNote: string,
|
failedNote: string,
|
||||||
rememberMe: string,
|
|
||||||
agreement: string,
|
agreement: string,
|
||||||
termsOfService: string,
|
termsOfService: string,
|
||||||
button: {
|
button: {
|
||||||
|
@ -37,9 +37,8 @@ const zhHans: LocaleInterface = {
|
|||||||
passwordInvalidNote: "密码不符合规则",
|
passwordInvalidNote: "密码不符合规则",
|
||||||
passwordConfirmInvalidNote: "两次输入的密码不一致",
|
passwordConfirmInvalidNote: "两次输入的密码不一致",
|
||||||
failedNote: "注册失败, 用户名重复或网络异常",
|
failedNote: "注册失败, 用户名重复或网络异常",
|
||||||
rememberMe: "string",
|
agreement: "我已阅读并同意",
|
||||||
agreement: "string",
|
termsOfService: "服务条款",
|
||||||
termsOfService: "string",
|
|
||||||
button: {
|
button: {
|
||||||
register: "注册",
|
register: "注册",
|
||||||
cancel: "取消"
|
cancel: "取消"
|
||||||
|
Loading…
Reference in New Issue
Block a user