new register
This commit is contained in:
+292
-58
@@ -1,9 +1,19 @@
|
||||
import React, { useState } from "react";
|
||||
import { Pressable, Text, View } from "react-native";
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import {
|
||||
FlatList,
|
||||
Modal,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { background } from "../assets";
|
||||
import BorderGradientButton from "../components/BorderGradientButton";
|
||||
import { Input } from "../components/Input";
|
||||
import ItemContainer from "../components/ItemContainer/ItemContainer";
|
||||
import COUNTRIES from "../constants/countries";
|
||||
import { isWeb } from "../hooks/useLayoutType";
|
||||
import Page from "../layouts/Page";
|
||||
import { Routes } from "../navigation";
|
||||
@@ -11,8 +21,55 @@ import { navigate } 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 [lastName, setLastName] = useState("");
|
||||
const [selectedCountry, setSelectedCountry] = useState(null);
|
||||
const [countrySearch, setCountrySearch] = useState("");
|
||||
const [isCountryModalVisible, setIsCountryModalVisible] = useState(false);
|
||||
const [preferredLanguage, setPreferredLanguage] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
AsyncStorage.getItem(LANGUAGE_STORAGE_KEY)
|
||||
.then((storedLanguage) => {
|
||||
if (storedLanguage) {
|
||||
setPreferredLanguage(storedLanguage);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn("Register: failed to load preferred language", error);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const filteredCountries = useMemo(() => {
|
||||
const query = countrySearch.trim().toLowerCase();
|
||||
if (!query) {
|
||||
return COUNTRIES;
|
||||
}
|
||||
return COUNTRIES.filter((country) =>
|
||||
country.name.toLowerCase().includes(query)
|
||||
);
|
||||
}, [countrySearch]);
|
||||
|
||||
const isFormValid =
|
||||
email.trim().length > 0 &&
|
||||
firstName.trim().length > 0 &&
|
||||
lastName.trim().length > 0 &&
|
||||
selectedCountry;
|
||||
|
||||
const handleSelectCountry = (country) => {
|
||||
setSelectedCountry(country);
|
||||
setIsCountryModalVisible(false);
|
||||
setCountrySearch("");
|
||||
};
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setIsCountryModalVisible(false);
|
||||
setCountrySearch("");
|
||||
};
|
||||
|
||||
return (
|
||||
<Page
|
||||
@@ -21,82 +78,259 @@ const Register = () => {
|
||||
headerType="NAVIGATION"
|
||||
title="Inscription"
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<ItemContainer height={360} disableKeyboardHeight>
|
||||
<View style={{ gap: 32, paddingTop: 5, paddingHorizontal: 5 }}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 22,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterSemiBold,
|
||||
}}
|
||||
>
|
||||
Saisis ton adresse mail pour commencer
|
||||
</Text>
|
||||
<Input
|
||||
placeholder="Adresse mail"
|
||||
label="Adresse mail"
|
||||
isBlur
|
||||
type="email"
|
||||
value={email}
|
||||
setValue={setEmail}
|
||||
/>
|
||||
<View style={styles.pageContent}>
|
||||
<ItemContainer height={520} disableKeyboardHeight>
|
||||
<View style={styles.formContent}>
|
||||
<Text style={styles.title}>Renseigne tes informations</Text>
|
||||
{preferredLanguage && (
|
||||
<Text style={styles.languageInfo}>
|
||||
Langue choisie :{" "}
|
||||
<Text style={styles.languageInfoValue}>
|
||||
{preferredLanguage === "fr" ? "Français" : "English"}
|
||||
</Text>
|
||||
</Text>
|
||||
)}
|
||||
<View style={{ gap: 16 }}>
|
||||
<View style={{ gap: 12 }}>
|
||||
<Input
|
||||
placeholder="Prénom"
|
||||
label="Prénom"
|
||||
isBlur
|
||||
value={firstName}
|
||||
setValue={setFirstName}
|
||||
/>
|
||||
<Input
|
||||
placeholder="Nom"
|
||||
label="Nom"
|
||||
isBlur
|
||||
value={lastName}
|
||||
setValue={setLastName}
|
||||
/>
|
||||
<Pressable
|
||||
style={[
|
||||
styles.countryButton,
|
||||
selectedCountry ? styles.countryButtonFilled : null,
|
||||
]}
|
||||
onPress={() => setIsCountryModalVisible(true)}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
styles.countryButtonText,
|
||||
!selectedCountry && styles.countryButtonPlaceholder,
|
||||
]}
|
||||
>
|
||||
{selectedCountry
|
||||
? selectedCountry.name
|
||||
: "Choisis ton pays"}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
<Input
|
||||
placeholder="Adresse mail"
|
||||
label="Adresse mail"
|
||||
isBlur
|
||||
type="email"
|
||||
value={email}
|
||||
setValue={setEmail}
|
||||
/>
|
||||
</View>
|
||||
<BorderGradientButton
|
||||
title="Créer mon compte"
|
||||
containerStyle={{
|
||||
width: "80%",
|
||||
alignSelf: "center",
|
||||
}}
|
||||
onPress={() => navigate(Routes.CreatePassword, { email })}
|
||||
disabled={!email}
|
||||
onPress={() =>
|
||||
navigate(Routes.CreatePassword, {
|
||||
email: email.trim(),
|
||||
firstName: firstName.trim(),
|
||||
lastName: lastName.trim(),
|
||||
country: selectedCountry,
|
||||
preferredLanguage,
|
||||
})
|
||||
}
|
||||
disabled={!isFormValid}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
alignItems: "center",
|
||||
gap: 4,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 12,
|
||||
color: Palette.gray,
|
||||
fontFamily: FONT_FAMILY.HelveticaNeueRegular,
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
<View style={styles.footer}>
|
||||
<Text style={styles.terms}>
|
||||
En t’inscrivant, tu acceptes nos conditions générales{"\n"}
|
||||
d’utilisation et notre politique de confidentialité.
|
||||
</Text>
|
||||
<Pressable onPress={() => navigate(Routes.Login)}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 14,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.HelveticaNeueRegular,
|
||||
}}
|
||||
>
|
||||
<Text style={styles.loginText}>
|
||||
Tu as déjà un compte?{" "}
|
||||
<Text
|
||||
style={{
|
||||
fontFamily: FONT_FAMILY.InterSemiBold,
|
||||
}}
|
||||
>
|
||||
Se connecter
|
||||
</Text>
|
||||
<Text style={styles.loginLink}>Se connecter</Text>
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
</ItemContainer>
|
||||
</View>
|
||||
<Modal
|
||||
transparent
|
||||
visible={isCountryModalVisible}
|
||||
animationType="fade"
|
||||
onRequestClose={handleCloseModal}
|
||||
>
|
||||
<View style={styles.modalOverlay}>
|
||||
<View style={styles.modalContainer}>
|
||||
<View style={styles.modalHeader}>
|
||||
<Text style={styles.modalTitle}>Choisis ton pays</Text>
|
||||
<Pressable onPress={handleCloseModal}>
|
||||
<Text style={styles.closeText}>Fermer</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
<TextInput
|
||||
value={countrySearch}
|
||||
onChangeText={setCountrySearch}
|
||||
placeholder="Rechercher un pays"
|
||||
placeholderTextColor={Palette.gray}
|
||||
style={styles.searchInput}
|
||||
/>
|
||||
<FlatList
|
||||
data={filteredCountries}
|
||||
keyExtractor={(item) => item.code}
|
||||
renderItem={({ item }) => (
|
||||
<Pressable
|
||||
style={styles.countryItem}
|
||||
onPress={() => handleSelectCountry(item)}
|
||||
>
|
||||
<Text style={styles.countryItemText}>{item.name}</Text>
|
||||
</Pressable>
|
||||
)}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
showsVerticalScrollIndicator={false}
|
||||
ListEmptyComponent={
|
||||
<Text style={styles.emptyListText}>Aucun pays trouvé</Text>
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
export default Register;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
pageContent: {
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
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,
|
||||
},
|
||||
countryButton: {
|
||||
borderRadius: 12,
|
||||
borderWidth: 1,
|
||||
borderColor: Palette.ultraLightWhite,
|
||||
backgroundColor: Palette.glass,
|
||||
minHeight: 50,
|
||||
justifyContent: "center",
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
countryButtonFilled: {
|
||||
borderColor: Palette.primary,
|
||||
},
|
||||
countryButtonText: {
|
||||
fontSize: 14,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
},
|
||||
countryButtonPlaceholder: {
|
||||
color: Palette.gray,
|
||||
},
|
||||
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,
|
||||
},
|
||||
modalOverlay: {
|
||||
flex: 1,
|
||||
backgroundColor: Palette.transparentBlack,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
padding: 16,
|
||||
},
|
||||
modalContainer: {
|
||||
width: "100%",
|
||||
maxWidth: 420,
|
||||
maxHeight: "80%",
|
||||
backgroundColor: Palette.darkPurple,
|
||||
borderRadius: 20,
|
||||
padding: 16,
|
||||
gap: 12,
|
||||
},
|
||||
modalHeader: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
modalTitle: {
|
||||
fontSize: 18,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterSemiBold,
|
||||
},
|
||||
closeText: {
|
||||
fontSize: 14,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
},
|
||||
searchInput: {
|
||||
borderRadius: 12,
|
||||
borderWidth: 1,
|
||||
borderColor: Palette.ultraLightWhite,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 10,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
},
|
||||
countryItem: {
|
||||
paddingVertical: 12,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: Palette.ultraLightWhite,
|
||||
},
|
||||
countryItemText: {
|
||||
fontSize: 14,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
},
|
||||
emptyListText: {
|
||||
fontSize: 14,
|
||||
color: Palette.gray,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
textAlign: "center",
|
||||
paddingVertical: 20,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user