diff --git a/app/(tabs)/login.tsx b/app/(tabs)/login.tsx index fd3121a..786a111 100644 --- a/app/(tabs)/login.tsx +++ b/app/(tabs)/login.tsx @@ -81,7 +81,7 @@ const LoginScreen = () => { }} > { - showPassword + (showPassword || showSecondPassword) ? : diff --git a/components/login/forgetPwd.tsx b/components/login/forgetPwd.tsx index 0f38b15..4bebfbb 100644 --- a/components/login/forgetPwd.tsx +++ b/components/login/forgetPwd.tsx @@ -2,7 +2,7 @@ import { fetchApi } from "@/lib/server-api-util"; import { User } from "@/types/user"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; -import { ActivityIndicator, TextInput, TouchableOpacity, View } from "react-native"; +import { ActivityIndicator, StyleSheet, TextInput, TouchableOpacity, View } from "react-native"; import { ThemedText } from "../ThemedText"; interface LoginProps { @@ -15,12 +15,10 @@ interface LoginProps { const ForgetPwd = ({ setIsSignUp, updateUrlParam, setError }: LoginProps) => { const { t } = useTranslation(); const [loading, setLocading] = useState(false); - // 发送邮箱后把按钮变为disabled const [isDisabled, setIsDisabled] = useState(false); const [email, setEmail] = useState(''); const [countdown, setCountdown] = useState(0); - // 倒计时效果 useEffect(() => { if (countdown > 0) { const timer = setTimeout(() => setCountdown(countdown - 1), 1000); @@ -30,7 +28,6 @@ const ForgetPwd = ({ setIsSignUp, updateUrlParam, setError }: LoginProps) => { } }, [countdown, isDisabled]); - // 发送邮件 const handleSubmit = () => { if (!email) { setError(t('auth.forgetPwd.emailPlaceholder', { ns: 'login' })); @@ -41,7 +38,7 @@ const ForgetPwd = ({ setIsSignUp, updateUrlParam, setError }: LoginProps) => { const body = { email: email, } - // 调接口确定邮箱是否正确,是否有该用户邮箱权限 + fetchApi('/iam/reset-password-session', { method: 'POST', body: JSON.stringify(body), @@ -50,19 +47,17 @@ const ForgetPwd = ({ setIsSignUp, updateUrlParam, setError }: LoginProps) => { } }) .then((_) => { - // console.log("Password reset email sent successfully"); setIsDisabled(true); - setCountdown(60); // 开始60秒倒计时 + setCountdown(60); }) .catch((error) => { - // console.error('Failed to send reset email:', error); setError(t('auth.forgetPwd.sendEmailError', { ns: 'login' })); }) .finally(() => { setLocading(false); }); }; - // 返回登陆 + const handleBackToLogin = () => { if (setIsSignUp) { setIsSignUp('login'); @@ -72,50 +67,95 @@ const ForgetPwd = ({ setIsSignUp, updateUrlParam, setError }: LoginProps) => { } } - return - {/* 邮箱输入框 */} - - - {t('auth.forgetPwd.title', { ns: 'login' })} - - - - {/* 发送重置密码邮件 */} - - {loading ? ( - - ) : ( - - {isDisabled - ? `${t("auth.forgetPwd.sendEmailBtnDisabled", { ns: "login" })} (${countdown}s)` - : t("auth.forgetPwd.sendEmailBtn", { ns: "login" })} - + return ( + + + + {t('auth.forgetPwd.title', { ns: 'login' })} - )} - - {/* 返回登陆 */} - - - {t('auth.forgetPwd.goback', { ns: 'login' })} - - - + + + + + {loading ? ( + + ) : ( + + {isDisabled + ? `${t("auth.forgetPwd.sendEmailBtnDisabled", { ns: "login" })} (${countdown}s)` + : t("auth.forgetPwd.sendEmailBtn", { ns: "login" })} + + )} + + + + + {t('auth.forgetPwd.goback', { ns: 'login' })} + + + + ); } +const styles = StyleSheet.create({ + container: { + width: '100%', + }, + inputContainer: { + marginBottom: 20, + }, + inputLabel: { + fontSize: 16, + color: '#1F2937', + marginBottom: 8, + marginLeft: 8, + }, + textInput: { + borderRadius: 12, + padding: 12, + fontSize: 16, + backgroundColor: '#FFF8DE', + }, + submitButton: { + width: '100%', + backgroundColor: '#E2793F', + borderRadius: 28, + padding: 16, + alignItems: 'center', + }, + disabledButton: { + opacity: 0.5, + }, + buttonText: { + color: '#FFFFFF', + fontWeight: '600', + }, + backButton: { + alignSelf: 'center', + marginTop: 24, + }, + backButtonText: { + color: '#1F2937', + fontSize: 14, + }, +}); -export default ForgetPwd \ No newline at end of file +export default ForgetPwd; \ No newline at end of file diff --git a/components/login/signUp.tsx b/components/login/signUp.tsx index ec2a608..8d2790d 100644 --- a/components/login/signUp.tsx +++ b/components/login/signUp.tsx @@ -2,7 +2,7 @@ import { Ionicons } from "@expo/vector-icons"; import { useLocalSearchParams, useRouter } from "expo-router"; import { useEffect, useState } from 'react'; import { useTranslation } from "react-i18next"; -import { ActivityIndicator, TextInput, TouchableOpacity, View } from 'react-native'; +import { ActivityIndicator, StyleSheet, TextInput, TouchableOpacity, View } from 'react-native'; import { useAuth } from "../../contexts/auth-context"; import { fetchApi } from "../../lib/server-api-util"; import { User } from "../../types/user"; @@ -143,206 +143,299 @@ const SignUp = ({ updateUrlParam, setError, setShowPassword, showPassword, setSh setShowSecondPassword(false) }, []) - return - {/* 邮箱输入 */} - - - {t('auth.login.email', { ns: 'login' })} - - - { - setEmail(value) - setError('123') - }} - keyboardType="email-address" - autoCapitalize="none" - /> - - - - {/* 密码输入 */} - - - {t('auth.login.password', { ns: 'login' })} - - - { - handlePasswordChange(value) - setError('123') - }} - secureTextEntry={!showPassword} - /> - setShowPassword(!showPassword)} - className="px-3 py-2" - > - - - - - - {/* 确认密码 */} - - - {t('auth.signup.confirmPassword', { ns: 'login' })} - - - { - handleConfirmPasswordChange(value) - setError('123') - }} - secureTextEntry={!showSecondPassword} - /> - setShowSecondPassword(!showSecondPassword)} - className="px-3 py-2" - > - - - - - - {/* 注册按钮 */} - - {loading ? ( - - ) : ( - - {t("auth.signup.signupButton", { ns: 'login' })} + return ( + + {/* 邮箱输入 */} + + + {t('auth.login.email', { ns: 'login' })} - )} - - - { - const newValue = !checked; - setChecked(newValue); - if (!newValue) { - setError(t('auth.signup.checkedRequired', { ns: 'login' })); - return - } else { - setError("123") - } + + { + setEmail(value) + setError('123') + }} + keyboardType="email-address" + autoCapitalize="none" + /> + + - }} - style={{ - width: 20, - height: 20, - borderRadius: 10, - borderWidth: 2, - borderColor: checked ? '#E2793F' : '#ccc', - backgroundColor: checked ? '#E2793F' : 'transparent', - justifyContent: 'center', - alignItems: 'center', - marginRight: 8, - }} + {/* 密码输入 */} + + + {t('auth.login.password', { ns: 'login' })} + + + { + handlePasswordChange(value) + setError('123') + }} + secureTextEntry={!showPassword} + /> + setShowPassword(!showPassword)} + style={styles.eyeIcon} + > + + + + + + {/* 确认密码 */} + + + {t('auth.signup.confirmPassword', { ns: 'login' })} + + + { + handleConfirmPasswordChange(value) + setError('123') + }} + secureTextEntry={!showSecondPassword} + /> + setShowSecondPassword(!showSecondPassword)} + style={styles.eyeIcon} + > + + + + + + {/* 注册按钮 */} + - {checked && ( - + {loading ? ( + + ) : ( + + {t("auth.signup.signupButton", { ns: 'login' })} + )} - - - {t("auth.telLogin.agree", { ns: 'login' })} - - { - setModalType('terms'); - setPrivacyModalVisible(true); - }}> - - {t("auth.telLogin.terms", { ns: 'login' })} - + + { + const newValue = !checked; + setChecked(newValue); + if (!newValue) { + setError(t('auth.signup.checkedRequired', { ns: 'login' })); + return + } else { + setError("123") + } + + }} + style={[ + styles.checkbox, + checked && styles.checkboxChecked + ]} + > + {checked && ( + + )} - - {t("auth.telLogin.and", { ns: 'login' })} - - { - setModalType('privacy'); - setPrivacyModalVisible(true); - }}> - - {t("auth.telLogin.privacyPolicy", { ns: 'login' })} + + + {t("auth.telLogin.agree", { ns: 'login' })} - - - {t("auth.telLogin.and", { ns: 'login' })} - - { - setModalType('user'); - setPrivacyModalVisible(true); - }}> - - {t("auth.telLogin.userAgreement", { ns: 'login' })} + { + setModalType('terms'); + setPrivacyModalVisible(true); + }}> + + {t("auth.telLogin.terms", { ns: 'login' })} + + + + {t("auth.telLogin.and", { ns: 'login' })} - - - {t("auth.telLogin.and", { ns: 'login' })} - - { - setModalType('ai'); - setPrivacyModalVisible(true); - }}> - - {t("auth.telLogin.aiAgreement", { ns: 'login' })} + { + setModalType('privacy'); + setPrivacyModalVisible(true); + }}> + + {t("auth.telLogin.privacyPolicy", { ns: 'login' })} + + + + {t("auth.telLogin.and", { ns: 'login' })} - - - {t("auth.telLogin.agreement", { ns: 'login' })} - - - {t("common.name")} - - - {t("auth.telLogin.getPhone", { ns: 'login' })} - + { + setModalType('user'); + setPrivacyModalVisible(true); + }}> + + {t("auth.telLogin.userAgreement", { ns: 'login' })} + + + + {t("auth.telLogin.and", { ns: 'login' })} + + { + setModalType('ai'); + setPrivacyModalVisible(true); + }}> + + {t("auth.telLogin.aiAgreement", { ns: 'login' })} + + + + {t("auth.telLogin.agreement", { ns: 'login' })} + + + {t("common.name")} + + + {t("auth.telLogin.getPhone", { ns: 'login' })} + + - - {/* 已有账号 */} - - - {t("auth.signup.haveAccount", { ns: 'login' })} - - { - updateUrlParam("status", "login"); - }} - > - - {t("auth.signup.login", { ns: 'login' })} + {/* 已有账号 */} + + + {t("auth.signup.haveAccount", { ns: 'login' })} - + { + updateUrlParam("status", "login"); + }} + > + + {t("auth.signup.login", { ns: 'login' })} + + + + + {/* 协议弹窗 */} + + ); +}; - {/* 协议弹窗 */} - - -} +const styles = StyleSheet.create({ + container: { + width: '100%', + }, + inputContainer: { + marginBottom: 16, + }, + inputWrapper: { + borderRadius: 12, + backgroundColor: '#FFF8DE', + overflow: 'hidden', + }, + inputLabel: { + fontSize: 16, + color: '#1F2937', + marginBottom: 8, + marginLeft: 8, + }, + textInput: { + padding: 12, + fontSize: 16, + color: '#1F2937', + }, + passwordInputContainer: { + flexDirection: 'row', + alignItems: 'center', + borderRadius: 12, + backgroundColor: '#FFF8DE', + overflow: 'hidden', + }, + eyeIcon: { + paddingHorizontal: 12, + paddingVertical: 8, + }, + signupButton: { + width: '100%', + backgroundColor: '#E2793F', + borderRadius: 28, + padding: 16, + alignItems: 'center', + marginBottom: 16, + }, + signupButtonText: { + color: '#FFFFFF', + fontWeight: '600', + }, + termsContainer: { + flexDirection: 'row', + alignItems: 'flex-start', + marginVertical: 10, + }, + checkbox: { + width: 20, + height: 20, + borderRadius: 10, + borderWidth: 2, + borderColor: '#E5E7EB', + justifyContent: 'center', + alignItems: 'center', + marginRight: 8, + marginTop: 2, + }, + checkboxChecked: { + backgroundColor: '#E2793F', + borderColor: '#E2793F', + }, + termsTextContainer: { + flexDirection: 'row', + flexWrap: 'wrap', + flex: 1, + }, + termsText: { + fontSize: 14, + color: '#1F2937', + lineHeight: 20, + }, + termsLink: { + fontSize: 14, + color: '#E2793F', + lineHeight: 20, + }, + loginContainer: { + flexDirection: 'row', + justifyContent: 'center', + marginTop: 24, + }, + loginText: { + fontSize: 14, + color: '#1F2937', + }, + loginLink: { + color: '#E2793F', + fontSize: 14, + fontWeight: '600', + marginLeft: 4, + }, +}); -export default SignUp \ No newline at end of file +export default SignUp; \ No newline at end of file