Files
lanecarford_front/src/views/login/LoginPage.vue

326 lines
7.0 KiB
Vue
Raw Normal View History

<template>
<div class="login-page">
<div class="content">
<div class="back-button" @click="goBack">
<img src="@/assets/images/arrow_left.png" class="back-icon" />
</div>
<div class="header">
<div class="title">Log in.</div>
<p class="subtitle">Redefine the styling experience with AI.</p>
<p class="subtitle">Use Styling Angel to speed up your fashion journey.</p>
</div>
<div class="login-container">
2025-10-22 14:03:57 +08:00
<div class="login-form">
<div class="input-group">
2025-10-22 14:03:57 +08:00
<input type="email" v-model="formData.email" placeholder="Email" class="input-field" />
</div>
<div class="input-group pwd">
<input
type="password"
v-model="formData.password"
placeholder="Your Password"
class="input-field"
/>
</div>
2025-10-22 14:03:57 +08:00
<div class="login-button" @click="handleLogin">Log in</div>
<div class="forgot-password" @click="handleForgotPassword">Forgot password?</div>
<div type="button" class="google-button" @click="handleGoogleLogin">
<img :src="google" class="google-icon" />
Sign in with Google
</div>
<div class="sign-up-button" @click="handleSignup">Dont have an account? Sign Up</div>
2025-10-22 14:03:57 +08:00
</div>
</div>
</div>
<div class="footer">
<p>Powered by AiDLab for Lane Crawford</p>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
import { useRouter } from 'vue-router'
import { showToast } from 'vant'
import { google } from '@/assets/base64'
2025-10-24 17:37:15 +08:00
import { fetchLogin } from '@/api/login'
const router = useRouter()
// 表单数据
2025-10-13 15:28:53 +08:00
const formData = reactive<Record<string, string>>({
email: '',
password: ''
})
// 移除表单错误状态管理,改用 toast 提示
// 加载状态
const isLoading = ref(false)
// 表单验证规则
const validateEmail = (email: string) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return emailRegex.test(email)
}
const validatePassword = (password: string) => {
return password.length >= 6
}
// 验证表单
const validateForm = () => {
// 验证邮箱
if (!formData.email) {
showToast('请输入邮箱地址')
return false
} else if (!validateEmail(formData.email)) {
showToast('请输入有效的邮箱地址')
return false
}
// 验证密码
if (!formData.password) {
showToast('请输入密码')
return false
} else if (!validatePassword(formData.password)) {
showToast('密码至少需要6位字符')
return false
}
return true
}
// 返回上一页
const goBack = () => {
router.go(-1)
}
// 处理登录
const handleLogin = async () => {
if (!validateForm()) {
return
}
isLoading.value = true
2025-10-24 17:37:15 +08:00
const response: any = await fetchLogin({ ...formData, operationType: 'LOGIN' } as any)
if (response.code === 200) {
console.log('登录成功', response)
// showToast('登录成功')
// router.push('/stylist/customer')
} else {
showToast(response.message)
}
2025-10-24 17:37:15 +08:00
// showToast('登录成功')
2025-10-24 17:37:15 +08:00
// 登录成功后跳转到主页或工作台
// router.push('/stylist/customer')
}
// 处理忘记密码
const handleForgotPassword = () => {
// 这里可以跳转到忘记密码页面
2025-10-22 14:03:57 +08:00
router.push('/reset')
}
// 处理Google登录
const handleGoogleLogin = async () => {
try {
isLoading.value = true
showToast('Google登录功能开发中...')
// 这里添加Google OAuth登录逻辑
// const response = await googleLoginAPI()
} catch (error) {
console.error('Google登录失败:', error)
showToast('Google登录失败请重试')
} finally {
isLoading.value = false
}
}
// 处理注册
const handleSignup = () => {
router.push('/signup')
}
// 移除实时验证输入的错误显示逻辑,改用表单提交时统一验证
</script>
<style scoped lang="less">
.login-page {
position: relative;
color: #fff;
width: 100%;
height: 100vh;
overflow: hidden;
display: flex;
flex-direction: column;
background-image: url('@/assets/images/login_bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
padding-top: 12rem;
font-family: 'satoshiRegular';
}
.back-button {
// position: absolute;
// top: 2rem;
// left: 2rem;
margin-top: 2.4rem;
margin-left: 6.1rem;
width: 2rem;
height: 3.4rem;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 3;
font-size: 3.4rem;
.back-icon {
width: 2.83rem;
height: 3.47rem;
}
}
.header {
margin-top: 1.42rem;
padding-left: 15.5rem;
color: white;
2025-10-13 10:13:54 +08:00
font-family: 'satoshiRegular';
.title {
font-size: 11rem;
font-weight: bold;
margin-bottom: 0.8rem;
color: white;
font-family: 'satoshiBold';
}
.subtitle {
font-size: 3rem;
color: white;
font-weight: 400;
line-height: 141%;
letter-spacing: 0.08rem;
}
}
.content {
position: relative;
// z-index: 2;
flex: 1;
}
.login-container {
display: flex;
align-items: center;
justify-content: center;
margin-top: 7.2rem;
.login-form {
position: relative;
width: calc(100% - 28.4rem);
height: 107.8rem;
background: radial-gradient(
100% 100% at 0% 0%,
rgba(115, 115, 115, 0.4) 0%,
rgba(0, 0, 0, 0) 100%
);
backdrop-filter: blur(35px);
border: 2px solid rgba(255, 255, 255, 0.15);
border-radius: 4.79rem;
padding: 11.2rem 8.62rem 14.28rem 7.18rem;
box-shadow: 0 0.8rem 3.2rem rgba(0, 0, 0, 0.1);
overflow: hidden;
border: 2px solid #fff;
font-size: 3.83rem;
}
.input-field {
width: 100%;
height: 10rem;
padding: 16px 20px;
border: 2px solid #fff;
background: transparent;
border-radius: 7.1rem;
color: white;
outline: none;
font-size: 3.83rem;
padding: 0 5.5rem;
}
.input-field::placeholder {
color: rgba(255, 255, 255, 0.6);
font-size: 3.83rem;
}
.input-group {
margin-bottom: 4rem;
&.pwd {
margin-bottom: 6.7rem;
}
}
.login-button {
width: 100%;
height: 10rem;
background: #000;
color: white;
border: none;
border-radius: 7rem;
font-size: 4rem;
margin-bottom: 1.67rem;
2025-10-22 14:03:57 +08:00
text-align: center;
line-height: 10rem;
}
.forgot-password {
font-family: 'satoshiRegular';
font-size: 2.39rem;
font-weight: 400;
text-align: center;
text-decoration: underline;
text-decoration-style: bold;
margin-bottom: 21.47rem;
}
}
.google-button {
width: 100%;
padding: 16px;
border: 2px solid #fff;
border-radius: 7rem;
font-size: 3.83rem;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
column-gap: 3.1rem;
margin-bottom: 1.67rem;
}
.sign-up-button {
font-family: 'satoshiRegular';
font-size: 2.39rem;
font-weight: 400;
text-align: center;
}
.google-icon {
width: 4.8rem;
height: 4.8rem;
}
.footer {
position: relative;
text-align: center;
color: white;
font-size: 3rem;
margin-bottom: 15.5rem;
}
</style>