|
|
@@ -1,17 +1,18 @@
|
|
|
import { View, Input, Button, Text, Image } from '@tarojs/components'
|
|
|
import { useState, useEffect } from 'react'
|
|
|
import Taro from '@tarojs/taro'
|
|
|
-import { useAuth } from '@/utils/auth' // 导入 useAuth Hook
|
|
|
-import './index.css'
|
|
|
+import { useAuth } from '@/utils/auth'
|
|
|
+import { cn } from '@/utils/cn'
|
|
|
|
|
|
export default function Register() {
|
|
|
const [username, setUsername] = useState('')
|
|
|
const [email, setEmail] = useState('')
|
|
|
const [password, setPassword] = useState('')
|
|
|
const [confirmPassword, setConfirmPassword] = useState('')
|
|
|
- const { register, isLoading } = useAuth() // 使用 useAuth 获取注册方法和加载状态
|
|
|
+ const [showPassword, setShowPassword] = useState(false)
|
|
|
+ const [showConfirmPassword, setShowConfirmPassword] = useState(false)
|
|
|
+ const { register, isLoading } = useAuth()
|
|
|
|
|
|
- // 设置导航栏标题
|
|
|
useEffect(() => {
|
|
|
Taro.setNavigationBarTitle({
|
|
|
title: '创建账号'
|
|
|
@@ -65,7 +66,6 @@ export default function Register() {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- // 邮箱格式验证(如果填写了邮箱)
|
|
|
if (email.trim() && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim())) {
|
|
|
Taro.showToast({
|
|
|
title: '请输入有效的邮箱地址',
|
|
|
@@ -76,13 +76,11 @@ export default function Register() {
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
- // 显示加载动画
|
|
|
Taro.showLoading({
|
|
|
title: '注册中...',
|
|
|
mask: true
|
|
|
})
|
|
|
|
|
|
- // 使用 useAuth 提供的 register 方法
|
|
|
await register({
|
|
|
username: username.trim(),
|
|
|
password: password.trim(),
|
|
|
@@ -97,7 +95,6 @@ export default function Register() {
|
|
|
duration: 1500
|
|
|
})
|
|
|
|
|
|
- // 注册成功后跳转到首页
|
|
|
setTimeout(() => {
|
|
|
Taro.switchTab({ url: '/pages/index/index' })
|
|
|
}, 1500)
|
|
|
@@ -118,103 +115,156 @@ export default function Register() {
|
|
|
}
|
|
|
|
|
|
return (
|
|
|
- <View className="register-container">
|
|
|
- <View className="register-header">
|
|
|
- <Image
|
|
|
- className="register-logo"
|
|
|
- src="https://source.unsplash.com/200x200/?avatar"
|
|
|
- mode="aspectFit"
|
|
|
- />
|
|
|
- <View className="register-title-container">
|
|
|
- <Text className="register-title">创建账号</Text>
|
|
|
- <Text className="register-subtitle">欢迎加入我们的小程序</Text>
|
|
|
- </View>
|
|
|
- </View>
|
|
|
-
|
|
|
- <View className="register-form">
|
|
|
- <View className="form-item">
|
|
|
- <Text className="form-label">用户名</Text>
|
|
|
- <View className="input-wrapper">
|
|
|
- <Input
|
|
|
- className="form-input"
|
|
|
- placeholder="请输入用户名(3-20个字符)"
|
|
|
- value={username}
|
|
|
- onInput={(e) => setUsername(e.detail.value)}
|
|
|
- maxlength={20}
|
|
|
- />
|
|
|
- </View>
|
|
|
- </View>
|
|
|
-
|
|
|
- <View className="form-item">
|
|
|
- <Text className="form-label">邮箱(可选)</Text>
|
|
|
- <View className="input-wrapper">
|
|
|
- <Input
|
|
|
- className="form-input"
|
|
|
- placeholder="请输入邮箱地址"
|
|
|
- type="text"
|
|
|
- value={email}
|
|
|
- onInput={(e) => setEmail(e.detail.value)}
|
|
|
- maxlength={50}
|
|
|
- />
|
|
|
+ <View className="min-h-screen bg-gradient-to-br from-green-50 via-white to-emerald-50">
|
|
|
+ <View className="flex-1 px-6 py-12">
|
|
|
+ {/* Logo区域 */}
|
|
|
+ <View className="flex flex-col items-center mb-10">
|
|
|
+ <View className="w-20 h-20 mb-4 rounded-full bg-white shadow-lg flex items-center justify-center">
|
|
|
+ <View className="i-heroicons-user-plus-20-solid w-12 h-12 text-green-500" />
|
|
|
</View>
|
|
|
+ <Text className="text-2xl font-bold text-gray-900 mb-1">创建账号</Text>
|
|
|
+ <Text className="text-gray-600 text-sm">欢迎加入我们的小程序社区</Text>
|
|
|
</View>
|
|
|
-
|
|
|
- <View className="form-item">
|
|
|
- <Text className="form-label">密码</Text>
|
|
|
- <View className="input-wrapper">
|
|
|
- <Input
|
|
|
- className="form-input"
|
|
|
- placeholder="请输入密码(至少6位)"
|
|
|
- password
|
|
|
- value={password}
|
|
|
- onInput={(e) => setPassword(e.detail.value)}
|
|
|
- maxlength={20}
|
|
|
- />
|
|
|
+
|
|
|
+ {/* 注册表单 */}
|
|
|
+ <View className="bg-white rounded-2xl shadow-sm p-6">
|
|
|
+ <View className="space-y-5">
|
|
|
+ {/* 用户名输入框 */}
|
|
|
+ <View className="space-y-2">
|
|
|
+ <Text className="text-sm font-medium text-gray-700">用户名</Text>
|
|
|
+ <View className="relative">
|
|
|
+ <View className="absolute left-3 top-1/2 -translate-y-1/2">
|
|
|
+ <View className="i-heroicons-user-20-solid w-5 h-5 text-gray-400" />
|
|
|
+ </View>
|
|
|
+ <Input
|
|
|
+ className="w-full h-12 pl-10 pr-4 bg-gray-50 rounded-lg text-gray-900 placeholder-gray-500 focus:bg-white focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent"
|
|
|
+ placeholder="请输入用户名(3-20个字符)"
|
|
|
+ value={username}
|
|
|
+ onInput={(e) => setUsername(e.detail.value)}
|
|
|
+ maxlength={20}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ {/* 邮箱输入框 */}
|
|
|
+ <View className="space-y-2">
|
|
|
+ <Text className="text-sm font-medium text-gray-700">邮箱(可选)</Text>
|
|
|
+ <View className="relative">
|
|
|
+ <View className="absolute left-3 top-1/2 -translate-y-1/2">
|
|
|
+ <View className="i-heroicons-envelope-20-solid w-5 h-5 text-gray-400" />
|
|
|
+ </View>
|
|
|
+ <Input
|
|
|
+ className="w-full h-12 pl-10 pr-4 bg-gray-50 rounded-lg text-gray-900 placeholder-gray-500 focus:bg-white focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent"
|
|
|
+ placeholder="请输入邮箱地址"
|
|
|
+ type="text"
|
|
|
+ value={email}
|
|
|
+ onInput={(e) => setEmail(e.detail.value)}
|
|
|
+ maxlength={50}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ {/* 密码输入框 */}
|
|
|
+ <View className="space-y-2">
|
|
|
+ <Text className="text-sm font-medium text-gray-700">密码</Text>
|
|
|
+ <View className="relative">
|
|
|
+ <View className="absolute left-3 top-1/2 -translate-y-1/2">
|
|
|
+ <View className="i-heroicons-lock-closed-20-solid w-5 h-5 text-gray-400" />
|
|
|
+ </View>
|
|
|
+ <Input
|
|
|
+ className="w-full h-12 pl-10 pr-12 bg-gray-50 rounded-lg text-gray-900 placeholder-gray-500 focus:bg-white focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent"
|
|
|
+ placeholder="请输入密码(至少6位)"
|
|
|
+ password={!showPassword}
|
|
|
+ value={password}
|
|
|
+ onInput={(e) => setPassword(e.detail.value)}
|
|
|
+ maxlength={20}
|
|
|
+ />
|
|
|
+ <View
|
|
|
+ className="absolute right-3 top-1/2 -translate-y-1/2"
|
|
|
+ onClick={() => setShowPassword(!showPassword)}
|
|
|
+ >
|
|
|
+ <View className={cn(
|
|
|
+ "w-5 h-5 text-gray-400",
|
|
|
+ showPassword ? "i-heroicons-eye-20-solid" : "i-heroicons-eye-slash-20-solid"
|
|
|
+ )} />
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ {/* 确认密码输入框 */}
|
|
|
+ <View className="space-y-2">
|
|
|
+ <Text className="text-sm font-medium text-gray-700">确认密码</Text>
|
|
|
+ <View className="relative">
|
|
|
+ <View className="absolute left-3 top-1/2 -translate-y-1/2">
|
|
|
+ <View className="i-heroicons-lock-closed-20-solid w-5 h-5 text-gray-400" />
|
|
|
+ </View>
|
|
|
+ <Input
|
|
|
+ className="w-full h-12 pl-10 pr-12 bg-gray-50 rounded-lg text-gray-900 placeholder-gray-500 focus:bg-white focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent"
|
|
|
+ placeholder="请再次输入密码"
|
|
|
+ password={!showConfirmPassword}
|
|
|
+ value={confirmPassword}
|
|
|
+ onInput={(e) => setConfirmPassword(e.detail.value)}
|
|
|
+ maxlength={20}
|
|
|
+ />
|
|
|
+ <View
|
|
|
+ className="absolute right-3 top-1/2 -translate-y-1/2"
|
|
|
+ onClick={() => setShowConfirmPassword(!showConfirmPassword)}
|
|
|
+ >
|
|
|
+ <View className={cn(
|
|
|
+ "w-5 h-5 text-gray-400",
|
|
|
+ showConfirmPassword ? "i-heroicons-eye-20-solid" : "i-heroicons-eye-slash-20-solid"
|
|
|
+ )} />
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ {/* 注册按钮 */}
|
|
|
+ <Button
|
|
|
+ className={cn(
|
|
|
+ "w-full h-12 rounded-lg font-medium text-white transition-all duration-200",
|
|
|
+ isLoading || !username || !password || !confirmPassword
|
|
|
+ ? "bg-gray-300 cursor-not-allowed"
|
|
|
+ : "bg-green-500 hover:bg-green-600 active:bg-green-700 shadow-lg"
|
|
|
+ )}
|
|
|
+ loading={isLoading}
|
|
|
+ onClick={handleRegister}
|
|
|
+ disabled={isLoading || !username || !password || !confirmPassword}
|
|
|
+ >
|
|
|
+ {isLoading ? (
|
|
|
+ <View className="flex items-center justify-center">
|
|
|
+ <View className="i-heroicons-arrow-path-20-solid animate-spin w-5 h-5 mr-2" />
|
|
|
+ 注册中...
|
|
|
+ </View>
|
|
|
+ ) : (
|
|
|
+ '立即注册'
|
|
|
+ )}
|
|
|
+ </Button>
|
|
|
</View>
|
|
|
- </View>
|
|
|
-
|
|
|
- <View className="form-item">
|
|
|
- <Text className="form-label">确认密码</Text>
|
|
|
- <View className="input-wrapper">
|
|
|
- <Input
|
|
|
- className="form-input"
|
|
|
- placeholder="请再次输入密码"
|
|
|
- password
|
|
|
- value={confirmPassword}
|
|
|
- onInput={(e) => setConfirmPassword(e.detail.value)}
|
|
|
- maxlength={20}
|
|
|
- />
|
|
|
+
|
|
|
+ {/* 登录链接 */}
|
|
|
+ <View className="mt-6 text-center">
|
|
|
+ <Text className="text-sm text-gray-600">
|
|
|
+ 已有账号?
|
|
|
+ <Text
|
|
|
+ className="text-green-500 font-medium hover:text-green-600"
|
|
|
+ onClick={goToLogin}
|
|
|
+ >
|
|
|
+ 立即登录
|
|
|
+ </Text>
|
|
|
+ </Text>
|
|
|
</View>
|
|
|
</View>
|
|
|
-
|
|
|
- <Button
|
|
|
- className={`register-button ${isLoading ? 'loading' : ''}`}
|
|
|
- loading={isLoading}
|
|
|
- onClick={handleRegister}
|
|
|
- disabled={isLoading || !username || !password || !confirmPassword}
|
|
|
- >
|
|
|
- {isLoading ? '注册中...' : '立即注册'}
|
|
|
- </Button>
|
|
|
-
|
|
|
- <View className="register-footer">
|
|
|
- <Text className="footer-text">
|
|
|
- 已有账号?
|
|
|
- <Text className="link-text" onClick={goToLogin}>
|
|
|
- 立即登录
|
|
|
- </Text>
|
|
|
+
|
|
|
+ {/* 协议声明 */}
|
|
|
+ <View className="mt-8 text-center">
|
|
|
+ <Text className="text-xs text-gray-500">
|
|
|
+ 注册即表示您同意
|
|
|
+ <Text className="text-green-500 mx-1">用户协议</Text>
|
|
|
+ 和
|
|
|
+ <Text className="text-green-500 mx-1">隐私政策</Text>
|
|
|
</Text>
|
|
|
</View>
|
|
|
</View>
|
|
|
-
|
|
|
- <View className="register-footer-info">
|
|
|
- <Text className="footer-tip">注册即表示您同意我们的</Text>
|
|
|
- <View className="footer-links">
|
|
|
- <Text className="link-text">用户协议</Text>
|
|
|
- <Text className="link-separator">和</Text>
|
|
|
- <Text className="link-text">隐私政策</Text>
|
|
|
- </View>
|
|
|
- </View>
|
|
|
</View>
|
|
|
)
|
|
|
-}
|
|
|
-
|
|
|
+}
|