import { Ionicons } from '@expo/vector-icons' import { Block, Text, Toast } from '@share/components' import { router } from 'expo-router' import React, { useCallback, 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 { setAuthToken, signIn, signUp } from '@/lib/auth' type AuthMode = 'login' | 'register' 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 [password, setPassword] = useState('') const [confirmPassword, setConfirmPassword] = useState('') const [showPassword, setShowPassword] = useState(false) const [showConfirmPassword, setShowConfirmPassword] = useState(false) const [loading, setLoading] = useState(false) 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 = useCallback(async () => { if (!email || !username || !password) { 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) if (result.error) { Toast.show({ title: result.error.message || '注册失败' }) } else { Toast.show({ title: '注册成功!' }) } } catch (error: any) { Toast.show({ title: error.message || '注册失败' }) } finally { setLoading(false) } }, [email, username, password, confirmPassword, signUp]) const handleSubmit = useCallback(() => { if (mode === 'login') { handleLogin() } else { handleRegister() } }, [mode, handleLogin, handleRegister]) return ( {APP_NAME} {(['login', 'register'] as const).map((tabMode) => { const isActive = mode === tabMode return ( setMode(tabMode)} > {tabMode === 'login' ? '登录' : '注册'} ) })} {mode === 'login' ? ( 账号 ) : ( <> 邮箱 用户名 )} 密码 setShowPassword(!showPassword)} className="p-1"> {mode === 'login' && ( router.push('/forgot-password')} > 忘记密码 )} {mode === 'register' && ( 确认密码 setShowConfirmPassword(!showConfirmPassword)} className="p-1"> )} {loading ? ( ) : ( )} {loading ? '处理中...' : mode === 'login' ? '登录' : '注册'} © 2025 LOOMART. All rights reserved. 插件当前版本号: {APP_VERSION} ) }