Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

RegisterScreen.jsx 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. import React, { useEffect } from "react";
  2. import {
  3. SafeAreaView,
  4. ScrollView,
  5. View,
  6. Text,
  7. TouchableOpacity,
  8. StyleSheet,
  9. Alert,
  10. } from "react-native";
  11. // import DateTimePicker from "@react-native-community/datetimepicker";
  12. import InputField from "../components/InputField";
  13. import MaterialIcons from "@expo/vector-icons/MaterialIcons";
  14. import Ionicons from "@expo/vector-icons/Ionicons";
  15. import RegistrationSVG from "../assets/images/registration.svg";
  16. import GoogleSVG from "../assets/images/google.svg";
  17. import FacebookSVG from "../assets/images/facebook.svg";
  18. import TwitterSVG from "../assets/images/twitter.svg";
  19. import CustomButton from "../components/Buttons/CustomButton";
  20. import { globalStyles } from "../styles/global";
  21. import Loader from "../components/Loader";
  22. import { Formik } from "formik";
  23. import { registerSchema } from "../schemas/registerSchema";
  24. import { useDispatch, useSelector } from "react-redux";
  25. import { selectRegisterError } from "../store/selectors/registerSelectors";
  26. import { selectIsLoadingByActionType } from "../store/selectors/loadingSelectors";
  27. import { REGISTER_USER_SCOPE } from "../store/actions/register/registerActionConstants";
  28. import {
  29. clearRegisterErrors,
  30. registerUser,
  31. } from "../store/actions/register/registerActions";
  32. import useAuthHook from "../hooks/useAuthHook";
  33. import { fetchAuthProvider } from "../store/actions/authProvider/authProviderActions";
  34. import { ACCESS_TOKEN } from "../constants/localStorage";
  35. import { storeData } from "../service/asyncStorage";
  36. const RegisterScreen = ({ navigation }) => {
  37. const { response, promptAsync } = useAuthHook();
  38. const dispatch = useDispatch();
  39. const error = useSelector(selectRegisterError);
  40. const isLoading = useSelector(
  41. selectIsLoadingByActionType(REGISTER_USER_SCOPE)
  42. );
  43. const storeToken = async (token) => {
  44. await storeData(ACCESS_TOKEN, token);
  45. }
  46. const handleApiResponseSuccess = () => {
  47. Alert.alert(
  48. "Success",
  49. "Successfully registered account, now you can log in",
  50. [
  51. {
  52. text: "OK",
  53. onPress: () => navigation.navigate("Login"),
  54. },
  55. ]
  56. );
  57. };
  58. const handleSignup = (values) => {
  59. const { username, email, password } = values;
  60. dispatch(clearRegisterErrors());
  61. dispatch(
  62. registerUser({ username, email, password, handleApiResponseSuccess })
  63. );
  64. };
  65. const handleGoogleAuth = () => {
  66. promptAsync({ useProxy: true, showInRecents: true });
  67. };
  68. useEffect(() => {
  69. if (response?.type === "success") {
  70. const accessToken = response.authentication.accessToken;
  71. if (accessToken) {
  72. storeToken(accessToken);
  73. dispatch(fetchAuthProvider({ accessToken }));
  74. }
  75. }
  76. }, [response]);
  77. return (
  78. <SafeAreaView style={globalStyles.safeArea}>
  79. <Loader visible={isLoading} />
  80. <ScrollView
  81. showsVerticalScrollIndicator={false}
  82. style={{ paddingHorizontal: 25 }}
  83. >
  84. <View style={{ alignItems: "center" }}>
  85. <RegistrationSVG width={300} height={300} />
  86. </View>
  87. <Text style={globalStyles.boldText}>Sign Up</Text>
  88. <View style={styles.providersContainer}>
  89. <TouchableOpacity
  90. onPress={handleGoogleAuth}
  91. style={globalStyles.iconButton}
  92. >
  93. <GoogleSVG height={24} width={24} />
  94. </TouchableOpacity>
  95. <TouchableOpacity onPress={() => {}} style={globalStyles.iconButton}>
  96. <FacebookSVG height={24} width={24} />
  97. </TouchableOpacity>
  98. <TouchableOpacity onPress={() => {}} style={globalStyles.iconButton}>
  99. <TwitterSVG height={24} width={24} />
  100. </TouchableOpacity>
  101. </View>
  102. <Text style={globalStyles.regularCenteredText}>
  103. Or, sign up with email...
  104. </Text>
  105. <Formik
  106. initialValues={{
  107. username: "",
  108. email: "",
  109. password: "",
  110. confirmPassword: "",
  111. }}
  112. validationSchema={registerSchema}
  113. onSubmit={handleSignup}
  114. validateOnChange={false}
  115. validateOnBlur={false}
  116. >
  117. {({
  118. handleChange,
  119. handleBlur,
  120. handleSubmit,
  121. values,
  122. isValid,
  123. errors,
  124. }) => (
  125. <>
  126. <InputField
  127. name={"username"}
  128. text={values.username}
  129. onChangeText={handleChange("username")}
  130. label={"Username"}
  131. handleBlur={handleBlur("username")}
  132. icon={
  133. <Ionicons
  134. name="person-outline"
  135. size={20}
  136. color="#666"
  137. style={{ marginRight: 5 }}
  138. />
  139. }
  140. />
  141. {errors.username && (
  142. <Text style={styles.errorMessage}>{errors.username}</Text>
  143. )}
  144. <InputField
  145. name={"email"}
  146. text={values.email}
  147. onChangeText={handleChange("email")}
  148. label={"Email"}
  149. handleBlur={handleBlur("email")}
  150. icon={
  151. <MaterialIcons
  152. name="alternate-email"
  153. size={20}
  154. color="#666"
  155. style={{ marginRight: 5 }}
  156. />
  157. }
  158. keyboardType="email-address"
  159. />
  160. {errors.email && (
  161. <Text style={styles.errorMessage}>{errors.email}</Text>
  162. )}
  163. <InputField
  164. name={"password"}
  165. text={values.password}
  166. onChangeText={handleChange("password")}
  167. label={"Password"}
  168. handleBlur={handleBlur("password")}
  169. icon={
  170. <Ionicons
  171. name="ios-lock-closed-outline"
  172. size={20}
  173. color="#666"
  174. style={{ marginRight: 5 }}
  175. />
  176. }
  177. inputType="password"
  178. />
  179. {errors.password && (
  180. <Text style={styles.errorMessage}>{errors.password}</Text>
  181. )}
  182. <InputField
  183. name={"confirmPassword"}
  184. text={values.confirmPassword}
  185. onChangeText={handleChange("confirmPassword")}
  186. label={"Confirm Password"}
  187. handleBlur={handleBlur("confirmPassword")}
  188. icon={
  189. <Ionicons
  190. name="ios-lock-closed-outline"
  191. size={20}
  192. color="#666"
  193. style={{ marginRight: 5 }}
  194. />
  195. }
  196. inputType="password"
  197. />
  198. {errors.confirmPassword && (
  199. <Text style={styles.errorMessage}>
  200. {errors.confirmPassword}
  201. </Text>
  202. )}
  203. {error && <Text style={styles.errorMessage}>{error}</Text>}
  204. <CustomButton label={"Sign Up"} onPress={handleSubmit} />
  205. </>
  206. )}
  207. </Formik>
  208. <View style={styles.alreadyRegistered}>
  209. <Text style={globalStyles.regularText}>Already Registered? </Text>
  210. <TouchableOpacity onPress={() => navigation.goBack()}>
  211. <Text style={globalStyles.primaryBold}>Sign In</Text>
  212. </TouchableOpacity>
  213. </View>
  214. </ScrollView>
  215. </SafeAreaView>
  216. );
  217. };
  218. const styles = StyleSheet.create({
  219. providersContainer: {
  220. flexDirection: "row",
  221. justifyContent: "space-between",
  222. marginBottom: 30,
  223. },
  224. dateOfBirthContainer: {
  225. flexDirection: "row",
  226. borderBottomColor: "#ccc",
  227. borderBottomWidth: 1,
  228. paddingBottom: 8,
  229. marginBottom: 30,
  230. },
  231. dateOfBirthLabel: {
  232. color: "#666",
  233. marginLeft: 5,
  234. marginTop: 5,
  235. },
  236. alreadyRegistered: {
  237. flexDirection: "row",
  238. justifyContent: "center",
  239. marginBottom: 30,
  240. },
  241. errorMessage: {
  242. marginBottom: 30,
  243. color: "red",
  244. },
  245. });
  246. export default RegisterScreen;