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