299 lines
7.5 KiB
JavaScript
299 lines
7.5 KiB
JavaScript
import * as ImagePicker from 'expo-image-picker'
|
|
import { Pressable, Text } from 'react-native'
|
|
import useMinuit from 'react-native-minuit/src/hooks/useMinuit.js'
|
|
import React, { useGlobal } from 'reactn'
|
|
|
|
import { responsiveWidth } from '../actions/responsiveSizes.js'
|
|
import Page from '../layouts/Page'
|
|
|
|
import alert from '../components/Alert.js'
|
|
import Avatar from '../components/Avatar'
|
|
import InputRow from '../components/InputRow'
|
|
import ItemRowList from '../components/ItemRowList.js'
|
|
|
|
import firebase, { usersRef } from '../config/firebase'
|
|
|
|
import { uploadFileToFirebase } from '../helpers/uploadToFirebase'
|
|
import { Routes } from '../navigation/Routes.js'
|
|
import { Fonts, gutters, Palette, Style } from '../styles'
|
|
|
|
import { useUserData } from '../providers/UserDataProvider.js'
|
|
|
|
export default ({ navigation }) => {
|
|
const { setIsLoading, setTooltip } = useMinuit()
|
|
const { onSignOut } = useUserData()
|
|
|
|
const [currentUID] = useGlobal('currentUID')
|
|
const [currentUserData] = useGlobal('currentUserData')
|
|
|
|
const settingsList = [
|
|
{
|
|
title: 'Nom du compte',
|
|
key: 'name',
|
|
value: currentUserData?.name || '',
|
|
type: 'string',
|
|
},
|
|
{
|
|
title: 'Adresse email',
|
|
key: 'email',
|
|
value: currentUserData?.email || '',
|
|
type: 'string',
|
|
},
|
|
{
|
|
title: 'Mot de passe',
|
|
key: 'password',
|
|
value: '',
|
|
type: 'string',
|
|
},
|
|
{
|
|
title: 'Notifications push',
|
|
key: 'notifications',
|
|
value: !!currentUserData?.notifications,
|
|
type: 'boolean',
|
|
},
|
|
{
|
|
title: 'Notifications par email',
|
|
key: 'emailNotifications',
|
|
value: !!currentUserData?.emailNotifications,
|
|
type: 'boolean',
|
|
},
|
|
{
|
|
title: 'Langue',
|
|
key: 'language',
|
|
value: currentUserData?.language || '',
|
|
type: 'string',
|
|
},
|
|
]
|
|
|
|
const destructiveSettingsList = [
|
|
{
|
|
title: 'Supprimer mon compte',
|
|
action: () => onDeleteUserAccount(),
|
|
textStyle: {
|
|
color: Palette.red,
|
|
},
|
|
},
|
|
].filter(({ condition = true }) => condition)
|
|
|
|
const onChangePicture = async () => {
|
|
try {
|
|
setIsLoading(true)
|
|
|
|
let result = await ImagePicker.launchImageLibraryAsync({
|
|
mediaTypes: ImagePicker.MediaTypeOptions.Images,
|
|
allowsEditing: true,
|
|
aspect: [4, 4],
|
|
quality: 1,
|
|
})
|
|
|
|
if (result?.assets?.[0]?.uri) {
|
|
const { resultURI = null } = await uploadFileToFirebase({
|
|
uri: result?.assets?.[0]?.uri,
|
|
path: `users/${currentUID}/profilePicture.png`,
|
|
})
|
|
|
|
if (resultURI) {
|
|
await usersRef.doc(currentUID).update({
|
|
profilePictureURL: resultURI,
|
|
})
|
|
|
|
await firebase.auth().currentUser.updateProfile({
|
|
photoURL: resultURI,
|
|
})
|
|
|
|
setTooltip({
|
|
type: 'success',
|
|
text: 'Photo de profil mise à jour',
|
|
})
|
|
} else {
|
|
throw new Error('Erreur changement photo de profil')
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.log(error)
|
|
|
|
setTooltip({
|
|
type: 'error',
|
|
text: error.message,
|
|
})
|
|
} finally {
|
|
setIsLoading(false)
|
|
}
|
|
}
|
|
|
|
const onUpdateValue = async ({ key, value = null, currentPassword = null }) => {
|
|
try {
|
|
setIsLoading(true)
|
|
const user = firebase.auth().currentUser
|
|
|
|
const reauthenticateUser = async () => {
|
|
try {
|
|
const credential = firebase.auth.EmailAuthProvider.credential(
|
|
user?.email,
|
|
currentPassword
|
|
)
|
|
|
|
await user.reauthenticateWithCredential(credential)
|
|
} catch (error) {
|
|
throw new Error('Erreur authentification')
|
|
}
|
|
}
|
|
|
|
// Validate input except for booleans where false is allowed
|
|
const isInvalidString = typeof value === 'string' && value.trim().length === 0
|
|
const isNullish = value === null || value === undefined
|
|
if (isNullish || isInvalidString) {
|
|
throw new Error('Vérifiez les informations saisies')
|
|
}
|
|
|
|
if (key === 'name') {
|
|
await user.updateProfile({
|
|
displayName: value,
|
|
})
|
|
}
|
|
|
|
if (['email', 'password'].includes(key)) {
|
|
await reauthenticateUser()
|
|
|
|
if (key === 'email') {
|
|
try {
|
|
await user.updateEmail(value)
|
|
} catch (e) {
|
|
throw new Error('Erreur changement email')
|
|
}
|
|
}
|
|
|
|
if (key === 'password') {
|
|
try {
|
|
await user.updatePassword(value)
|
|
} catch (e) {
|
|
throw new Error('Erreur changement mot de passe')
|
|
}
|
|
}
|
|
}
|
|
|
|
if (key !== 'password') {
|
|
await usersRef.doc(currentUID).update({
|
|
[key]: value,
|
|
})
|
|
}
|
|
|
|
setTooltip({
|
|
type: 'success',
|
|
text: 'Modifications enregistrées',
|
|
})
|
|
} catch (error) {
|
|
console.log(error)
|
|
|
|
setTooltip({
|
|
type: 'error',
|
|
text: error.message,
|
|
})
|
|
} finally {
|
|
setIsLoading(false)
|
|
}
|
|
}
|
|
|
|
const onDeleteUserAccount = async () => {
|
|
alert(
|
|
'Êtes-vous sûr?',
|
|
'La suppression de votre compte entraînera la suppression de toutes les données liées.',
|
|
[
|
|
{
|
|
text: 'Annuler',
|
|
onPress: () => {},
|
|
style: 'cancel',
|
|
},
|
|
{
|
|
text: 'Confirmer',
|
|
onPress: async () => {
|
|
try {
|
|
setIsLoading(true)
|
|
|
|
await firebase.functions().httpsCallable('users-deleteUserAccount')()
|
|
|
|
await onSignOut()
|
|
|
|
setTooltip({
|
|
type: 'success',
|
|
text: 'Compte supprimé avec succès!',
|
|
})
|
|
|
|
navigation.reset({
|
|
index: 0,
|
|
routes: [
|
|
{
|
|
name: Routes.Login,
|
|
},
|
|
],
|
|
})
|
|
} catch (error) {
|
|
setTooltip({
|
|
type: 'error',
|
|
text: error.message,
|
|
})
|
|
} finally {
|
|
setIsLoading(false)
|
|
}
|
|
},
|
|
style: 'confirm',
|
|
},
|
|
],
|
|
{ cancelable: false }
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Page headerType="NAVIGATE" title={'Paramètres du compte'} scrollEnabled>
|
|
<Pressable
|
|
onPress={onChangePicture}
|
|
style={[Style.containerCenter, { marginBottom: gutters }]}
|
|
>
|
|
<Avatar
|
|
name={currentUserData?.name}
|
|
url={currentUserData?.profilePictureURL || null}
|
|
forceRawImage
|
|
size={responsiveWidth(30)}
|
|
containerStyle={{
|
|
marginBottom: gutters / 2,
|
|
...Style.defaultShadows,
|
|
}}
|
|
/>
|
|
<Text
|
|
style={Fonts({
|
|
type: 'section',
|
|
style: { color: Palette.primary, textDecorationLine: 'underline' },
|
|
})}
|
|
>
|
|
Modifier
|
|
</Text>
|
|
</Pressable>
|
|
|
|
{settingsList.map((setting) => {
|
|
const { title, key, value, type } = setting
|
|
|
|
return (
|
|
<InputRow
|
|
key={key}
|
|
itemKey={key}
|
|
value={value}
|
|
type={type}
|
|
title={title}
|
|
onUpdateValue={onUpdateValue}
|
|
/>
|
|
)
|
|
})}
|
|
|
|
<ItemRowList
|
|
title={'Gérer mon abonnement'}
|
|
action={() => navigation.navigate(Routes.ManageSubscription)}
|
|
containerStyle={{}}
|
|
/>
|
|
|
|
{destructiveSettingsList.map((setting, index) => (
|
|
<ItemRowList key={index} {...setting} containerStyle={{}} />
|
|
))}
|
|
</Page>
|
|
)
|
|
}
|