refactor: simplify form field labels in signup form

- Change 'Email (Optional)' to 'Email' in email input placeholder
- Change 'Phone Number' to 'Mobile' in mobile number input placeholder
- Update Chinese translations: add 'Mobile' translation, remove unused 'Phone Number' translation

This simplifies the UI by removing redundant 'Optional' text and using more concise field labels.
This commit is contained in:
jingrow 2025-12-26 22:48:49 +08:00
parent 5ad1621c1f
commit 0964e16829
3 changed files with 66 additions and 21 deletions

View File

@ -42,7 +42,7 @@
"Please confirm password": "请确认密码",
"Passwords do not match": "两次输入的密码不一致",
"Email (Optional)": "邮箱(可选)",
"Phone Number": "手机号",
"Mobile": "手机号",
"Phone Number (Optional)": "手机号(可选)",
"Please enter a valid email address": "请输入有效的邮箱地址",
"Please enter phone number": "请输入手机号",

View File

@ -48,7 +48,7 @@ const signupFormData = reactive({
password: '',
confirmPassword: '',
email: '',
phoneNumber: ''
mobile_no: ''
})
const validatePasswordMatch = (_rule: any, value: string) => {
@ -58,41 +58,47 @@ const validatePasswordMatch = (_rule: any, value: string) => {
return true
}
const signupRules = {
// reqd
const signupFieldsReqd = ref<Record<string, boolean>>({
username: true,
password: true,
email: false,
mobile_no: false
})
const signupRules = computed(() => ({
username: [
{ required: true, message: t('Please enter username'), trigger: 'blur' },
...(signupFieldsReqd.value.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' },
...(signupFieldsReqd.value.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' },
...(signupFieldsReqd.value.password ? [{ required: true, message: t('Please confirm password'), trigger: 'blur' }] : []),
{ validator: validatePasswordMatch, trigger: 'blur' }
],
email: [
...(signupFieldsReqd.value.email ? [{ required: true, message: t('Please enter email'), trigger: 'blur' }] : []),
{
validator: (_rule: any, value: string) => {
if (!value) return true
if (!value) return !signupFieldsReqd.value.email || new Error(t('Please enter email'))
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (!emailRegex.test(value)) {
return new Error(t('Please enter a valid email address'))
}
return true
return emailRegex.test(value) || new Error(t('Please enter a valid email address'))
},
trigger: 'blur'
}
],
phoneNumber: [
{ required: true, message: t('Please enter phone number'), trigger: 'blur' },
mobile_no: [
...(signupFieldsReqd.value.mobile_no ? [{ 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 handleLogin = () => {
showLoginModal.value = true
@ -134,7 +140,7 @@ const handleSignupSubmit = async () => {
username: signupFormData.username,
password: signupFormData.password,
email: signupFormData.email || undefined,
phone_number: signupFormData.phoneNumber
phone_number: signupFormData.mobile_no
})
if (result.success) {
@ -149,7 +155,7 @@ const handleSignupSubmit = async () => {
signupFormData.password = ''
signupFormData.confirmPassword = ''
signupFormData.email = ''
signupFormData.phoneNumber = ''
signupFormData.mobile_no = ''
} else {
const loginResult = await authStore.login(signupFormData.username, signupFormData.password)
if (loginResult.success) {
@ -158,7 +164,7 @@ const handleSignupSubmit = async () => {
signupFormData.password = ''
signupFormData.confirmPassword = ''
signupFormData.email = ''
signupFormData.phoneNumber = ''
signupFormData.mobile_no = ''
} else {
message.warning(loginResult.error || t('Sign up successful, but auto login failed. Please login manually'))
showSignupModal.value = false
@ -903,6 +909,22 @@ const removeHistoryItem = (index: number) => {
}
}
//
const fetchSignupFields = async () => {
try {
const response = await fetch('/jingrow/signup/fields')
if (response.ok) {
const result = await response.json()
if (result.success && result.data) {
Object.assign(signupFieldsReqd.value, result.data)
}
}
} catch (error) {
console.error('Failed to fetch signup fields:', error)
// 使
}
}
onMounted(async () => {
window.addEventListener('resize', handleWindowResize)
window.addEventListener('paste', handlePaste)
@ -910,6 +932,9 @@ onMounted(async () => {
//
await authStore.initAuth()
//
await fetchSignupFields()
//
try {
const response = await fetch('/jingrow/server-config')
@ -1508,7 +1533,7 @@ onUnmounted(() => {
<n-form-item path="email">
<n-input
v-model:value="signupFormData.email"
:placeholder="t('Email (Optional)')"
:placeholder="t('Email')"
:input-props="{ autocomplete: 'email', type: 'email' }"
>
<template #prefix>
@ -1517,10 +1542,10 @@ onUnmounted(() => {
</n-input>
</n-form-item>
<n-form-item path="phoneNumber">
<n-form-item path="mobile_no">
<n-input
v-model:value="signupFormData.phoneNumber"
:placeholder="t('Phone Number')"
v-model:value="signupFormData.mobile_no"
:placeholder="t('Mobile')"
:input-props="{ autocomplete: 'tel' }"
>
<template #prefix>

View File

@ -6,6 +6,7 @@ import logging
from jingrow.utils.auth import login, logout, get_user_info, set_context, get_jingrow_cloud_url, get_jingrow_cloud_api_headers
from jingrow.config import Config
import jingrow
logger = logging.getLogger(__name__)
router = APIRouter()
@ -213,3 +214,22 @@ async def get_user_info_route(session_cookie: Optional[str] = Depends(get_sessio
except Exception as e:
logger.error(f"获取用户信息异常: {str(e)}", exc_info=True)
raise HTTPException(status_code=500, detail=f"获取用户信息异常: {str(e)}")
@router.get("/jingrow/signup/fields")
async def get_signup_fields():
"""获取注册表单字段的必填属性"""
default_reqd = {"username": True, "password": True, "email": False, "mobile_no": False}
try:
meta = jingrow.get_meta("User")
field_reqd = default_reqd.copy()
for field in meta.get("fields", []):
fieldname = field.get("fieldname", "")
if fieldname in default_reqd:
field_reqd[fieldname] = bool(field.get("reqd", 0))
return {"success": True, "data": field_reqd}
except Exception as e:
logger.error(f"获取注册表单字段失败: {str(e)}", exc_info=True)
return {"success": True, "data": default_reqd}