Files
musicland/src/screens/Login.js
T
Philip Cesar Garay 84fc719a10 update
2025-07-31 21:25:33 +08:00

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>
);
};