feat: adjust signup form validation based on locale
This commit is contained in:
parent
5ad1621c1f
commit
52442082a2
@ -42,8 +42,9 @@
|
||||
"Please confirm password": "请确认密码",
|
||||
"Passwords do not match": "两次输入的密码不一致",
|
||||
"Email (Optional)": "邮箱(可选)",
|
||||
"Phone Number": "手机号",
|
||||
"Phone Number (Optional)": "手机号(可选)",
|
||||
"Please enter email": "请输入邮箱",
|
||||
"Mobile": "手机号",
|
||||
"Mobile (Optional)": "手机号(可选)",
|
||||
"Please enter a valid email address": "请输入有效的邮箱地址",
|
||||
"Please enter phone number": "请输入手机号",
|
||||
"Please enter a valid phone number": "请输入有效的手机号码",
|
||||
|
||||
@ -3,7 +3,7 @@ import { computed, ref, watch, onMounted, onUnmounted, nextTick, reactive } from
|
||||
import { NButton, NSpace, useMessage, NModal, NForm, NFormItem, NInput, NText, NLayout, NLayoutSider, NLayoutHeader, NLayoutContent } from 'naive-ui'
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { useSEO } from '@/shared/composables/useSEO'
|
||||
import { t } from '@/shared/i18n'
|
||||
import { t, getCurrentLocale } from '@/shared/i18n'
|
||||
import { useAuthStore } from '@/shared/stores/auth'
|
||||
import { signupApi } from '@/shared/api/auth'
|
||||
import AppHeader from '@/app/layouts/AppHeader.vue'
|
||||
@ -58,41 +58,81 @@ const validatePasswordMatch = (_rule: any, value: string) => {
|
||||
return true
|
||||
}
|
||||
|
||||
const signupRules = {
|
||||
username: [
|
||||
{ required: true, message: t('Please enter username'), trigger: 'blur' },
|
||||
{ min: 3, message: t('Username must be at least 3 characters'), trigger: 'blur' }
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: t('Please enter password'), trigger: 'blur' },
|
||||
{ min: 6, message: t('Password must be at least 6 characters'), trigger: 'blur' }
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, message: t('Please confirm password'), trigger: 'blur' },
|
||||
{ validator: validatePasswordMatch, trigger: 'blur' }
|
||||
],
|
||||
email: [
|
||||
{
|
||||
validator: (_rule: any, value: string) => {
|
||||
if (!value) return true
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||||
if (!emailRegex.test(value)) {
|
||||
return new Error(t('Please enter a valid email address'))
|
||||
}
|
||||
return true
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
phoneNumber: [
|
||||
{ required: true, message: t('Please enter phone number'), trigger: 'blur' },
|
||||
{
|
||||
pattern: /^1[3-9]\d{9}$/,
|
||||
message: t('Please enter a valid phone number'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
const isEnglish = computed(() => getCurrentLocale() === 'en-US')
|
||||
|
||||
const signupRules = computed(() => {
|
||||
const rules: any = {
|
||||
username: [
|
||||
{ required: true, message: t('Please enter username'), trigger: 'blur' },
|
||||
{ min: 3, message: t('Username must be at least 3 characters'), trigger: 'blur' }
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: t('Please enter password'), trigger: 'blur' },
|
||||
{ min: 6, message: t('Password must be at least 6 characters'), trigger: 'blur' }
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, message: t('Please confirm password'), trigger: 'blur' },
|
||||
{ validator: validatePasswordMatch, trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 英文版:email必填,手机号可选
|
||||
if (isEnglish.value) {
|
||||
rules.email = [
|
||||
{ required: true, message: t('Please enter email'), trigger: 'blur' },
|
||||
{
|
||||
validator: (_rule: any, value: string) => {
|
||||
// required规则已处理空值,这里只验证格式
|
||||
if (!value) return true
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||||
if (!emailRegex.test(value)) {
|
||||
return new Error(t('Please enter a valid email address'))
|
||||
}
|
||||
return true
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
rules.phoneNumber = [
|
||||
{
|
||||
validator: (_rule: any, value: string) => {
|
||||
if (!value) return true
|
||||
const phoneRegex = /^1[3-9]\d{9}$/
|
||||
if (!phoneRegex.test(value)) {
|
||||
return new Error(t('Please enter a valid phone number'))
|
||||
}
|
||||
return true
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
} else {
|
||||
// 中文版:email可选,手机号必填
|
||||
rules.email = [
|
||||
{
|
||||
validator: (_rule: any, value: string) => {
|
||||
if (!value) return true
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||||
if (!emailRegex.test(value)) {
|
||||
return new Error(t('Please enter a valid email address'))
|
||||
}
|
||||
return true
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
rules.phoneNumber = [
|
||||
{ required: true, message: t('Please enter phone number'), trigger: 'blur' },
|
||||
{
|
||||
pattern: /^1[3-9]\d{9}$/,
|
||||
message: t('Please enter a valid phone number'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
return rules
|
||||
})
|
||||
|
||||
const handleLogin = () => {
|
||||
showLoginModal.value = true
|
||||
@ -134,7 +174,7 @@ const handleSignupSubmit = async () => {
|
||||
username: signupFormData.username,
|
||||
password: signupFormData.password,
|
||||
email: signupFormData.email || undefined,
|
||||
phone_number: signupFormData.phoneNumber
|
||||
phone_number: isEnglish.value ? (signupFormData.phoneNumber || undefined) : signupFormData.phoneNumber
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
@ -1508,7 +1548,7 @@ onUnmounted(() => {
|
||||
<n-form-item path="email">
|
||||
<n-input
|
||||
v-model:value="signupFormData.email"
|
||||
:placeholder="t('Email (Optional)')"
|
||||
:placeholder="isEnglish ? t('Email') : t('Email (Optional)')"
|
||||
:input-props="{ autocomplete: 'email', type: 'email' }"
|
||||
>
|
||||
<template #prefix>
|
||||
@ -1517,10 +1557,10 @@ onUnmounted(() => {
|
||||
</n-input>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item path="phoneNumber">
|
||||
<n-form-item v-if="!isEnglish" path="phoneNumber">
|
||||
<n-input
|
||||
v-model:value="signupFormData.phoneNumber"
|
||||
:placeholder="t('Phone Number')"
|
||||
:placeholder="t('Mobile')"
|
||||
:input-props="{ autocomplete: 'tel' }"
|
||||
>
|
||||
<template #prefix>
|
||||
|
||||
@ -59,7 +59,7 @@
|
||||
<n-form-item path="email">
|
||||
<n-input
|
||||
v-model:value="formData.email"
|
||||
:placeholder="t('Email (Optional)')"
|
||||
:placeholder="isEnglish ? t('Email') : t('Email (Optional)')"
|
||||
:input-props="{ autocomplete: 'email', type: 'email' }"
|
||||
>
|
||||
<template #prefix>
|
||||
@ -68,10 +68,10 @@
|
||||
</n-input>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item path="phoneNumber">
|
||||
<n-form-item v-if="!isEnglish" path="phoneNumber">
|
||||
<n-input
|
||||
v-model:value="formData.phoneNumber"
|
||||
:placeholder="t('Phone Number')"
|
||||
:placeholder="t('Mobile')"
|
||||
:input-props="{ autocomplete: 'tel' }"
|
||||
>
|
||||
<template #prefix>
|
||||
@ -112,7 +112,7 @@ import { useRouter } from 'vue-router'
|
||||
import { NForm, NFormItem, NInput, NButton, NText, useMessage } from 'naive-ui'
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { useAuthStore } from '../../shared/stores/auth'
|
||||
import { t } from '../../shared/i18n'
|
||||
import { t, getCurrentLocale } from '../../shared/i18n'
|
||||
import { signupApi } from '../../shared/api/auth'
|
||||
|
||||
const router = useRouter()
|
||||
@ -137,41 +137,81 @@ const validatePasswordMatch = (_rule: any, value: string) => {
|
||||
return true
|
||||
}
|
||||
|
||||
const rules = {
|
||||
username: [
|
||||
{ required: true, message: t('Please enter username'), trigger: 'blur' },
|
||||
{ min: 3, message: t('Username must be at least 3 characters'), trigger: 'blur' }
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: t('Please enter password'), trigger: 'blur' },
|
||||
{ min: 6, message: t('Password must be at least 6 characters'), trigger: 'blur' }
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, message: t('Please confirm password'), trigger: 'blur' },
|
||||
{ validator: validatePasswordMatch, trigger: 'blur' }
|
||||
],
|
||||
email: [
|
||||
{
|
||||
validator: (_rule: any, value: string) => {
|
||||
if (!value) return true
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||||
if (!emailRegex.test(value)) {
|
||||
return new Error(t('Please enter a valid email address'))
|
||||
}
|
||||
return true
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
phoneNumber: [
|
||||
{ required: true, message: t('Please enter phone number'), trigger: 'blur' },
|
||||
{
|
||||
pattern: /^1[3-9]\d{9}$/,
|
||||
message: t('Please enter a valid phone number'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
const isEnglish = computed(() => getCurrentLocale() === 'en-US')
|
||||
|
||||
const rules = computed(() => {
|
||||
const rules: any = {
|
||||
username: [
|
||||
{ required: true, message: t('Please enter username'), trigger: 'blur' },
|
||||
{ min: 3, message: t('Username must be at least 3 characters'), trigger: 'blur' }
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: t('Please enter password'), trigger: 'blur' },
|
||||
{ min: 6, message: t('Password must be at least 6 characters'), trigger: 'blur' }
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, message: t('Please confirm password'), trigger: 'blur' },
|
||||
{ validator: validatePasswordMatch, trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 英文版:email必填,手机号可选
|
||||
if (isEnglish.value) {
|
||||
rules.email = [
|
||||
{ required: true, message: t('Please enter email'), trigger: 'blur' },
|
||||
{
|
||||
validator: (_rule: any, value: string) => {
|
||||
// required规则已处理空值,这里只验证格式
|
||||
if (!value) return true
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||||
if (!emailRegex.test(value)) {
|
||||
return new Error(t('Please enter a valid email address'))
|
||||
}
|
||||
return true
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
rules.phoneNumber = [
|
||||
{
|
||||
validator: (_rule: any, value: string) => {
|
||||
if (!value) return true
|
||||
const phoneRegex = /^1[3-9]\d{9}$/
|
||||
if (!phoneRegex.test(value)) {
|
||||
return new Error(t('Please enter a valid phone number'))
|
||||
}
|
||||
return true
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
} else {
|
||||
// 中文版:email可选,手机号必填
|
||||
rules.email = [
|
||||
{
|
||||
validator: (_rule: any, value: string) => {
|
||||
if (!value) return true
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||||
if (!emailRegex.test(value)) {
|
||||
return new Error(t('Please enter a valid email address'))
|
||||
}
|
||||
return true
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
rules.phoneNumber = [
|
||||
{ required: true, message: t('Please enter phone number'), trigger: 'blur' },
|
||||
{
|
||||
pattern: /^1[3-9]\d{9}$/,
|
||||
message: t('Please enter a valid phone number'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
return rules
|
||||
})
|
||||
|
||||
const handleSignup = async () => {
|
||||
try {
|
||||
@ -182,7 +222,7 @@ const handleSignup = async () => {
|
||||
username: formData.username,
|
||||
password: formData.password,
|
||||
email: formData.email || undefined,
|
||||
phone_number: formData.phoneNumber
|
||||
phone_number: isEnglish.value ? (formData.phoneNumber || undefined) : formData.phoneNumber
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user