522 lines
20 KiB
JavaScript
522 lines
20 KiB
JavaScript
import { useRoute } from '@react-navigation/native'
|
|
import React, { useState } from 'react'
|
|
import { Modal, Pressable, ScrollView, Text, View } from 'react-native'
|
|
import { responsiveHeight } from 'react-native-responsive-dimensions'
|
|
import { useGlobal } from 'reactn'
|
|
import { background } from '../assets'
|
|
import BorderGradientButton from '../components/BorderGradientButton'
|
|
import GradientButton from '../components/GradientButton'
|
|
import { Input } from '../components/Input'
|
|
import ItemContainer from '../components/ItemContainer/ItemContainer'
|
|
import { checkIfPasswordIsStrongEnough, handleFirebaseError } from '../actions/signupActions'
|
|
import firebase, { usersRef } from '../config/firebase'
|
|
import Page from '../layouts/Page'
|
|
import { isWeb } from '../hooks/useLayoutType'
|
|
import { Routes } from '../navigation'
|
|
import { reset } from '../navigation/NavigationService'
|
|
import { Palette } from '../styles'
|
|
import { FONT_FAMILY } from '../styles/Fonts'
|
|
|
|
const CreatePassword = () => {
|
|
const route = useRoute()
|
|
const email = route?.params?.email || ''
|
|
const firstName = route?.params?.firstName || ''
|
|
const lastName = route?.params?.lastName || ''
|
|
const city = route?.params?.city || ''
|
|
const country = route?.params?.country || null
|
|
const preferredLanguage = route?.params?.preferredLanguage || null
|
|
const birthDate = route?.params?.birthDate || null
|
|
const [password, setPassword] = useState('')
|
|
const [passwordError, setPasswordError] = useState('')
|
|
const [loading, setLoading] = useState(false)
|
|
const [isCguAccepted, setIsCguAccepted] = useState(false)
|
|
const [isCguModalVisible, setIsCguModalVisible] = useState(false)
|
|
const [hasScrolledCguToEnd, setHasScrolledCguToEnd] = useState(false)
|
|
const [, setTooltip] = useGlobal('_tooltip')
|
|
|
|
const handlePasswordChange = (text) => {
|
|
setPassword(text)
|
|
if (!text) {
|
|
setPasswordError('')
|
|
return
|
|
}
|
|
|
|
if (!checkIfPasswordIsStrongEnough({ password: text })) {
|
|
setPasswordError(
|
|
'Le mot de passe doit contenir au moins une majuscule, une minuscule, un chiffre et avoir une longueur minimale de 6 caractères'
|
|
)
|
|
} else {
|
|
setPasswordError('')
|
|
}
|
|
}
|
|
|
|
const isPasswordValid = checkIfPasswordIsStrongEnough({ password })
|
|
|
|
const handleToggleCguAccepted = () => {
|
|
setIsCguAccepted((prev) => !prev)
|
|
}
|
|
|
|
const handleOpenCguModal = () => {
|
|
setHasScrolledCguToEnd(false)
|
|
setIsCguModalVisible(true)
|
|
}
|
|
|
|
const handleCloseCguModal = () => {
|
|
setIsCguModalVisible(false)
|
|
setHasScrolledCguToEnd(false)
|
|
}
|
|
|
|
const handleCguScroll = ({ nativeEvent }) => {
|
|
const { layoutMeasurement, contentOffset, contentSize } = nativeEvent
|
|
const paddingToBottom = 20
|
|
const contentFits = contentSize.height <= layoutMeasurement.height + 1
|
|
const isAtEnd =
|
|
layoutMeasurement.height + contentOffset.y >= contentSize.height - paddingToBottom
|
|
if (isAtEnd) {
|
|
setHasScrolledCguToEnd(true)
|
|
} else if (contentFits) {
|
|
setHasScrolledCguToEnd(true)
|
|
}
|
|
}
|
|
|
|
const onCreateAccount = async () => {
|
|
try {
|
|
if (!isPasswordValid) {
|
|
setTooltip({
|
|
text: 'Le mot de passe doit contenir au moins une majuscule, une minuscule, un chiffre et avoir une longueur minimale de 6 caractères',
|
|
type: 'error',
|
|
})
|
|
return
|
|
}
|
|
|
|
if (!isCguAccepted) {
|
|
setTooltip({
|
|
text: 'Tu dois accepter les CGU pour continuer',
|
|
type: 'error',
|
|
})
|
|
return
|
|
}
|
|
|
|
setLoading(true)
|
|
const cred = await firebase.auth().createUserWithEmailAndPassword(email.trim(), password)
|
|
const uid = cred?.user?.uid || firebase.auth().currentUser?.uid
|
|
if (!uid) throw new Error('Création de compte échouée')
|
|
const trimmedFirstName = typeof firstName === 'string' ? firstName.trim() : ''
|
|
const trimmedLastName = typeof lastName === 'string' ? lastName.trim() : ''
|
|
const trimmedCity = typeof city === 'string' ? city.trim() : ''
|
|
await usersRef.doc(uid).set(
|
|
{
|
|
email: email.trim(),
|
|
emailNotifications: true,
|
|
...(trimmedFirstName ? { firstName: trimmedFirstName } : {}),
|
|
...(trimmedLastName ? { lastName: trimmedLastName } : {}),
|
|
...(trimmedCity ? { city: trimmedCity } : {}),
|
|
...(preferredLanguage ? { preferredLanguage } : {}),
|
|
...(birthDate ? { birthDate } : {}),
|
|
...(country?.code ? { countryCode: country.code } : {}),
|
|
...(country?.name ? { countryName: country.name } : {}),
|
|
registrationFlowRequired: true,
|
|
createdAt: firebase.firestore.FieldValue.serverTimestamp(),
|
|
updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
|
|
},
|
|
{ merge: true }
|
|
)
|
|
setTooltip({ text: 'Compte créé, continuons', type: 'success' })
|
|
reset({ index: 0, routes: [{ name: Routes.RegistrationChoice }] })
|
|
} catch (e) {
|
|
console.log('Register error', e?.message)
|
|
const message =
|
|
e?.code && e.code.startsWith('auth/')
|
|
? handleFirebaseError(e.code)
|
|
: e?.message || 'Création impossible'
|
|
setTooltip({ text: message, type: 'error' })
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Page
|
|
width={isWeb ? 600 : null}
|
|
backgroundImg={isWeb ? background.loginBgWeb : background.homeBG}
|
|
headerType="NAVIGATION"
|
|
title="Inscription"
|
|
>
|
|
<View
|
|
style={{
|
|
flex: 1,
|
|
paddingVertical: 20,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
}}
|
|
>
|
|
<ItemContainer
|
|
height={isWeb ? 360 : responsiveHeight(65)}
|
|
disableKeyboardHeight
|
|
style={{ width: '100%' }}
|
|
>
|
|
<View style={{ gap: 32, paddingTop: 5, paddingHorizontal: 5 }}>
|
|
<View style={{ gap: 16 }}>
|
|
<View style={{ gap: 2 }}>
|
|
<Text
|
|
style={{
|
|
fontSize: 22,
|
|
color: Palette.white,
|
|
fontFamily: FONT_FAMILY.InterSemiBold,
|
|
}}
|
|
>
|
|
Choisis un mot de passe{'\n'}sécurisé
|
|
</Text>
|
|
<Text
|
|
style={{
|
|
fontSize: 14,
|
|
color: Palette.gray,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
}}
|
|
>
|
|
Utilise au moins 6 caractères pour sécuriser ton compte.
|
|
</Text>
|
|
</View>
|
|
<Input
|
|
placeholder="Mot de passe"
|
|
label="Mot de passe"
|
|
isBlur
|
|
type="password"
|
|
value={password}
|
|
setValue={handlePasswordChange}
|
|
/>
|
|
{passwordError ? (
|
|
<Text
|
|
style={{
|
|
fontSize: 12,
|
|
color: Palette.red,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
}}
|
|
>
|
|
{passwordError}
|
|
</Text>
|
|
) : null}
|
|
</View>
|
|
<View style={{ gap: 12 }}>
|
|
<View
|
|
style={{
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
gap: 8,
|
|
flexWrap: 'wrap',
|
|
}}
|
|
>
|
|
<Pressable
|
|
onPress={handleToggleCguAccepted}
|
|
style={{
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
gap: 8,
|
|
}}
|
|
>
|
|
<View
|
|
style={{
|
|
width: 17,
|
|
height: 17,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
borderWidth: 1,
|
|
borderRadius: 100,
|
|
borderColor: Palette.white,
|
|
}}
|
|
>
|
|
{isCguAccepted ? (
|
|
<View
|
|
style={{
|
|
width: 9,
|
|
height: 9,
|
|
borderRadius: 100,
|
|
backgroundColor: Palette.white,
|
|
}}
|
|
/>
|
|
) : null}
|
|
</View>
|
|
<Text
|
|
style={{
|
|
fontSize: 14,
|
|
color: Palette.white,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
}}
|
|
>
|
|
J'accepte les
|
|
</Text>
|
|
</Pressable>
|
|
<Pressable onPress={handleOpenCguModal}>
|
|
<Text
|
|
style={{
|
|
fontSize: 14,
|
|
color: Palette.white,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
textDecorationLine: 'underline',
|
|
}}
|
|
>
|
|
CGU
|
|
</Text>
|
|
</Pressable>
|
|
</View>
|
|
</View>
|
|
<GradientButton
|
|
title={loading ? 'Création...' : 'Créer mon compte'}
|
|
containerStyle={{
|
|
width: '80%',
|
|
alignSelf: 'center',
|
|
}}
|
|
onPress={onCreateAccount}
|
|
disabled={loading || !email || !isPasswordValid || !isCguAccepted}
|
|
/>
|
|
</View>
|
|
</ItemContainer>
|
|
</View>
|
|
<Modal
|
|
animationType="slide"
|
|
visible={isCguModalVisible}
|
|
transparent
|
|
onRequestClose={handleCloseCguModal}
|
|
>
|
|
<View
|
|
style={{
|
|
flex: 1,
|
|
backgroundColor: Palette.transparentBlack,
|
|
justifyContent: 'center',
|
|
paddingHorizontal: 20,
|
|
paddingVertical: 40,
|
|
alignItems: 'center',
|
|
}}
|
|
>
|
|
<View
|
|
style={{
|
|
backgroundColor: Palette.darkPurple,
|
|
borderRadius: 16,
|
|
padding: 20,
|
|
paddingTop: 28,
|
|
maxHeight: '75%',
|
|
width: '90%',
|
|
flexShrink: 1,
|
|
}}
|
|
>
|
|
<Pressable
|
|
onPress={handleCloseCguModal}
|
|
style={{
|
|
position: 'absolute',
|
|
top: 12,
|
|
right: 12,
|
|
padding: 6,
|
|
zIndex: 2,
|
|
}}
|
|
>
|
|
<Text
|
|
style={{
|
|
fontSize: 16,
|
|
color: Palette.gray,
|
|
fontFamily: FONT_FAMILY.InterSemiBold,
|
|
}}
|
|
>
|
|
X
|
|
</Text>
|
|
</Pressable>
|
|
<View style={{ gap: 16, flex: 1 }}>
|
|
<Text
|
|
style={{
|
|
fontSize: 20,
|
|
color: Palette.white,
|
|
fontFamily: FONT_FAMILY.InterSemiBold,
|
|
textAlign: 'center',
|
|
}}
|
|
>
|
|
Conditions Générales d'Utilisation
|
|
</Text>
|
|
<ScrollView
|
|
showsVerticalScrollIndicator={false}
|
|
contentContainerStyle={{ gap: 16, paddingBottom: 12 }}
|
|
onScroll={handleCguScroll}
|
|
onMomentumScrollEnd={handleCguScroll}
|
|
scrollEventThrottle={16}
|
|
style={{ flex: 1 }}
|
|
>
|
|
<Text
|
|
style={{
|
|
fontSize: 14,
|
|
color: Palette.gray,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
lineHeight: 20,
|
|
}}
|
|
>
|
|
Cupidatat incididunt aute aute velit deserunt labore excepteur eu velit cillum
|
|
est. Laboris in sunt ea Lorem culpa velit nisi ad elit esse voluptate id
|
|
adipisicing nulla magna. Duis qui fugiat consequat elit velit aute ad.
|
|
Reprehenderit proident duis exercitation velit proident aute minim. Anim
|
|
reprehenderit mollit consectetur id sint adipisicing pariatur tempor sit pariatur
|
|
proident nostrud. Sit culpa tempor enim ut consectetur sunt aute est reprehenderit
|
|
incididunt incididunt in ullamco consectetur. Eiusmod non incididunt proident
|
|
eiusmod. Esse Lorem ut amet in est id aute consectetur.
|
|
</Text>
|
|
<Text
|
|
style={{
|
|
fontSize: 14,
|
|
color: Palette.gray,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
lineHeight: 20,
|
|
}}
|
|
>
|
|
Aliqua est sint consectetur occaecat exercitation. Elit nisi velit ad qui eiusmod
|
|
reprehenderit proident labore nostrud labore consequat enim fugiat non. Eiusmod
|
|
occaecat pariatur deserunt velit elit sint irure fugiat excepteur labore ad velit
|
|
ex deserunt laborum. Aliqua excepteur reprehenderit nostrud aliqua pariatur aliqua
|
|
excepteur Lorem consectetur. Ut est culpa ullamco ipsum Lorem ullamco ea labore
|
|
anim.
|
|
</Text>
|
|
<Text
|
|
style={{
|
|
fontSize: 14,
|
|
color: Palette.gray,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
lineHeight: 20,
|
|
}}
|
|
>
|
|
Et ut ex duis tempor amet aliquip cupidatat sit sit. Aliqua consectetur amet duis
|
|
fugiat nulla duis culpa exercitation reprehenderit. Ea voluptate proident ad elit
|
|
pariatur do. Culpa incididunt deserunt dolor ut officia aliquip ut occaecat
|
|
eiusmod sint veniam. Deserunt consequat adipisicing aliquip velit labore fugiat
|
|
aute culpa id sint. Adipisicing eu commodo ex do aliqua in labore laboris sit sunt
|
|
adipisicing excepteur. Do sint velit veniam pariatur consequat proident cupidatat
|
|
in incididunt ullamco.
|
|
</Text>
|
|
<Text
|
|
style={{
|
|
fontSize: 14,
|
|
color: Palette.gray,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
lineHeight: 20,
|
|
}}
|
|
>
|
|
Culpa eu cillum fugiat elit eiusmod enim. Cupidatat culpa aliquip culpa et tempor
|
|
est velit. Aute id deserunt non ut minim deserunt adipisicing sit veniam eu id
|
|
incididunt adipisicing dolore. Eiusmod nisi excepteur est voluptate consequat
|
|
reprehenderit non exercitation commodo aute.
|
|
</Text>
|
|
<Text
|
|
style={{
|
|
fontSize: 14,
|
|
color: Palette.gray,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
lineHeight: 20,
|
|
}}
|
|
>
|
|
Eu culpa enim dolore anim ipsum eu veniam mollit dolore officia cupidatat laborum
|
|
officia do. Ad proident in anim nisi exercitation consequat exercitation occaecat
|
|
consequat ut laborum esse consectetur ullamco. Enim elit sit in id velit quis
|
|
nostrud nostrud eu labore aute reprehenderit voluptate deserunt. Minim voluptate
|
|
et duis voluptate enim duis.
|
|
</Text>
|
|
<Text
|
|
style={{
|
|
fontSize: 14,
|
|
color: Palette.gray,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
lineHeight: 20,
|
|
}}
|
|
>
|
|
Minim laboris deserunt minim ex. Duis aliquip cillum proident. Magna velit nisi
|
|
fugiat. Non id proident pariatur elit in exercitation et amet id qui ad laborum
|
|
nulla ullamco ea.
|
|
</Text>
|
|
<Text
|
|
style={{
|
|
fontSize: 14,
|
|
color: Palette.gray,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
lineHeight: 20,
|
|
}}
|
|
>
|
|
Cillum nisi aute dolore culpa est veniam cupidatat sunt sint ipsum. Amet ullamco
|
|
minim non voluptate cillum dolore sunt irure nulla pariatur excepteur voluptate
|
|
id. Commodo ullamco aliqua non ea mollit ullamco do minim dolor magna. Ipsum eu
|
|
minim quis laborum do dolore labore eiusmod et. Ullamco officia velit anim.
|
|
Exercitation voluptate reprehenderit ex et do eu fugiat tempor do cillum ad.
|
|
</Text>
|
|
<Text
|
|
style={{
|
|
fontSize: 14,
|
|
color: Palette.gray,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
lineHeight: 20,
|
|
}}
|
|
>
|
|
Cupidatat consectetur excepteur commodo laborum incididunt laboris minim dolore ut
|
|
ipsum dolor ullamco culpa aliquip. Cillum proident quis consectetur voluptate
|
|
labore nisi Lorem pariatur in esse. Amet ipsum mollit officia fugiat Lorem ipsum
|
|
elit officia. Esse reprehenderit magna quis irure sit consectetur dolore sunt
|
|
mollit aliquip eiusmod voluptate amet. Ex irure culpa ea cupidatat nulla ea labore
|
|
aute occaecat consequat consectetur cillum amet. Velit ad do occaecat non elit
|
|
quis. Amet id reprehenderit ullamco amet tempor deserunt exercitation elit
|
|
consectetur minim aliqua. Cillum do aliquip do ea ipsum veniam deserunt in ipsum
|
|
pariatur nisi proident et ut deserunt.
|
|
</Text>
|
|
<Text
|
|
style={{
|
|
fontSize: 14,
|
|
color: Palette.gray,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
lineHeight: 20,
|
|
}}
|
|
>
|
|
Mollit et adipisicing velit tempor deserunt excepteur fugiat eiusmod adipisicing.
|
|
Tempor do ex duis dolor deserunt cillum officia est nisi mollit fugiat. Amet duis
|
|
ea laboris officia aliquip id sint voluptate consectetur velit elit reprehenderit
|
|
nostrud exercitation. Ea dolore adipisicing nulla incididunt laboris sint commodo
|
|
non mollit eiusmod. Tempor nulla eu laborum tempor veniam laboris consequat non
|
|
consequat exercitation pariatur velit. Voluptate magna mollit esse incididunt id.
|
|
Pariatur eu irure esse ullamco fugiat culpa.
|
|
</Text>
|
|
<Text
|
|
style={{
|
|
fontSize: 14,
|
|
color: Palette.gray,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
lineHeight: 20,
|
|
}}
|
|
>
|
|
Sint dolore aliqua pariatur do mollit occaecat deserunt qui proident non
|
|
exercitation mollit cillum culpa. Est cupidatat consequat ea commodo laborum
|
|
labore sunt excepteur labore aute est amet anim. Tempor deserunt labore mollit
|
|
enim officia aliqua occaecat. Ullamco mollit qui mollit do ex irure enim.
|
|
</Text>
|
|
</ScrollView>
|
|
{hasScrolledCguToEnd ? (
|
|
<View style={{ gap: 10 }}>
|
|
<GradientButton
|
|
title="Accepter sans réserve"
|
|
onPress={() => {
|
|
setIsCguAccepted(true)
|
|
handleCloseCguModal()
|
|
}}
|
|
/>
|
|
<BorderGradientButton title="Refuser" onPress={handleCloseCguModal} />
|
|
</View>
|
|
) : (
|
|
<Text
|
|
style={{
|
|
fontSize: 12,
|
|
color: Palette.gray,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
textAlign: 'center',
|
|
}}
|
|
>
|
|
Fais défiler jusqu'en bas pour afficher les actions
|
|
</Text>
|
|
)}
|
|
</View>
|
|
</View>
|
|
</View>
|
|
</Modal>
|
|
</Page>
|
|
)
|
|
}
|
|
|
|
export default CreatePassword
|