11import React , { FC , useEffect , useState } from 'react' ;
22import isEmail from 'validator/es/lib/isEmail' ;
3+ import isMobilePhone from 'validator/es/lib/isMobilePhone' ;
34
45import styles from '../styles/default.css' ;
56import { ButtonAppearance , MessageType , Views } from '../constants' ;
67import { useAuthorizer } from '../contexts/AuthorizerContext' ;
78import { StyledButton , StyledFooter , StyledLink } from '../styledComponents' ;
89import { formatErrorMessage } from '../utils/format' ;
910import { Message } from './Message' ;
11+ import { OtpDataType } from '../types' ;
12+ import { AuthorizerResetPassword } from './AuthorizerResetPassword' ;
1013
1114interface InputDataType {
12- email : string | null ;
15+ email_or_phone_number : string | null ;
1316}
1417
18+ const initOtpData : OtpDataType = {
19+ is_screen_visible : false ,
20+ email : '' ,
21+ phone_number : '' ,
22+ } ;
23+
1524export const AuthorizerForgotPassword : FC < {
1625 setView ?: ( v : Views ) => void ;
1726 onForgotPassword ?: ( data : any ) => void ;
27+ onPasswordReset ?: ( ) => void ;
1828 urlProps ?: Record < string , any > ;
19- } > = ( { setView, onForgotPassword, urlProps } ) => {
29+ } > = ( { setView, onForgotPassword, onPasswordReset , urlProps } ) => {
2030 const [ error , setError ] = useState ( `` ) ;
2131 const [ loading , setLoading ] = useState ( false ) ;
2232 const [ successMessage , setSuccessMessage ] = useState ( `` ) ;
33+ const [ otpData , setOtpData ] = useState < OtpDataType > ( { ...initOtpData } ) ;
2334 const [ formData , setFormData ] = useState < InputDataType > ( {
24- email : null ,
35+ email_or_phone_number : null ,
2536 } ) ;
2637 const [ errorData , setErrorData ] = useState < InputDataType > ( {
27- email : null ,
38+ email_or_phone_number : null ,
2839 } ) ;
2940 const { authorizerRef, config } = useAuthorizer ( ) ;
3041
@@ -36,22 +47,50 @@ export const AuthorizerForgotPassword: FC<{
3647 e . preventDefault ( ) ;
3748 try {
3849 setLoading ( true ) ;
39-
40- const res = await authorizerRef . forgotPassword ( {
41- email : formData . email || '' ,
50+ let email : string = '' ;
51+ let phone_number : string = '' ;
52+ if ( formData . email_or_phone_number ) {
53+ if ( isEmail ( formData . email_or_phone_number ) ) {
54+ email = formData . email_or_phone_number ;
55+ } else if ( isMobilePhone ( formData . email_or_phone_number ) ) {
56+ phone_number = formData . email_or_phone_number ;
57+ }
58+ }
59+ if ( ! email && ! phone_number ) {
60+ setErrorData ( {
61+ ...errorData ,
62+ email_or_phone_number : 'Invalid email or phone number' ,
63+ } ) ;
64+ setLoading ( false ) ;
65+ return ;
66+ }
67+ const { data : res , errors } = await authorizerRef . forgotPassword ( {
68+ email : email ,
69+ phone_number : phone_number ,
4270 state : urlProps ?. state || '' ,
4371 redirect_uri :
4472 urlProps ?. redirect_uri ||
4573 config . redirectURL ||
4674 window . location . origin ,
4775 } ) ;
4876 setLoading ( false ) ;
49-
50- if ( res && res . message ) {
77+ if ( errors && errors . length ) {
78+ setError ( formatErrorMessage ( errors [ 0 ] ?. message ) ) ;
79+ return ;
80+ }
81+ if ( res ?. message ) {
5182 setError ( `` ) ;
5283 setSuccessMessage ( res . message ) ;
84+ if ( res ?. should_show_mobile_otp_screen ) {
85+ setOtpData ( {
86+ ...otpData ,
87+ is_screen_visible : true ,
88+ email : email ,
89+ phone_number : phone_number ,
90+ } ) ;
91+ return ;
92+ }
5393 }
54-
5594 if ( onForgotPassword ) {
5695 onForgotPassword ( res ) ;
5796 }
@@ -66,17 +105,38 @@ export const AuthorizerForgotPassword: FC<{
66105 } ;
67106
68107 useEffect ( ( ) => {
69- if ( formData . email === '' ) {
70- setErrorData ( { ...errorData , email : 'Email is required' } ) ;
71- } else if ( formData . email && ! isEmail ( formData . email ) ) {
72- setErrorData ( { ...errorData , email : 'Please enter valid email' } ) ;
108+ if ( formData . email_or_phone_number === '' ) {
109+ setErrorData ( {
110+ ...errorData ,
111+ email_or_phone_number : 'Email OR Phone Number is required' ,
112+ } ) ;
113+ } else if (
114+ formData . email_or_phone_number !== null &&
115+ ! isEmail ( formData . email_or_phone_number || '' ) &&
116+ ! isMobilePhone ( formData . email_or_phone_number || '' )
117+ ) {
118+ setErrorData ( {
119+ ...errorData ,
120+ email_or_phone_number : 'Invalid Email OR Phone Number' ,
121+ } ) ;
73122 } else {
74- setErrorData ( { ...errorData , email : null } ) ;
123+ setErrorData ( { ...errorData , email_or_phone_number : null } ) ;
75124 }
76- } , [ formData . email ] ) ;
125+ } , [ formData . email_or_phone_number ] ) ;
77126
78127 if ( successMessage ) {
79- return < Message type = { MessageType . Success } text = { successMessage } /> ;
128+ return (
129+ < >
130+ < Message type = { MessageType . Success } text = { successMessage } />
131+ { otpData . is_screen_visible && (
132+ < AuthorizerResetPassword
133+ showOTPInput
134+ onReset = { onPasswordReset }
135+ phone_number = { otpData . phone_number }
136+ />
137+ ) }
138+ </ >
139+ ) ;
80140 }
81141
82142 return (
@@ -93,32 +153,42 @@ export const AuthorizerForgotPassword: FC<{
93153 < div className = { styles [ 'styled-form-group' ] } >
94154 < label
95155 className = { styles [ 'form-input-label' ] }
96- htmlFor = "authorizer-forgot-password-email"
156+ htmlFor = "authorizer-forgot-password-email-or-phone-number "
97157 >
98- < span > * </ span > Email
158+ < span > * </ span > Email / Phone Number
99159 </ label >
100160 < input
101- name = "email "
102- id = "authorizer-forgot-password-email"
161+ name = "email_or_phone_number "
162+ id = "authorizer-forgot-password-email-or-phone-number "
103163 className = { `${ styles [ 'form-input-field' ] } ${
104- errorData . email ? styles [ 'input-error-content' ] : null
164+ errorData . email_or_phone_number
165+ ? styles [ 'input-error-content' ]
166+ : null
105167 } `}
106- placeholder = "eg. foo@bar.com"
107- type = "email"
108- value = { formData . email || '' }
109- onChange = { ( e ) => onInputChange ( 'email' , e . target . value ) }
168+ placeholder = "eg. hello@world.com / +919999999999"
169+ type = "text"
170+ value = { formData . email_or_phone_number || '' }
171+ onChange = { ( e ) =>
172+ onInputChange ( 'email_or_phone_number' , e . target . value )
173+ }
110174 />
111- { errorData . email && (
112- < div className = { styles [ 'form-input-error' ] } > { errorData . email } </ div >
175+ { errorData . email_or_phone_number && (
176+ < div className = { styles [ 'form-input-error' ] } >
177+ { errorData . email_or_phone_number }
178+ </ div >
113179 ) }
114180 </ div >
115181 < br />
116182 < StyledButton
117183 type = "submit"
118- disabled = { loading || ! ! errorData . email || ! formData . email }
184+ disabled = {
185+ loading ||
186+ ! ! errorData . email_or_phone_number ||
187+ ! formData . email_or_phone_number
188+ }
119189 appearance = { ButtonAppearance . Primary }
120190 >
121- { loading ? `Processing ...` : `Send Email ` }
191+ { loading ? `Processing ...` : `Request Change ` }
122192 </ StyledButton >
123193 </ form >
124194 { setView && (
0 commit comments