Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

LoginScreen.jsx 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import React, { useEffect } from "react";
  2. import {
  3. SafeAreaView,
  4. View,
  5. Text,
  6. TouchableOpacity,
  7. StyleSheet,
  8. } from "react-native";
  9. import MaterialIcons from "@expo/vector-icons/MaterialIcons";
  10. import Ionicons from "@expo/vector-icons/Ionicons";
  11. import LoginSVG from "../assets/images/login.svg";
  12. import GoogleSVG from "../assets/images/google.svg";
  13. import FacebookSVG from "../assets/images/facebook.svg";
  14. import TwitterSVG from "../assets/images/twitter.svg";
  15. import CustomButton from "../components/Buttons/CustomButton";
  16. import InputField from "../components/InputField";
  17. import { globalStyles } from "../styles/global";
  18. import Loader from "../components/Loader";
  19. import { Formik } from "formik";
  20. import { loginSchema } from "../schemas/loginSchema";
  21. import { useDispatch, useSelector } from "react-redux";
  22. import { selectLoginError } from "../store/selectors/loginSelectors";
  23. import {
  24. clearLoginErrors,
  25. fetchUser,
  26. } from "../store/actions/login/loginActions";
  27. import { selectIsLoadingByActionType } from "../store/selectors/loadingSelectors";
  28. import { LOGIN_USER_SCOPE } from "../store/actions/login/loginActionConstants";
  29. import { fetchAuthProvider } from "../store/actions/authProvider/authProviderActions";
  30. import useAuthHook from "../hooks/useAuthHook";
  31. import { storeData } from "../service/asyncStorage";
  32. import { ACCESS_TOKEN } from "../constants/localStorage";
  33. const LoginScreen = ({ navigation }) => {
  34. const { response, promptAsync } = useAuthHook();
  35. const dispatch = useDispatch();
  36. const error = useSelector(selectLoginError);
  37. const isLoading = useSelector(selectIsLoadingByActionType(LOGIN_USER_SCOPE));
  38. const storeToken = async (token) => {
  39. await storeData(ACCESS_TOKEN, token);
  40. }
  41. useEffect(() => {
  42. if (response?.type === "success") {
  43. const accessToken = response.authentication.accessToken;
  44. if (accessToken) {
  45. storeToken(accessToken);
  46. dispatch(fetchAuthProvider({ accessToken }));
  47. }
  48. }
  49. }, [response]);
  50. const handleGoogleAuth = () => {
  51. promptAsync({ useProxy: true, showInRecents: true });
  52. };
  53. const handleLogin = (values) => {
  54. const { email, password } = values;
  55. dispatch(clearLoginErrors());
  56. dispatch(
  57. fetchUser({
  58. identifier: email,
  59. password,
  60. })
  61. );
  62. };
  63. return (
  64. <SafeAreaView style={globalStyles.safeArea}>
  65. <Loader visible={isLoading} />
  66. <View style={{ paddingHorizontal: 25 }}>
  67. <View style={{ alignItems: "center" }}>
  68. <LoginSVG height={300} width={300} />
  69. </View>
  70. <Formik
  71. initialValues={{
  72. email: "",
  73. password: "",
  74. }}
  75. validationSchema={loginSchema}
  76. onSubmit={handleLogin}
  77. validateOnChange={false}
  78. validateOnBlur={false}
  79. >
  80. {({
  81. handleChange,
  82. handleBlur,
  83. handleSubmit,
  84. values,
  85. isValid,
  86. errors,
  87. }) => (
  88. <>
  89. <Text style={globalStyles.boldText}>Sign In</Text>
  90. <InputField
  91. name="email"
  92. label={"Email"}
  93. keyboardType="email-address"
  94. onChangeText={handleChange("email")}
  95. text={values.email}
  96. handleBlur={handleBlur("email")}
  97. icon={
  98. <MaterialIcons
  99. name="alternate-email"
  100. size={20}
  101. color="#666"
  102. style={{ marginRight: 5 }}
  103. />
  104. }
  105. />
  106. {errors.email && (
  107. <Text style={styles.errorMessage}>{errors.email}</Text>
  108. )}
  109. <InputField
  110. name="password"
  111. label={"Password"}
  112. filedButtonLabel={"Forgot?"}
  113. fieldButtonFunction={() => {}}
  114. inputType="password"
  115. handleBlur={handleBlur("password")}
  116. text={values.password}
  117. onChangeText={handleChange("password")}
  118. icon={
  119. <Ionicons
  120. name="ios-lock-closed-outline"
  121. size={20}
  122. color="#666"
  123. style={{ marginRight: 5 }}
  124. />
  125. }
  126. />
  127. {errors.password && (
  128. <Text style={styles.errorMessage}>{errors.password}</Text>
  129. )}
  130. {error && <Text style={styles.errorMessage}>{error}</Text>}
  131. <CustomButton label={"Login"} onPress={handleSubmit} />
  132. </>
  133. )}
  134. </Formik>
  135. <Text style={globalStyles.regularCenteredText}>Or login with ...</Text>
  136. <View style={styles.providersContainer}>
  137. <TouchableOpacity
  138. onPress={handleGoogleAuth}
  139. style={globalStyles.iconButton}
  140. >
  141. <GoogleSVG height={24} width={24} />
  142. </TouchableOpacity>
  143. <TouchableOpacity onPress={() => {}} style={globalStyles.iconButton}>
  144. <FacebookSVG height={24} width={24} />
  145. </TouchableOpacity>
  146. <TouchableOpacity onPress={() => {}} style={globalStyles.iconButton}>
  147. <TwitterSVG height={24} width={24} />
  148. </TouchableOpacity>
  149. </View>
  150. <View style={styles.registerContainer}>
  151. <Text style={globalStyles.regularText}>Need account? </Text>
  152. <TouchableOpacity onPress={() => navigation.navigate("Register")}>
  153. <Text style={styles.registerButtonText}>Sign Up</Text>
  154. </TouchableOpacity>
  155. </View>
  156. </View>
  157. </SafeAreaView>
  158. );
  159. };
  160. const styles = StyleSheet.create({
  161. providerText: {
  162. textAlign: "center",
  163. color: "#666",
  164. marginBottom: 30,
  165. fontFamily: "poppins-regular",
  166. },
  167. providersContainer: {
  168. flexDirection: "row",
  169. justifyContent: "space-between",
  170. marginBottom: 30,
  171. },
  172. registerContainer: {
  173. flexDirection: "row",
  174. justifyContent: "center",
  175. marginBottom: 30,
  176. },
  177. registerButtonText: {
  178. color: "#AD40AF",
  179. fontWeight: "700",
  180. fontFamily: "poppins-semibold",
  181. },
  182. errorMessage: {
  183. marginBottom: 30,
  184. color: "red",
  185. },
  186. });
  187. export default LoginScreen;