All files / app/register/hooks useRegisterForm.ts

67.44% Statements 29/43
58.33% Branches 7/12
66.66% Functions 6/9
65% Lines 26/40

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128                          20x 20x 20x 20x 20x           20x   20x   2x   2x   2x             2x     2x   2x                             2x                                                                         20x 3x 3x     20x 3x 3x     20x 3x 3x     20x 1x     20x                          
import { useState } from 'react';
import { useRouter } from 'expo-router';
import { ZodError } from 'zod';
 
import { useUserStore } from '@/src/store/userStore';
import { registerSchema } from '@/src/schemas/auth.schema';
import { showAlert, toast } from '@/src/components/dialogs';
 
/**
 * 注册表单 Hook
 * 负责注册表单的状态管理和验证
 */
export function useRegisterForm() {
  const router = useRouter();
  const [email, setEmail] = useState('');
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [errors, setErrors] = useState<{
    email?: string;
    username?: string;
    password?: string;
  }>({});
 
  const { register, isLoading } = useUserStore();
 
  const handleRegister = async () => {
    // 清除之前的错误
    setErrors({});
 
    try {
      // 使用 Zod 验证表单数据
      registerSchema.parse({
        email,
        username,
        password,
      });
 
      // 验证通过,执行注册
      await register(email, username, password);
 
      // 检查是否已经自动登录(有 session)
      const { isAuthenticated } = useUserStore.getState();
 
      Iif (isAuthenticated) {
        // 自动登录成功
        showAlert({
          title: '注册成功',
          message: '欢迎加入 Pet Love!',
          type: 'success',
          buttons: [
            {
              text: '确定',
              onPress: () => router.replace('/(tabs)/collect'),
            },
          ],
        });
      } else {
        // 需要邮箱验证
        showAlert({
          title: '注册成功',
          message: '请查收验证邮件并完成邮箱验证后登录。',
          type: 'success',
          buttons: [
            {
              text: '确定',
              onPress: () => router.back(), // 返回登录页
            },
          ],
        });
      }
    } catch (error) {
      if (error instanceof ZodError) {
        // 处理验证错误
        const fieldErrors: {
          email?: string;
          username?: string;
          password?: string;
        } = {};
        error.errors.forEach((err) => {
          const field = err.path[0] as 'email' | 'username' | 'password';
          fieldErrors[field] = err.message;
        });
        setErrors(fieldErrors);
 
        // 显示第一个错误
        const firstError = error.errors[0];
        toast.error('验证失败', firstError.message);
      } else if (error instanceof Error) {
        // 处理 API 错误
        toast.error('注册失败', error.message);
        console.error('注册错误:', error);
      }
    }
  };
 
  const handleEmailChange = (text: string) => {
    setEmail(text);
    if (errors.email) setErrors({ ...errors, email: undefined });
  };
 
  const handleUsernameChange = (text: string) => {
    setUsername(text);
    if (errors.username) setErrors({ ...errors, username: undefined });
  };
 
  const handlePasswordChange = (text: string) => {
    setPassword(text);
    if (errors.password) setErrors({ ...errors, password: undefined });
  };
 
  const navigateBack = () => {
    router.back();
  };
 
  return {
    email,
    username,
    password,
    errors,
    isLoading,
    handleEmailChange,
    handleUsernameChange,
    handlePasswordChange,
    handleRegister,
    navigateBack,
  };
}