| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- import { View, Text } from '@tarojs/components'
- import { useState, useEffect } from 'react'
- import Taro from '@tarojs/taro'
- import { useAuth } from '@/utils/auth'
- import { cn } from '@/utils/cn'
- import { Button } from '@/components/ui/button'
- import { Input } from '@/components/ui/input'
- import Navbar from '@/components/ui/navbar'
- import './index.css'
- export default function Register() {
- const [username, setUsername] = useState('')
- const [email, setEmail] = useState('')
- const [password, setPassword] = useState('')
- const [confirmPassword, setConfirmPassword] = useState('')
- const [showPassword, setShowPassword] = useState(false)
- const [showConfirmPassword, setShowConfirmPassword] = useState(false)
- const { register, isLoading } = useAuth()
- useEffect(() => {
- Taro.setNavigationBarTitle({
- title: '创建账号'
- })
- }, [])
- const handleRegister = async () => {
- // 输入验证
- if (!username.trim()) {
- Taro.showToast({
- title: '请输入用户名',
- icon: 'none',
- duration: 2000
- })
- return
- }
- if (username.trim().length < 3) {
- Taro.showToast({
- title: '用户名至少3个字符',
- icon: 'none',
- duration: 2000
- })
- return
- }
- if (!password.trim()) {
- Taro.showToast({
- title: '请输入密码',
- icon: 'none',
- duration: 2000
- })
- return
- }
- if (password.trim().length < 6) {
- Taro.showToast({
- title: '密码至少6个字符',
- icon: 'none',
- duration: 2000
- })
- return
- }
- if (password.trim() !== confirmPassword.trim()) {
- Taro.showToast({
- title: '两次输入的密码不一致',
- icon: 'none',
- duration: 2000
- })
- return
- }
- if (email.trim() && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim())) {
- Taro.showToast({
- title: '请输入有效的邮箱地址',
- icon: 'none',
- duration: 2000
- })
- return
- }
- try {
- Taro.showLoading({
- title: '注册中...',
- mask: true
- })
- await register({
- username: username.trim(),
- password: password.trim(),
- email: email.trim() || undefined
- })
-
- Taro.hideLoading()
-
- Taro.showToast({
- title: '注册成功',
- icon: 'success',
- duration: 1500
- })
-
- setTimeout(() => {
- Taro.switchTab({ url: '/pages/index/index' })
- }, 1500)
- } catch (error: any) {
- Taro.hideLoading()
-
- const errorMessage = error.message || '注册失败,请重试'
- Taro.showToast({
- title: errorMessage,
- icon: 'none',
- duration: 3000
- })
- }
- }
- const goToLogin = () => {
- Taro.navigateBack()
- }
- return (
- <View className="min-h-screen bg-gradient-to-br from-green-50 via-white to-emerald-50">
- <Navbar
- title="创建账号"
- backgroundColor="bg-transparent"
- textColor="text-gray-900"
- border={false}
- />
- <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="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>
- <Input
- leftIcon="i-heroicons-user-20-solid"
- placeholder="请输入用户名(3-20个字符)"
- value={username}
- onInput={(e) => setUsername(e.detail.value)}
- maxlength={20}
- size="lg"
- variant="filled"
- />
- </View>
- {/* 邮箱输入框 */}
- <View className="space-y-2">
- <Text className="text-sm font-medium text-gray-700">邮箱(可选)</Text>
- <Input
- leftIcon="i-heroicons-envelope-20-solid"
- placeholder="请输入邮箱地址"
- type="text"
- value={email}
- onInput={(e) => setEmail(e.detail.value)}
- maxlength={50}
- size="lg"
- variant="filled"
- />
- </View>
- {/* 密码输入框 */}
- <View className="space-y-2">
- <Text className="text-sm font-medium text-gray-700">密码</Text>
- <Input
- leftIcon="i-heroicons-lock-closed-20-solid"
- rightIcon={showPassword ? "i-heroicons-eye-20-solid" : "i-heroicons-eye-slash-20-solid"}
- placeholder="请输入密码(至少6位)"
- password={!showPassword}
- value={password}
- onInput={(e) => setPassword(e.detail.value)}
- maxlength={20}
- size="lg"
- variant="filled"
- onRightIconClick={() => setShowPassword(!showPassword)}
- />
- </View>
- {/* 确认密码输入框 */}
- <View className="space-y-2">
- <Text className="text-sm font-medium text-gray-700">确认密码</Text>
- <Input
- leftIcon="i-heroicons-lock-closed-20-solid"
- rightIcon={showConfirmPassword ? "i-heroicons-eye-20-solid" : "i-heroicons-eye-slash-20-solid"}
- placeholder="请再次输入密码"
- password={!showConfirmPassword}
- value={confirmPassword}
- onInput={(e) => setConfirmPassword(e.detail.value)}
- maxlength={20}
- size="lg"
- variant="filled"
- onRightIconClick={() => setShowConfirmPassword(!showConfirmPassword)}
- />
- </View>
- {/* 注册按钮 */}
- <Button
- className={cn(
- "w-full",
- isLoading || !username || !password || !confirmPassword
- ? "bg-gray-300"
- : "bg-green-500 hover:bg-green-600"
- )}
- size="lg"
- variant="default"
- 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 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>
- {/* 协议声明 */}
- <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>
- )
- }
|