345 lines
9.1 KiB
JavaScript
345 lines
9.1 KiB
JavaScript
import React, { useState, useRef, useEffect, useGlobal } from "reactn";
|
|
import {
|
|
Text,
|
|
View,
|
|
KeyboardAvoidingView,
|
|
Image,
|
|
Pressable,
|
|
} from "react-native";
|
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
|
|
import {
|
|
responsiveHeight,
|
|
responsiveWidth,
|
|
} from "../actions/responsiveSizes.js";
|
|
|
|
import firebase from "../config/firebase";
|
|
|
|
import Button from "../components/Button";
|
|
import { Input } from "../components/Input";
|
|
|
|
import { Fonts, gutters, Palette, Style } from "../styles";
|
|
import { Routes } from "../navigation";
|
|
import { art, mockups } from "../assets";
|
|
import {
|
|
checkIfEmailIsValid,
|
|
checkIfPasswordIsStrongEnough,
|
|
handleFirebaseError,
|
|
} from "../actions/signupActions";
|
|
|
|
import useLayoutType from "../hooks/useLayoutType.js";
|
|
import { capitalize } from "../helpers/index.js";
|
|
|
|
export default ({ navigation }) => {
|
|
console.log("LOGINSCREEN");
|
|
const [, setTooltip] = useGlobal("_tooltip");
|
|
const [, setIsLoading] = useGlobal("_isLoading");
|
|
|
|
const [mode, setMode] = useState("LOGIN");
|
|
|
|
const [emailIsStatic, setEmailIsStatic] = useState(false);
|
|
|
|
const [email, setEmail] = useState("login@minuit.com");
|
|
const [password, setPassword] = useState("password");
|
|
|
|
const [firstName, setFirstName] = useState("");
|
|
const [lastName, setLastName] = useState("");
|
|
|
|
const passwordInputRef = useRef();
|
|
|
|
const { isDesktop } = useLayoutType();
|
|
|
|
useEffect(() => {
|
|
const checkIfUserIsLoggedIn = async () => {
|
|
const userEmail = await AsyncStorage.getItem("userEmail");
|
|
|
|
if (userEmail) {
|
|
setEmail(userEmail);
|
|
setEmailIsStatic(true);
|
|
}
|
|
};
|
|
|
|
checkIfUserIsLoggedIn();
|
|
}, []);
|
|
|
|
const onLogin = async () => {
|
|
try {
|
|
setIsLoading(true);
|
|
|
|
let trimmedEmail = email.trim();
|
|
|
|
await firebase.auth().signInWithEmailAndPassword(trimmedEmail, password);
|
|
await AsyncStorage.setItem("userEmail", trimmedEmail);
|
|
|
|
onAuthSuccess();
|
|
} catch (error) {
|
|
console.log(error);
|
|
setTooltip({
|
|
text: handleFirebaseError(error.code),
|
|
type: "error",
|
|
});
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
const onSignup = async () => {
|
|
try {
|
|
setIsLoading(true);
|
|
|
|
if (!checkIfPasswordIsStrongEnough({ password })) {
|
|
throw new Error(
|
|
"Votre mot de passe doit contenir au moins 6 caractères, une majuscule et un chiffre."
|
|
);
|
|
}
|
|
|
|
if (!checkIfEmailIsValid({ email })) {
|
|
throw new Error("Veuillez renseigner une adresse email valide.");
|
|
}
|
|
|
|
const { user = null } = await firebase
|
|
.auth()
|
|
.createUserWithEmailAndPassword(email, password);
|
|
|
|
if (!user) {
|
|
throw new Error("Erreur lors de la création du compte");
|
|
}
|
|
|
|
let userObject = {
|
|
firstName: capitalize(firstName.trim()),
|
|
lastName: capitalize(lastName.trim()),
|
|
};
|
|
|
|
// push user data to firestore
|
|
|
|
onAuthSuccess();
|
|
|
|
setTooltip({
|
|
text: "Votre compte a été créé avec succès!",
|
|
type: "success",
|
|
});
|
|
} catch (error) {
|
|
console.log(error);
|
|
setTooltip({
|
|
text: error?.code?.startsWith("auth/")
|
|
? handleFirebaseError(error.code)
|
|
: error.message,
|
|
type: "error",
|
|
});
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
const onAuthSuccess = async () => {
|
|
navigation.reset({
|
|
index: 0,
|
|
routes: [{ name: Routes.Splash }],
|
|
});
|
|
};
|
|
|
|
return (
|
|
<View
|
|
headerType="NONE"
|
|
style={{
|
|
flex: 1,
|
|
backgroundColor: Palette.lightPurple,
|
|
...Style.containerRow,
|
|
}}
|
|
>
|
|
<View
|
|
style={{
|
|
position: "relative",
|
|
flex: 1,
|
|
padding: 2 * gutters,
|
|
backgroundColor: Palette.darkPurple,
|
|
height: "100%",
|
|
...Style.containerCenter,
|
|
}}
|
|
>
|
|
<Image
|
|
resizeMode="contain"
|
|
source={art.gradientTriangle}
|
|
style={{
|
|
position: "absolute",
|
|
top: responsiveHeight(20),
|
|
right: responsiveHeight(5),
|
|
width: responsiveWidth(140),
|
|
height: responsiveWidth(140),
|
|
}}
|
|
/>
|
|
|
|
<KeyboardAvoidingView
|
|
style={{ ...Style.containerCenter, width: "100%" }}
|
|
behavior="padding"
|
|
keyboardVerticalOffset={responsiveHeight(10)}
|
|
>
|
|
<Text
|
|
style={{
|
|
...Fonts({ type: "megaTitle" }),
|
|
marginBottom: responsiveHeight(10),
|
|
}}
|
|
>
|
|
minuit.starter
|
|
</Text>
|
|
|
|
{emailIsStatic && mode === "LOGIN" ? (
|
|
<>
|
|
<Text
|
|
style={{
|
|
...Fonts({
|
|
type: "default",
|
|
color: Palette.white,
|
|
style: { marginBottom: 20, textAlign: "center" },
|
|
}),
|
|
}}
|
|
>
|
|
{`Vous êtes connecté(e) avec l'adresse ${email},`}
|
|
</Text>
|
|
|
|
<Pressable
|
|
onPress={async () => {
|
|
await AsyncStorage.removeItem("userEmail");
|
|
|
|
setEmailIsStatic(false);
|
|
}}
|
|
>
|
|
<Text
|
|
style={{
|
|
...Fonts({
|
|
type: "default",
|
|
color: Palette.primary,
|
|
style: {
|
|
marginBottom: 20,
|
|
textAlign: "center",
|
|
textDecorationLine: "underline",
|
|
},
|
|
}),
|
|
}}
|
|
>
|
|
Modifier
|
|
</Text>
|
|
</Pressable>
|
|
</>
|
|
) : (
|
|
<Input
|
|
layout="line"
|
|
type="email"
|
|
label="Adresse email"
|
|
placeholder="Votre adresse email"
|
|
value={email}
|
|
setValue={setEmail}
|
|
containerStyle={{ marginBottom: 20 }}
|
|
textInputProps={{
|
|
returnKeyType: "next",
|
|
onSubmitEditing: () => passwordInputRef.current.focus(),
|
|
}}
|
|
/>
|
|
)}
|
|
|
|
<Input
|
|
layout="line"
|
|
inputRef={passwordInputRef}
|
|
label="Mot de passe"
|
|
placeholder="Votre mot de passe"
|
|
value={password}
|
|
setValue={setPassword}
|
|
type="password"
|
|
containerStyle={{ marginBottom: gutters }}
|
|
textInputProps={{
|
|
returnKeyType: "done",
|
|
onSubmitEditing: onLogin,
|
|
}}
|
|
/>
|
|
|
|
{mode === "LOGIN" ? (
|
|
<Pressable
|
|
onPress={() => navigation.navigate("ForgotPassword")}
|
|
style={{ marginBottom: gutters }}
|
|
>
|
|
<Text
|
|
style={{
|
|
...Fonts({
|
|
type: "default",
|
|
style: { textDecorationLine: "underline" },
|
|
}),
|
|
}}
|
|
>
|
|
Mot de passe oublié?
|
|
</Text>
|
|
</Pressable>
|
|
) : (
|
|
<>
|
|
<Input
|
|
layout="line"
|
|
label="Prénom"
|
|
placeholder="Votre prénom"
|
|
value={firstName}
|
|
setValue={setFirstName}
|
|
containerStyle={{ marginBottom: gutters }}
|
|
/>
|
|
|
|
<Input
|
|
layout="line"
|
|
label="Nom"
|
|
placeholder="Votre nom"
|
|
value={lastName}
|
|
setValue={setLastName}
|
|
containerStyle={{ marginBottom: gutters }}
|
|
/>
|
|
</>
|
|
)}
|
|
|
|
<Button
|
|
{...(mode === "LOGIN"
|
|
? { text: "Connexion", onPress: onLogin }
|
|
: {
|
|
text: "Inscription",
|
|
onPress: onSignup,
|
|
})}
|
|
containerStyle={{ marginBottom: gutters }}
|
|
/>
|
|
|
|
<Pressable onPress={() => navigation.navigate("TermsOfUse")}>
|
|
<Text
|
|
style={Fonts({
|
|
type: "default",
|
|
style: { textAlign: "center", opacity: 1 },
|
|
})}
|
|
>
|
|
En vous {mode === "LOGIN" ? "connectant" : "inscrivant"}, vous
|
|
acceptez sans réserve les{" "}
|
|
<Text
|
|
style={{
|
|
color: Palette.primary,
|
|
textDecorationLine: "underline",
|
|
}}
|
|
>
|
|
conditions générales d'utilisation
|
|
</Text>{" "}
|
|
de minuit.starter.
|
|
</Text>
|
|
</Pressable>
|
|
</KeyboardAvoidingView>
|
|
</View>
|
|
|
|
{isDesktop && (
|
|
<View style={{ flex: 2, height: "100%", overflow: "hidden" }}>
|
|
<Image
|
|
resizeMode="contain"
|
|
source={mockups.loginAppDashboard}
|
|
style={{
|
|
position: "absolute",
|
|
top: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
width: "100%",
|
|
height: "100%",
|
|
}}
|
|
/>
|
|
</View>
|
|
)}
|
|
</View>
|
|
);
|
|
};
|