feat: adjust signup form validation based on locale

This commit is contained in:
jingrow 2025-12-26 23:39:47 +08:00
parent 5ad1621c1f
commit 52442082a2
3 changed files with 163 additions and 82 deletions

View File

@ -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": "请输入有效的手机号码",

View File

@ -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>

View File

@ -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) {