Files
musicland/src/screens/Register.js
T
Thomas Demirdjian e96e4c263d change card
2025-12-01 15:07:46 +01:00

389 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import AsyncStorage from "@react-native-async-storage/async-storage";
import * as AppleAuthentication from "expo-apple-authentication";
import React, { useCallback, useEffect, useState } from "react";
import {
ActivityIndicator,
KeyboardAvoidingView,
Platform,
Pressable,
StyleSheet,
Text,
View,
} from "react-native";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
import Svg, { Path } from "react-native-svg";
import { background } from "../assets";
import BorderGradientButton from "../components/BorderGradientButton";
import { Input } from "../components/Input";
import ItemContainer from "../components/ItemContainer/ItemContainer";
import firebase from "../config/firebase";
import { isWeb } from "../hooks/useLayoutType";
import useSocialAuth from "../hooks/useSocialAuth";
import Page from "../layouts/Page";
import { Routes } from "../navigation";
import { navigate, reset } from "../navigation/NavigationService";
import { Palette } from "../styles";
import { FONT_FAMILY } from "../styles/Fonts";
const LANGUAGE_STORAGE_KEY = "preferredLanguage";
const Register = () => {
const [email, setEmail] = useState("");
const [firstName, setFirstName] = useState("");
const [preferredLanguage, setPreferredLanguage] = useState(null);
const afterSocialAuth = useCallback(async () => {
const uid = firebase.auth().currentUser?.uid;
if (!uid) throw new Error("Aucun utilisateur après connexion");
reset({ index: 0, routes: [{ name: Routes.BottomTab }] });
}, []);
const {
signInWithGoogle,
signInWithApple,
isAppleSignInAvailable,
isLoading: socialLoading,
} = useSocialAuth({
onSuccess: afterSocialAuth,
});
const isBusy = socialLoading;
useEffect(() => {
AsyncStorage.getItem(LANGUAGE_STORAGE_KEY)
.then((storedLanguage) => {
if (storedLanguage) {
setPreferredLanguage(storedLanguage);
}
})
.catch((error) => {
console.warn("Register: failed to load preferred language", error);
});
}, []);
const isFormValid = email.trim().length > 0 && firstName.trim().length > 0;
const renderFormContent = () => (
<View style={styles.formContent}>
<Text style={styles.title}>Renseigne tes informations</Text>
{preferredLanguage && !isWeb ? (
<Text style={styles.languageInfo}>
Langue choisie :{" "}
<Text style={styles.languageInfoValue}>
{preferredLanguage === "fr" ? "Français" : "English"}
</Text>
</Text>
) : null}
<View style={{ gap: 16 }}>
<Input
placeholder="Prénom"
label="Prénom"
isBlur
value={firstName}
setValue={setFirstName}
/>
<Input
placeholder="Adresse mail"
label="Adresse mail"
isBlur
type="email"
value={email}
setValue={setEmail}
/>
</View>
<BorderGradientButton
title="Créer mon compte"
containerStyle={{
width: "90%",
alignSelf: "center",
}}
onPress={() =>
navigate(Routes.CreatePassword, {
email: email.trim(),
firstName: firstName.trim(),
preferredLanguage,
})
}
disabled={!isFormValid || isBusy}
/>
<View style={styles.socialWrapper}>
{isAppleSignInAvailable ? (
<AppleAuthButton
onPress={signInWithApple}
disabled={isBusy}
loading={socialLoading}
/>
) : null}
<GoogleAuthButton
onPress={signInWithGoogle}
disabled={isBusy}
loading={socialLoading}
/>
</View>
<View style={styles.footer}>
<Text style={styles.terms}>
En tinscrivant, tu acceptes nos conditions générales{"\n"}
dutilisation et notre politique de confidentialité.
</Text>
</View>
<Text style={styles.bottomFooterText}>
Tu as déjà un compte ?{" "}
<Text
style={styles.bottomFooterLink}
onPress={() => navigate(Routes.Login)}
>
Se connecter
</Text>
</Text>
</View>
);
return (
<Page
width={isWeb ? 600 : null}
backgroundImg={isWeb ? background.loginBgWeb : background.homeBG}
headerType="NAVIGATION"
title="Inscription"
>
<View style={styles.pageContent}>
<ItemContainer
height={isWeb ? 720 : undefined}
disableKeyboardHeight
style={!isWeb ? styles.mobileItemContainer : styles.webItemContainer}
>
{isWeb ? (
renderFormContent()
) : (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.mobileAvoider}
>
<KeyboardAwareScrollView
contentContainerStyle={styles.mobileScrollContent}
showsVerticalScrollIndicator={false}
keyboardShouldPersistTaps="handled"
>
{renderFormContent()}
</KeyboardAwareScrollView>
</KeyboardAvoidingView>
)}
</ItemContainer>
</View>
</Page>
);
};
const AppleAuthButton = ({ onPress, disabled, loading }) => {
if (isWeb) {
return null;
}
return (
<View style={styles.nativeButtonWrapper}>
<AppleAuthentication.AppleAuthenticationButton
buttonType={AppleAuthentication.AppleAuthenticationButtonType.SIGN_UP}
buttonStyle={AppleAuthentication.AppleAuthenticationButtonStyle.WHITE}
style={styles.nativeButton}
cornerRadius={12}
onPress={onPress}
disabled={disabled}
/>
{loading ? (
<View style={styles.nativeLoadingOverlay}>
<ActivityIndicator size="small" color={Palette.black} />
</View>
) : null}
</View>
);
};
const GoogleAuthButton = ({ onPress, disabled, loading }) => (
<Pressable
accessibilityRole="button"
onPress={onPress}
disabled={disabled}
style={({ pressed }) => [
styles.socialButton,
pressed && !disabled ? styles.socialButtonPressed : null,
disabled ? styles.socialButtonDisabled : null,
]}
>
<View style={styles.socialButtonContent}>
<View style={styles.socialIconContainer}>
<GoogleLogo />
</View>
<Text style={styles.socialButtonText}>Continuer avec Google</Text>
{loading ? (
<ActivityIndicator size="small" color="#4285F4" />
) : (
<View style={styles.socialRightSpacer} />
)}
</View>
</Pressable>
);
const GoogleLogo = () => (
<Svg width={24} height={24} viewBox="0 0 18 18">
<Path
fill="#4285F4"
d="M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.71v2.26h2.9c1.68-1.55 2.7-3.83 2.7-6.61Z"
/>
<Path
fill="#34A853"
d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.9-2.26c-.8.54-1.83.86-3.06.86a5.31 5.31 0 0 1-5.02-3.69H.96v2.32A9 9 0 0 0 9 18Z"
/>
<Path
fill="#FBBC05"
d="M3.98 10.73c-.18-.54-.28-1.12-.28-1.73s.1-1.19.28-1.73V4.95H.96A9 9 0 0 0 0 9c0 1.45.35 2.82.96 4.05l3.02-2.32Z"
/>
<Path
fill="#EA4335"
d="M9 3.54c1.32 0 2.5.45 3.43 1.33l2.57-2.57C13.47.9 11.43 0 9 0A9 9 0 0 0 .96 4.95l3.02 2.32A5.31 5.31 0 0 1 9 3.54Z"
/>
</Svg>
);
export default Register;
const styles = StyleSheet.create({
pageContent: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
webItemContainer: {
width: "100%",
maxWidth: 680,
},
mobileItemContainer: {
width: "100%",
minHeight: 720,
},
mobileAvoider: {
flex: 1,
},
mobileScrollContent: {
flexGrow: 1,
justifyContent: "center",
paddingVertical: 24,
},
formContent: {
gap: 32,
paddingTop: 5,
paddingHorizontal: 5,
},
title: {
fontSize: 22,
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
},
languageInfo: {
fontSize: 14,
color: Palette.gray,
fontFamily: FONT_FAMILY.InterRegular,
},
languageInfoValue: {
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
},
footer: {
alignItems: "center",
gap: 4,
},
terms: {
fontSize: 12,
color: Palette.gray,
fontFamily: FONT_FAMILY.HelveticaNeueRegular,
textAlign: "center",
},
loginText: {
fontSize: 14,
color: Palette.white,
fontFamily: FONT_FAMILY.HelveticaNeueRegular,
},
loginLink: {
fontFamily: FONT_FAMILY.InterSemiBold,
},
bottomLoginPrompt: {
marginTop: 16,
paddingHorizontal: 24,
marginBottom: 30,
},
bottomFooterText: {
fontSize: 15,
color: Palette.white,
fontFamily: FONT_FAMILY.HelveticaNeueRegular,
textAlign: "center",
},
bottomFooterLink: {
fontFamily: FONT_FAMILY.InterBold,
color: Palette.white,
fontSize: 16,
},
socialWrapper: {
width: "100%",
gap: 16,
alignItems: "center",
},
socialButton: {
alignSelf: "center",
borderRadius: 12,
width: "90%",
backgroundColor: Palette.white,
borderWidth: 1,
borderColor: "#E3E7EF",
paddingVertical: 12,
paddingHorizontal: 20,
shadowColor: "rgba(12, 6, 34, 0.08)",
shadowOffset: { width: 0, height: 8 },
shadowOpacity: 0.3,
shadowRadius: 16,
elevation: 2,
},
socialButtonPressed: {
backgroundColor: "#F4F7FF",
},
socialButtonDisabled: {
opacity: 0.7,
},
socialButtonContent: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
gap: 12,
},
socialIconContainer: {
justifyContent: "center",
alignItems: "center",
width: 28,
height: 28,
},
socialButtonText: {
flex: 1,
textAlign: "center",
fontSize: 15,
color: "#202124",
fontFamily: FONT_FAMILY.InterSemiBold,
},
socialRightSpacer: {
width: 24,
height: 24,
},
nativeButtonWrapper: {
alignSelf: "center",
width: "90%",
height: 50,
justifyContent: "center",
},
nativeButton: {
width: "100%",
height: 50,
},
nativeLoadingOverlay: {
...StyleSheet.absoluteFillObject,
alignItems: "center",
justifyContent: "center",
},
});