123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- import React, { useEffect, useState } from "react";
- import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
- import MaterialIcons from "@expo/vector-icons/MaterialIcons";
- import Ionicons from "@expo/vector-icons/Ionicons";
- import LoginSVG from "@assets/images/login.svg";
- import GoogleSVG from "@assets/images/google.svg";
- import FacebookSVG from "@assets/images/facebook.svg";
- import TwitterSVG from "@assets/images/twitter.svg";
- import CustomButton from "@components/Buttons/CustomButton";
- import InputField from "@components/InputField";
- import { globalStyles } from "@styles/global";
- import Loader from "@components/Loader";
- import { Formik } from "formik";
- import { loginSchema } from "@schemas/loginSchema";
- import { useDispatch } from "react-redux";
- import useAuthHook from "../hooks/useAuthHook";
- import Layout from "@components/Layout/Layout";
- import { useTheme } from "@styles";
- import { useTranslation } from "react-i18next";
- import { useLoginMutation } from "@features/auth/authApiSlice";
- import { setCredentials } from "@features/auth/authSlice";
- import { useAuthProviderMutation } from "@features/auth/authApiSlice";
- import { storeData } from "@service/asyncStorage";
- import { ACCESS_TOKEN } from "@constants/localStorage";
-
- const LoginScreen = ({ navigation }) => {
- const [authProvider, { isLoading: isLoadingProvider }] =
- useAuthProviderMutation();
- const [currentProvider, setCurrentProvider] = useState("");
- const { colors } = useTheme();
- const { t } = useTranslation();
- const [login, { isLoading, error }] = useLoginMutation();
- const { response, promptAsync } = useAuthHook();
- const dispatch = useDispatch();
-
- const authProviderHandler = async (response) => {
- if (response?.type === "success") {
- const accessToken = response.authentication.accessToken;
- if (accessToken) {
- await storeData(ACCESS_TOKEN, accessToken)
- try {
- const userResponse = await authProvider({
- provider: currentProvider,
- accessToken,
- }).unwrap();
- if (userResponse) {
- dispatch(setCredentials(userResponse));
- }
- } catch (e) {
- console.log(e);
- }
- }
- }
- };
-
- useEffect(() => {
- authProviderHandler(response);
- }, [response, currentProvider]);
-
- const handleGoogleAuth = () => {
- promptAsync();
- };
-
- const handleLogin = async (values) => {
- const { email: identifier, password } = values;
-
- try {
- const userData = await login({ identifier, password }).unwrap();
- dispatch(setCredentials(userData));
- } catch (e) {
- console.log("Login error", e);
- }
- };
-
- return (
- <Layout>
- <Loader visible={isLoading || isLoadingProvider} />
- <View style={{ paddingHorizontal: 25 }}>
- <View style={{ alignItems: "center" }}>
- <LoginSVG height={300} width={300} />
- </View>
- <Formik
- initialValues={{
- email: "",
- password: "",
- }}
- validationSchema={loginSchema}
- onSubmit={handleLogin}
- validateOnChange={false}
- validateOnBlur={false}
- >
- {({
- handleChange,
- handleBlur,
- handleSubmit,
- values,
- isValid,
- errors,
- }) => (
- <>
- <Text
- style={[globalStyles.boldText, { color: colors.textPrimary }]}
- >
- {t("login.signIn")}
- </Text>
- <InputField
- name="email"
- label={t("login.email")}
- keyboardType="email-address"
- onChangeText={handleChange("email")}
- text={values.email}
- style={{ color: colors.textPrimary }}
- handleBlur={handleBlur("email")}
- icon={
- <MaterialIcons
- name="alternate-email"
- size={20}
- color="#666"
- style={{ marginRight: 5 }}
- />
- }
- />
- {errors.email && (
- <Text style={styles.errorMessage}>{errors.email}</Text>
- )}
- <InputField
- name="password"
- label={t("login.password")}
- filedButtonLabel={t("register.forgot")}
- fieldButtonFunction={() => {}}
- inputType="password"
- handleBlur={handleBlur("password")}
- text={values.password}
- onChangeText={handleChange("password")}
- icon={
- <Ionicons
- name="ios-lock-closed-outline"
- size={20}
- color="#666"
- style={{ marginRight: 5 }}
- />
- }
- />
- {errors.password && (
- <Text style={styles.errorMessage}>{errors.password}</Text>
- )}
- {error && (
- <Text style={styles.errorMessage}>
- {error?.data?.error?.message}
- </Text>
- )}
- <CustomButton label={t("login.login")} onPress={handleSubmit} />
- </>
- )}
- </Formik>
- <Text
- style={[
- globalStyles.regularCenteredText,
- { color: colors.textPrimary },
- ]}
- >
- {t("login.orLoginWith")}
- </Text>
- <View style={styles.providersContainer}>
- <TouchableOpacity
- onPress={() => {
- setCurrentProvider("google");
- handleGoogleAuth();
- }}
- style={globalStyles.iconButton}
- >
- <GoogleSVG height={24} width={24} />
- </TouchableOpacity>
- <TouchableOpacity onPress={() => {}} style={globalStyles.iconButton}>
- <FacebookSVG height={24} width={24} />
- </TouchableOpacity>
- <TouchableOpacity onPress={() => {}} style={globalStyles.iconButton}>
- <TwitterSVG height={24} width={24} />
- </TouchableOpacity>
- </View>
- <View style={styles.registerContainer}>
- <Text
- style={[globalStyles.regularText, { color: colors.textPrimary }]}
- >
- {t("login.needAccount")}{" "}
- </Text>
- <TouchableOpacity onPress={() => navigation.navigate("Register")}>
- <Text style={styles.registerButtonText}>{t("login.signUp")}</Text>
- </TouchableOpacity>
- </View>
- </View>
- </Layout>
- );
- };
-
- const styles = StyleSheet.create({
- providerText: {
- textAlign: "center",
- color: "#666",
- marginBottom: 30,
- fontFamily: "poppins-regular",
- },
- providersContainer: {
- flexDirection: "row",
- justifyContent: "space-between",
- marginBottom: 30,
- },
- registerContainer: {
- flexDirection: "row",
- justifyContent: "center",
- marginBottom: 30,
- },
- registerButtonText: {
- color: "#AD40AF",
- fontWeight: "700",
- fontFamily: "poppins-semibold",
- },
- errorMessage: {
- marginBottom: 30,
- color: "red",
- },
- });
-
- export default LoginScreen;
|