225 lines
5.0 KiB
Vue
225 lines
5.0 KiB
Vue
<template>
|
|
<el-dialog
|
|
class="login-dialog"
|
|
v-model="show"
|
|
header-class="login-dialog-header"
|
|
align-center
|
|
destroy-on-close
|
|
:show-close="false"
|
|
:close-on-press-escape="false"
|
|
:close-on-click-modal="false"
|
|
>
|
|
<div class="login-dialog-content">
|
|
<img class="bg" src="@/assets/images/login/bg.jpg" />
|
|
<img class="logo" src="@/assets/images/logo.png" />
|
|
<div class="close" @click="show = false"><svg-icon name="close" /></div>
|
|
<div class="content" v-if="curentTabInfo">
|
|
<div class="header">
|
|
<div class="title" v-show="curentTabInfo.title">
|
|
<div class="icon" @click="onBack"><svg-icon name="back" size="17" /></div>
|
|
<div class="label">{{ curentTabInfo.title }}</div>
|
|
</div>
|
|
<div class="nav" v-show="!curentTabInfo.title">
|
|
<div
|
|
class="item"
|
|
:class="{ active: currentTab === TabNames.sign_up }"
|
|
@click="currentTab = TabNames.sign_up"
|
|
>
|
|
SIGN UP
|
|
</div>
|
|
<div
|
|
class="item"
|
|
:class="{ active: currentTab === TabNames.login }"
|
|
@click="currentTab = TabNames.login"
|
|
>
|
|
LOG IN
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<component
|
|
:is="curentTabInfo.component"
|
|
@retrieve-password="currentTab = TabNames.retrieve_password"
|
|
@login="onLogin"
|
|
@register="onRegister"
|
|
@submit-email-code="onSubmitEmailCode"
|
|
:name="data.name"
|
|
:email="data.email"
|
|
:password="data.password"
|
|
type="FORGOT_PWD"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</el-dialog>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, ref, markRaw, watch, onBeforeUnmount } from 'vue'
|
|
import md5 from 'md5'
|
|
import login from './login.vue'
|
|
import register from './register.vue'
|
|
import emailVerify from './email-verify.vue'
|
|
import myEvent from '@/utils/myEvent'
|
|
const data = ref({
|
|
name: '',
|
|
email: '',
|
|
password: '',
|
|
type: ''
|
|
})
|
|
const show = ref(false)
|
|
const TabNames = {
|
|
login: 'login',
|
|
sign_up: 'sign_up',
|
|
email_verify: 'email_verify',
|
|
retrieve_password: 'retrieve_password'
|
|
}
|
|
const tabList = markRaw([
|
|
{
|
|
name: TabNames.login,
|
|
component: login
|
|
},
|
|
{
|
|
name: TabNames.sign_up,
|
|
component: register
|
|
},
|
|
{
|
|
name: TabNames.email_verify,
|
|
title: 'EMAIL VERIFICATION',
|
|
component: emailVerify
|
|
},
|
|
{
|
|
name: TabNames.retrieve_password,
|
|
title: 'RETRIEVE PASSWORD',
|
|
component: login
|
|
}
|
|
])
|
|
const currentTab = ref(TabNames.login)
|
|
const curentTabInfo = computed(() => tabList.find((v) => v.name === currentTab.value))
|
|
const lastTab = ref('')
|
|
watch(currentTab, (v, o) => (lastTab.value = o))
|
|
const onBack = () => {
|
|
if (lastTab.value) currentTab.value = lastTab.value
|
|
}
|
|
const open = (type?: string) => {
|
|
currentTab.value = TabNames[type] || TabNames.login
|
|
data.value.name = ''
|
|
data.value.email = ''
|
|
data.value.password = ''
|
|
show.value = true
|
|
}
|
|
myEvent.add('openLoginDialog', open)
|
|
onBeforeUnmount(() => {
|
|
myEvent.remove('openLoginDialog', open)
|
|
})
|
|
|
|
const onLogin = (res: any) => {
|
|
data.value = res
|
|
data.value.type = TabNames.login
|
|
currentTab.value = TabNames.email_verify
|
|
}
|
|
const onRegister = (res: any) => {
|
|
data.value = res
|
|
data.value.type = TabNames.sign_up
|
|
currentTab.value = TabNames.email_verify
|
|
}
|
|
const onSubmitEmailCode = (code: string) => {
|
|
// data.value.code = code
|
|
console.log(code)
|
|
show.value = false
|
|
}
|
|
</script>
|
|
|
|
<style lang="less">
|
|
.login-dialog-header {
|
|
display: none;
|
|
}
|
|
.el-dialog.login-dialog {
|
|
--el-dialog-border-radius: 0;
|
|
--el-dialog-padding-primary: 0;
|
|
}
|
|
.login-dialog-content {
|
|
width: 90rem;
|
|
height: 62rem;
|
|
position: relative;
|
|
> .bg {
|
|
width: 100%;
|
|
height: 100%;
|
|
display: block;
|
|
}
|
|
> * {
|
|
position: absolute;
|
|
}
|
|
> .logo {
|
|
width: auto;
|
|
height: 4rem;
|
|
top: 4rem;
|
|
left: 3rem;
|
|
}
|
|
> .close {
|
|
width: 3rem;
|
|
height: 3rem;
|
|
top: 2rem;
|
|
right: 2rem;
|
|
cursor: pointer;
|
|
}
|
|
> .content {
|
|
width: 34rem;
|
|
top: 5rem;
|
|
right: 6rem;
|
|
height: calc(100% - 10rem);
|
|
> .header {
|
|
--padding-bottom: 1.2rem;
|
|
padding-bottom: var(--padding-bottom);
|
|
border-bottom: 0.1rem solid #9f9f9f;
|
|
> div {
|
|
display: flex;
|
|
height: 3rem;
|
|
}
|
|
> .nav {
|
|
> .item {
|
|
user-select: none;
|
|
cursor: pointer;
|
|
flex: 1;
|
|
height: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
position: relative;
|
|
font-size: 2rem;
|
|
font-family: KaiseiOpti-Regular;
|
|
color: #9f9f9f;
|
|
&.active {
|
|
font-family: KaiseiOpti-Bold;
|
|
color: #232323;
|
|
|
|
&::after {
|
|
content: '';
|
|
position: absolute;
|
|
bottom: calc(0rem - var(--padding-bottom) - 0.2rem);
|
|
left: 0;
|
|
width: 100%;
|
|
height: 0;
|
|
border-bottom: 0.4rem solid #232323;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
> .title {
|
|
align-items: center;
|
|
justify-content: center;
|
|
> .icon {
|
|
width: 2.4rem;
|
|
height: 2.4rem;
|
|
cursor: pointer;
|
|
margin-right: 1rem;
|
|
}
|
|
> .label {
|
|
font-family: KaiseiOpti-Bold;
|
|
font-size: 2rem;
|
|
color: #232323;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|