|
|
|
|
import React, { useEffect, useState, useRef } from "react";
|
|
|
|
|
import {
|
|
|
|
|
View,
|
|
|
|
|
Text,
|
|
|
|
|
StyleSheet,
|
|
|
|
|
TouchableOpacity,
|
|
|
|
|
StatusBar,
|
|
|
|
|
Platform,
|
|
|
|
|
BackHandler,
|
|
|
|
|
Image,
|
|
|
|
|
Modal,
|
|
|
|
|
SafeAreaView,
|
|
|
|
|
} from "react-native";
|
|
|
|
|
import { useTranslation } from "react-i18next";
|
|
|
|
|
import { useNavigation } from "@react-navigation/native";
|
|
|
|
|
import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
|
|
|
|
|
import fontSize from "../../utils/fontsizeUtils";
|
|
|
|
|
|
|
|
|
|
import EmailLoginModal from "./EmailLoginModal";
|
|
|
|
|
import PhoneLoginModal from "./PhoneLoginModal";
|
|
|
|
|
import * as WebBrowser from "expo-web-browser";
|
|
|
|
|
import * as AuthSession from "expo-auth-session";
|
|
|
|
|
import * as Linking from "expo-linking";
|
|
|
|
|
import * as Google from "expo-auth-session/providers/google";
|
|
|
|
|
|
|
|
|
|
WebBrowser.maybeCompleteAuthSession();
|
|
|
|
|
|
|
|
|
|
type RootStackParamList = {
|
|
|
|
|
Login: undefined;
|
|
|
|
|
EmailLogin: undefined;
|
|
|
|
|
MainTabs: { screen: string };
|
|
|
|
|
Google: undefined;
|
|
|
|
|
Home: { screen: string };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type LoginScreenProps = {
|
|
|
|
|
onClose?: () => void;
|
|
|
|
|
isModal?: boolean;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const CLIENT_ID =
|
|
|
|
|
"529750832779-osemooqkar78m8lhrn9dvbvi98fr4g08.apps.googleusercontent.com"; // from Google Cloud
|
|
|
|
|
const REDIRECT_URI = AuthSession.makeRedirectUri({
|
|
|
|
|
native: "brainnelapp://redirect",
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export const LoginScreen = ({ onClose, isModal }: LoginScreenProps) => {
|
|
|
|
|
const { t } = useTranslation();
|
|
|
|
|
const navigation =
|
|
|
|
|
useNavigation<NativeStackNavigationProp<RootStackParamList>>();
|
|
|
|
|
|
|
|
|
|
// 全新的状态管理方式
|
|
|
|
|
const [emailModalVisible, setEmailModalVisible] = useState(false);
|
|
|
|
|
const [phoneModalVisible, setPhoneModalVisible] = useState(false);
|
|
|
|
|
|
|
|
|
|
// 防止多次触发
|
|
|
|
|
const isProcessingEmail = useRef(false);
|
|
|
|
|
const isProcessingPhone = useRef(false);
|
|
|
|
|
|
|
|
|
|
// 处理Android返回按钮
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const backAction = () => {
|
|
|
|
|
if (emailModalVisible) {
|
|
|
|
|
setEmailModalVisible(false);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (phoneModalVisible) {
|
|
|
|
|
setPhoneModalVisible(false);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
handleClose();
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const backHandler = BackHandler.addEventListener(
|
|
|
|
|
"hardwareBackPress",
|
|
|
|
|
backAction
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return () => backHandler.remove();
|
|
|
|
|
}, [emailModalVisible, phoneModalVisible]);
|
|
|
|
|
|
|
|
|
|
// 关闭主屏幕
|
|
|
|
|
const handleClose = () => {
|
|
|
|
|
if (isModal && onClose) {
|
|
|
|
|
onClose();
|
|
|
|
|
} else {
|
|
|
|
|
navigation.goBack();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const discovery = {
|
|
|
|
|
authorizationEndpoint: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
|
|
|
tokenEndpoint: "https://oauth2.googleapis.com/token",
|
|
|
|
|
revocationEndpoint: "https://oauth2.googleapis.com/revoke",
|
|
|
|
|
};
|
|
|
|
|
const [request, response, handleGoogleLogin] = AuthSession.useAuthRequest(
|
|
|
|
|
{
|
|
|
|
|
clientId: CLIENT_ID,
|
|
|
|
|
scopes: ["openid", "profile", "email"],
|
|
|
|
|
redirectUri: REDIRECT_URI,
|
|
|
|
|
responseType: AuthSession.ResponseType.Code,
|
|
|
|
|
},
|
|
|
|
|
discovery
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
React.useEffect(() => {
|
|
|
|
|
if (response?.type === "success") {
|
|
|
|
|
const { code } = response.params;
|
|
|
|
|
console.log("授权码:", code);
|
|
|
|
|
}
|
|
|
|
|
}, [response]);
|
|
|
|
|
// 处理谷歌登录
|
|
|
|
|
// const handleGoogleLogin = async () => {
|
|
|
|
|
// // navigation.navigate("Google");
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
// 处理Facebook登录
|
|
|
|
|
const handleFacebookLogin = () => {
|
|
|
|
|
// 处理Facebook登录
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 处理Apple登录
|
|
|
|
|
const handleAppleLogin = () => {
|
|
|
|
|
// 处理Apple登录
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 处理Instagram登录
|
|
|
|
|
const handleInstagramLogin = () => {
|
|
|
|
|
// 处理Instagram登录
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 显示邮箱登录
|
|
|
|
|
const showEmailModal = () => {
|
|
|
|
|
if (isProcessingEmail.current) return;
|
|
|
|
|
|
|
|
|
|
isProcessingEmail.current = true;
|
|
|
|
|
// 确保手机模态框已关闭
|
|
|
|
|
setPhoneModalVisible(false);
|
|
|
|
|
|
|
|
|
|
// 延迟打开邮箱模态框,避免冲突
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
setEmailModalVisible(true);
|
|
|
|
|
isProcessingEmail.current = false;
|
|
|
|
|
}, 100);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 显示手机登录
|
|
|
|
|
const showPhoneModal = () => {
|
|
|
|
|
if (isProcessingPhone.current) return;
|
|
|
|
|
|
|
|
|
|
isProcessingPhone.current = true;
|
|
|
|
|
// 确保邮箱模态框已关闭
|
|
|
|
|
setEmailModalVisible(false);
|
|
|
|
|
|
|
|
|
|
// 延迟打开手机模态框,避免冲突
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
setPhoneModalVisible(true);
|
|
|
|
|
isProcessingPhone.current = false;
|
|
|
|
|
}, 100);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 关闭邮箱登录
|
|
|
|
|
const hideEmailModal = () => {
|
|
|
|
|
console.log("Hiding email modal");
|
|
|
|
|
setEmailModalVisible(false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 关闭手机登录
|
|
|
|
|
const hidePhoneModal = () => {
|
|
|
|
|
console.log("Hiding phone modal");
|
|
|
|
|
setPhoneModalVisible(false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 处理忘记密码
|
|
|
|
|
const handleForgotPassword = () => {
|
|
|
|
|
// 处理忘记密码
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<SafeAreaView style={styles.safeArea}>
|
|
|
|
|
<StatusBar barStyle="light-content" backgroundColor="#0066FF" />
|
|
|
|
|
<View style={styles.safeAreaContent}>
|
|
|
|
|
{/* 顶部蓝色背景区域 */}
|
|
|
|
|
<View style={styles.blueHeader}>
|
|
|
|
|
<Text style={styles.logo}>brainnel</Text>
|
|
|
|
|
<View style={styles.features}>
|
|
|
|
|
<View style={styles.featureItem}>
|
|
|
|
|
<View style={styles.featureIconContainer}>
|
|
|
|
|
<Text style={styles.featureIcon}>💰</Text>
|
|
|
|
|
</View>
|
|
|
|
|
<Text style={styles.featureText}>{t("wholesalePrice")}</Text>
|
|
|
|
|
</View>
|
|
|
|
|
<View style={styles.featureItem}>
|
|
|
|
|
<View style={styles.featureIconContainer}>
|
|
|
|
|
<Text style={styles.featureIcon}>🚚</Text>
|
|
|
|
|
</View>
|
|
|
|
|
<Text style={styles.featureText}>{t("fastShipping")}</Text>
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
|
|
|
|
|
{/* 登录区域 */}
|
|
|
|
|
<View style={styles.loginContainer}>
|
|
|
|
|
<TouchableOpacity style={styles.closeButton} onPress={handleClose}>
|
|
|
|
|
<Text style={styles.closeButtonText}>×</Text>
|
|
|
|
|
</TouchableOpacity>
|
|
|
|
|
|
|
|
|
|
<View style={styles.titleContainer}>
|
|
|
|
|
<Text style={styles.subtitle}>{t("loginSubtitle")}</Text>
|
|
|
|
|
</View>
|
|
|
|
|
|
|
|
|
|
{/* 登录按钮 */}
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
style={styles.loginButton}
|
|
|
|
|
onPress={() => handleGoogleLogin()}
|
|
|
|
|
>
|
|
|
|
|
<View style={styles.loginButtonIcon}>
|
|
|
|
|
<Image
|
|
|
|
|
source={require("../../../assets/img/google.png")}
|
|
|
|
|
style={{ width: 20, height: 20 }}
|
|
|
|
|
/>
|
|
|
|
|
</View>
|
|
|
|
|
<Text style={styles.loginButtonText}>
|
|
|
|
|
{t("continueWithGoogle")}
|
|
|
|
|
</Text>
|
|
|
|
|
</TouchableOpacity>
|
|
|
|
|
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
style={styles.loginButton}
|
|
|
|
|
onPress={handleFacebookLogin}
|
|
|
|
|
>
|
|
|
|
|
<View style={[styles.loginButtonIcon, styles.facebookIcon]}>
|
|
|
|
|
<Text style={{ color: "#fff" }}>f</Text>
|
|
|
|
|
</View>
|
|
|
|
|
<Text style={styles.loginButtonText}>
|
|
|
|
|
{t("continueWithFacebook")}
|
|
|
|
|
</Text>
|
|
|
|
|
</TouchableOpacity>
|
|
|
|
|
|
|
|
|
|
{Platform.OS === "ios" && (
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
style={styles.loginButton}
|
|
|
|
|
onPress={handleAppleLogin}
|
|
|
|
|
>
|
|
|
|
|
<View style={[styles.loginButtonIcon, styles.appleIconBg]}>
|
|
|
|
|
<Text>🍎</Text>
|
|
|
|
|
</View>
|
|
|
|
|
<Text style={styles.loginButtonText}>
|
|
|
|
|
{t("continueWithApple")}
|
|
|
|
|
</Text>
|
|
|
|
|
</TouchableOpacity>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
style={styles.loginButton}
|
|
|
|
|
onPress={handleInstagramLogin}
|
|
|
|
|
>
|
|
|
|
|
<View style={[styles.loginButtonIcon, styles.instagramIcon]}>
|
|
|
|
|
<Text>📷</Text>
|
|
|
|
|
</View>
|
|
|
|
|
<Text style={styles.loginButtonText}>
|
|
|
|
|
{t("continueWithInstagram")}
|
|
|
|
|
</Text>
|
|
|
|
|
</TouchableOpacity>
|
|
|
|
|
|
|
|
|
|
<TouchableOpacity style={styles.loginButton} onPress={showEmailModal}>
|
|
|
|
|
<View style={styles.loginButtonIcon}>
|
|
|
|
|
<Text>✉️</Text>
|
|
|
|
|
</View>
|
|
|
|
|
<Text style={styles.loginButtonText}>{t("continueWithEmail")}</Text>
|
|
|
|
|
</TouchableOpacity>
|
|
|
|
|
|
|
|
|
|
<TouchableOpacity style={styles.loginButton} onPress={showPhoneModal}>
|
|
|
|
|
<View style={styles.loginButtonIcon}>
|
|
|
|
|
<Text>📱</Text>
|
|
|
|
|
</View>
|
|
|
|
|
<Text style={styles.loginButtonText}>{t("continueWithPhone")}</Text>
|
|
|
|
|
</TouchableOpacity>
|
|
|
|
|
|
|
|
|
|
{/* 忘记密码 */}
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
style={styles.forgotPassword}
|
|
|
|
|
onPress={handleForgotPassword}
|
|
|
|
|
>
|
|
|
|
|
<Text style={styles.forgotPasswordText}>{t("forgotPassword")}</Text>
|
|
|
|
|
</TouchableOpacity>
|
|
|
|
|
|
|
|
|
|
{/* 服务条款 */}
|
|
|
|
|
<View style={styles.termsContainer}>
|
|
|
|
|
<Text style={styles.terms}>
|
|
|
|
|
{t("termsText")}{" "}
|
|
|
|
|
<Text style={styles.link}>{t("termsOfUse")}</Text>
|
|
|
|
|
</Text>
|
|
|
|
|
<Text style={styles.terms}>
|
|
|
|
|
{t("and")} <Text style={styles.link}>{t("privacyPolicy")}</Text>
|
|
|
|
|
</Text>
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
|
|
|
|
|
{/* 邮箱登录模态框 - 直接渲染 */}
|
|
|
|
|
<EmailLoginModal visible={emailModalVisible} onClose={hideEmailModal} />
|
|
|
|
|
|
|
|
|
|
{/* 手机登录模态框 - 直接渲染 */}
|
|
|
|
|
<PhoneLoginModal visible={phoneModalVisible} onClose={hidePhoneModal} />
|
|
|
|
|
</SafeAreaView>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const styles = StyleSheet.create({
|
|
|
|
|
safeArea: {
|
|
|
|
|
flex: 1,
|
|
|
|
|
},
|
|
|
|
|
safeAreaContent: {
|
|
|
|
|
flex: 1,
|
|
|
|
|
paddingTop: 0,
|
|
|
|
|
},
|
|
|
|
|
container: {
|
|
|
|
|
flex: 1,
|
|
|
|
|
backgroundColor: "#FFF",
|
|
|
|
|
},
|
|
|
|
|
closeButton: {
|
|
|
|
|
position: "absolute",
|
|
|
|
|
top: 15,
|
|
|
|
|
left: 10,
|
|
|
|
|
width: 24,
|
|
|
|
|
height: 24,
|
|
|
|
|
justifyContent: "center",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
zIndex: 1,
|
|
|
|
|
},
|
|
|
|
|
closeButtonText: {
|
|
|
|
|
color: "#000",
|
|
|
|
|
fontSize: fontSize(24),
|
|
|
|
|
fontWeight: "300",
|
|
|
|
|
},
|
|
|
|
|
blueHeader: {
|
|
|
|
|
backgroundColor: "#0066FF",
|
|
|
|
|
paddingHorizontal: 20,
|
|
|
|
|
paddingBottom: 20,
|
|
|
|
|
paddingTop: Platform.OS === "ios" ? 60 : 40,
|
|
|
|
|
borderBottomLeftRadius: 24,
|
|
|
|
|
borderBottomRightRadius: 24,
|
|
|
|
|
},
|
|
|
|
|
logo: {
|
|
|
|
|
fontSize: fontSize(28),
|
|
|
|
|
fontWeight: "bold",
|
|
|
|
|
color: "#fff",
|
|
|
|
|
marginBottom: 15,
|
|
|
|
|
},
|
|
|
|
|
features: {
|
|
|
|
|
flexDirection: "row",
|
|
|
|
|
gap: 16,
|
|
|
|
|
},
|
|
|
|
|
featureItem: {
|
|
|
|
|
flexDirection: "row",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
gap: 8,
|
|
|
|
|
},
|
|
|
|
|
featureIconContainer: {
|
|
|
|
|
backgroundColor: "rgba(255, 255, 255, 0.2)",
|
|
|
|
|
borderRadius: 8,
|
|
|
|
|
width: 24,
|
|
|
|
|
height: 24,
|
|
|
|
|
justifyContent: "center",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
},
|
|
|
|
|
featureIcon: {
|
|
|
|
|
fontSize: fontSize(12),
|
|
|
|
|
},
|
|
|
|
|
featureText: {
|
|
|
|
|
fontSize: fontSize(14),
|
|
|
|
|
color: "#fff",
|
|
|
|
|
},
|
|
|
|
|
loginContainer: {
|
|
|
|
|
flex: 1,
|
|
|
|
|
paddingHorizontal: 20,
|
|
|
|
|
paddingTop: Platform.OS === "ios" ? 40 : 20,
|
|
|
|
|
},
|
|
|
|
|
titleContainer: {
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
marginBottom: 30,
|
|
|
|
|
paddingTop: 20,
|
|
|
|
|
position: "relative",
|
|
|
|
|
},
|
|
|
|
|
subtitle: {
|
|
|
|
|
fontSize: fontSize(14),
|
|
|
|
|
color: "#666",
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
},
|
|
|
|
|
loginButton: {
|
|
|
|
|
flexDirection: "row",
|
|
|
|
|
height: 50,
|
|
|
|
|
borderRadius: 25,
|
|
|
|
|
borderWidth: 1,
|
|
|
|
|
borderColor: "#E1E1E1",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
marginBottom: 12,
|
|
|
|
|
paddingHorizontal: 16,
|
|
|
|
|
backgroundColor: "#fff",
|
|
|
|
|
},
|
|
|
|
|
loginButtonIcon: {
|
|
|
|
|
width: 24,
|
|
|
|
|
height: 24,
|
|
|
|
|
borderRadius: 12,
|
|
|
|
|
justifyContent: "center",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
marginRight: 16,
|
|
|
|
|
},
|
|
|
|
|
facebookIcon: {
|
|
|
|
|
backgroundColor: "#3b5998",
|
|
|
|
|
},
|
|
|
|
|
appleIconBg: {
|
|
|
|
|
backgroundColor: "#000",
|
|
|
|
|
},
|
|
|
|
|
instagramIcon: {
|
|
|
|
|
backgroundColor: "#E1306C",
|
|
|
|
|
},
|
|
|
|
|
loginButtonText: {
|
|
|
|
|
flex: 1,
|
|
|
|
|
fontSize: fontSize(16),
|
|
|
|
|
color: "#000",
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
marginRight: 16,
|
|
|
|
|
},
|
|
|
|
|
forgotPassword: {
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
marginVertical: 20,
|
|
|
|
|
},
|
|
|
|
|
forgotPasswordText: {
|
|
|
|
|
color: "#0066FF",
|
|
|
|
|
fontSize: fontSize(14),
|
|
|
|
|
},
|
|
|
|
|
termsContainer: {
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
marginTop: 10,
|
|
|
|
|
},
|
|
|
|
|
terms: {
|
|
|
|
|
fontSize: fontSize(12),
|
|
|
|
|
color: "#666",
|
|
|
|
|
textAlign: "center",
|
|
|
|
|
lineHeight: 18,
|
|
|
|
|
},
|
|
|
|
|
link: {
|
|
|
|
|
color: "#0066FF",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export default LoginScreen;
|