import { Ionicons } from '@expo/vector-icons' import { Block, Text, Toast } from '@share/components' import { router } from 'expo-router' import React, { useCallback, useMemo, useState } from 'react' import { TextInput } from 'react-native' import { KeyboardAwareScrollView } from 'react-native-keyboard-controller' import { APP_VERSION } from '@/app.constants' import BannerSection from '@/components/BannerSection' import { emailOtp as emailOtpService, setAuthToken, signIn, signUp } from '@/lib/auth' import { isValidEmail } from '@/utils' type AuthMode = 'login' | 'register' | 'registerEmail' const APP_NAME = '多米' // 判断是否为邮箱格式的辅助函数 const isEmail = (input: string) => { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input) } export default function Auth() { const [mode, setMode] = useState('login') const [username, setUsername] = useState('') const [email, setEmail] = useState('') const [emailOtp, setEmailOtp] = useState('') const [password, setPassword] = useState('') const [confirmPassword, setConfirmPassword] = useState('') const [showPassword, setShowPassword] = useState(false) const [showConfirmPassword, setShowConfirmPassword] = useState(false) const [loading, setLoading] = useState(false) const canSend = useMemo(() => { return isValidEmail(email) }, [email]) const handleEmiallOtp = () => { if (!canSend) { Toast.show({ title: '请输入有效的邮箱地址' }) return } Toast.showLoading({ title: '正在发送验证码...' }) setLoading(true) emailOtpService .sendVerificationOtp({ email, type: 'email-verification' }) .then((res) => { if (res.error) { Toast.show({ title: res.error.message || '验证码发送失败' }) } else { Toast.show({ title: '验证码已发送,请查收邮箱' }) } }) .finally(() => { Toast.hideLoading() setLoading(false) }) } const handleEmailVerify = async () => { if (!canSend) { Toast.show({ title: '请输入有效的邮箱地址' }) return } if (!emailOtp) { Toast.show({ title: '请输入邮箱验证码' }) return } try { Toast.showLoading({ title: '正在验证' }) const emailVerifyRes = await emailOtpService.verifyEmail({ email, otp: emailOtp }) Toast.hideLoading() console.log('emailVerifyRes------------', emailVerifyRes) if (emailVerifyRes?.error) { Toast.show({ title: '邮箱验证码验证失败' }) return } setMode('register') } catch (error) {} } const handleLogin = useCallback(async () => { if (!username || !password) { Toast.show({ title: '请填写账号和密码' }) return } setLoading(true) try { let result if (isEmail(username)) { // 如果用户名是邮箱格式,使用邮箱登录 result = await signIn.email( { email: username, password, }, { onSuccess: async (ctx) => { const authToken = ctx.response.headers.get('set-auth-token') if (authToken) { setAuthToken(authToken) } }, onError: (ctx) => { console.error(`[LOGIN] email login error`, ctx) }, }, ) } else { // 如果用户名不是邮箱格式,使用用户名登录 result = await signIn.username( { username, password, }, { onSuccess: async (ctx) => { const authToken = ctx.response.headers.get('set-auth-token') if (authToken) { setAuthToken(authToken) } }, onError: (ctx) => { console.error(`[LOGIN] username login error`, ctx) }, }, ) } if (result.error) { Toast.show({ title: '请输入正确的账号或密码' }) } else { Toast.show({ title: '登录成功!' }) router.replace('/(tabs)') } } catch (error: any) { Toast.show({ title: error.message || '登录失败' }) } finally { setLoading(false) } }, [username, password, signIn]) const handleRegister = async () => { if (!email || !username || !password || !emailOtp) { Toast.show({ title: '请填写所有必填项' }) return } if (password !== confirmPassword) { Toast.show({ title: '两次密码输入不一致' }) return } if (password.length < 6) { Toast.show({ title: '密码长度至少6位' }) return } setLoading(true) try { const result = await signUp.email({ email, username, password, name: username, }) // console.log('result------------', result) const messageMap = { USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL: '该邮箱已被注册,请使用其他邮箱', USERNAME_ALREADY_EXISTS_USE_ANOTHER_USERNAME: '该用户名已被注册,请使用其他用户名', } const friendlyMessage = messageMap[result?.error?.code] if (result.error) { Toast.show({ title: friendlyMessage || result?.error?.message || '注册失败' }) } else { Toast.show({ title: '注册成功!' }) } } catch (error: any) { Toast.show({ title: error.message || '注册失败' }) } finally { setLoading(false) } } const renderLogin = () => { if (mode !== 'login') { return null } return ( 账号 密码 setShowPassword(!showPassword)} className="p-1"> router.push('/forgotPassword')}> 忘记密码 {loading ? ( ) : ( )} {loading ? '处理中...' : '登录'} ) } const renderEmailSend = () => { if (mode !== 'registerEmail') { return null } return ( 邮箱 发送验证码 邮箱验证码 {loading ? ( ) : ( )} 下一步 ) } const renderRegister = () => { if (mode !== 'register') { return null } return ( 账号 密码 setShowPassword(!showPassword)} className="p-1"> 确认密码 setShowConfirmPassword(!showConfirmPassword)} className="p-1"> {loading ? ( ) : ( )} {loading ? '处理中...' : '注册'} ) } return ( {APP_NAME} {(['login', 'register'] as const).map((tabMode) => { const isActive = tabMode === mode || (mode === 'registerEmail' && tabMode === 'register') return ( { if (tabMode === 'register') { setMode('registerEmail') } else { setMode('login') } }} > {tabMode === 'login' ? '登录' : '注册'} ) })} {renderLogin()} {renderRegister()} {renderEmailSend()} © 2025 LOOMART. All rights reserved. 插件当前版本号: {APP_VERSION} ) }