import { useRoute } from '@react-navigation/native'
import React, { useEffect, useMemo, useState, useGlobal } from 'reactn'
import { Text, View } from 'react-native'
import { checkIfPasswordIsStrongEnough, handleFirebaseError } from '../actions/signupActions'
import { background } from '../assets'
import GradientButton from '../components/GradientButton'
import { Input } from '../components/Input'
import ItemContainer from '../components/ItemContainer/ItemContainer'
import firebase from '../config/firebase'
import Page from '../layouts/Page'
import { isWeb } from '../hooks/useLayoutType'
import { Routes } from '../navigation'
import { navigate } from '../navigation/NavigationService'
import { Palette } from '../styles'
import { FONT_FAMILY } from '../styles/Fonts'
const PASSWORD_ERROR_MESSAGE =
'Ton mot de passe doit contenir au moins 6 caractères et combiner plusieurs types de caractères.'
const PASSWORD_MISMATCH_MESSAGE = 'Les mots de passe ne correspondent pas.'
const INVALID_LINK_MESSAGE =
"Ce lien de réinitialisation n'est plus valide. Demande un nouveau mot de passe."
const ResetPassword = () => {
const route = useRoute()
const oobCode = (route?.params?.oobCode || '').trim()
const [, setTooltip] = useGlobal('_tooltip')
const [, setIsLoading] = useGlobal('_isLoading')
const [email, setEmail] = useState(route?.params?.email || '')
const [password, setPassword] = useState('')
const [confirmPassword, setConfirmPassword] = useState('')
const [passwordError, setPasswordError] = useState('')
const [confirmError, setConfirmError] = useState('')
const [codeError, setCodeError] = useState('')
const [isVerifyingCode, setIsVerifyingCode] = useState(true)
const [isSubmitting, setIsSubmitting] = useState(false)
const trimmedPassword = useMemo(() => (password || '').trim(), [password])
const trimmedConfirmPassword = useMemo(() => (confirmPassword || '').trim(), [confirmPassword])
const isPasswordValid = useMemo(() => {
if (!trimmedPassword.length) return false
return checkIfPasswordIsStrongEnough({ password: trimmedPassword })
}, [trimmedPassword])
const doPasswordsMatch = useMemo(() => {
if (!trimmedPassword.length || !trimmedConfirmPassword.length) return false
return trimmedPassword === trimmedConfirmPassword
}, [trimmedPassword, trimmedConfirmPassword])
useEffect(() => {
const verifyCode = async () => {
if (!oobCode) {
setCodeError(INVALID_LINK_MESSAGE)
setTooltip({ text: INVALID_LINK_MESSAGE, type: 'error' })
setIsVerifyingCode(false)
return
}
try {
setIsLoading(true)
const resetEmail = await firebase.auth().verifyPasswordResetCode(oobCode)
setEmail(resetEmail)
setCodeError('')
} catch (error) {
console.log('ResetPassword verify error', error?.message)
const message =
error?.code && error.code.startsWith('auth/')
? handleFirebaseError(error.code)
: error?.message || INVALID_LINK_MESSAGE
setCodeError(message || INVALID_LINK_MESSAGE)
setTooltip({ text: message || INVALID_LINK_MESSAGE, type: 'error' })
} finally {
setIsLoading(false)
setIsVerifyingCode(false)
}
}
verifyCode()
}, [oobCode, setIsLoading, setTooltip])
useEffect(() => {
if (!password?.length) {
setPasswordError('')
return
}
if (!isPasswordValid) {
setPasswordError(PASSWORD_ERROR_MESSAGE)
} else {
setPasswordError('')
}
}, [password, isPasswordValid])
useEffect(() => {
if (!confirmPassword?.length) {
setConfirmError('')
return
}
if (!doPasswordsMatch) {
setConfirmError(PASSWORD_MISMATCH_MESSAGE)
} else {
setConfirmError('')
}
}, [confirmPassword, doPasswordsMatch])
const handleSubmit = async () => {
if (!isPasswordValid) {
setPasswordError(PASSWORD_ERROR_MESSAGE)
return
}
if (!doPasswordsMatch) {
setConfirmError(PASSWORD_MISMATCH_MESSAGE)
return
}
try {
setIsSubmitting(true)
setIsLoading(true)
await firebase.auth().confirmPasswordReset(oobCode, trimmedPassword)
setTooltip({
text: 'Ton mot de passe a été mis à jour. Tu peux te connecter.',
type: 'success',
})
navigate(Routes.Login)
} catch (error) {
console.log('ResetPassword submit error', error?.message)
const message =
error?.code && error.code.startsWith('auth/')
? handleFirebaseError(error.code)
: error?.message || 'Impossible de mettre à jour le mot de passe.'
setTooltip({ text: message, type: 'error' })
} finally {
setIsLoading(false)
setIsSubmitting(false)
}
}
const renderForm = () => (
<>
Définis un nouveau mot de passe
Utilise au moins 6 caractères pour sécuriser ton compte.
{email ? (
Compte concerné : {email}
) : null}
{passwordError ? (
{passwordError}
) : null}
{confirmError ? (
{confirmError}
) : null}
>
)
const renderCodeError = () => (
Lien invalide ou expiré
{codeError || INVALID_LINK_MESSAGE}
)
const handleFallbackNavigation = () => {
navigate(Routes.ForgotPassword)
}
const buttonDisabled = codeError
? isSubmitting
: isVerifyingCode || isSubmitting || !isPasswordValid || !doPasswordsMatch
const buttonLabel = codeError
? 'Demander un nouveau lien'
: isSubmitting
? 'Mise à jour...'
: isVerifyingCode
? 'Vérification...'
: 'Mettre à jour le mot de passe'
const buttonAction = codeError ? handleFallbackNavigation : handleSubmit
return (
{codeError ? renderCodeError() : renderForm()}
)
}
export default ResetPassword