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 { AuthorizerVerifyOtp } from './AuthorizerVerifyOtp' ;
12+ import { OtpDataType } from '../types' ;
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 ;
@@ -20,11 +29,12 @@ export const AuthorizerForgotPassword: FC<{
2029 const [ error , setError ] = useState ( `` ) ;
2130 const [ loading , setLoading ] = useState ( false ) ;
2231 const [ successMessage , setSuccessMessage ] = useState ( `` ) ;
32+ const [ otpData , setOtpData ] = useState < OtpDataType > ( { ...initOtpData } ) ;
2333 const [ formData , setFormData ] = useState < InputDataType > ( {
24- email : null ,
34+ email_or_phone_number : null ,
2535 } ) ;
2636 const [ errorData , setErrorData ] = useState < InputDataType > ( {
27- email : null ,
37+ email_or_phone_number : null ,
2838 } ) ;
2939 const { authorizerRef, config } = useAuthorizer ( ) ;
3040
@@ -36,22 +46,50 @@ export const AuthorizerForgotPassword: FC<{
3646 e . preventDefault ( ) ;
3747 try {
3848 setLoading ( true ) ;
39-
40- const res = await authorizerRef . forgotPassword ( {
41- email : formData . email || '' ,
49+ let email : string = '' ;
50+ let phone_number : string = '' ;
51+ if ( formData . email_or_phone_number ) {
52+ if ( isEmail ( formData . email_or_phone_number ) ) {
53+ email = formData . email_or_phone_number ;
54+ } else if ( isMobilePhone ( formData . email_or_phone_number ) ) {
55+ phone_number = formData . email_or_phone_number ;
56+ }
57+ }
58+ if ( ! email && ! phone_number ) {
59+ setErrorData ( {
60+ ...errorData ,
61+ email_or_phone_number : 'Invalid email or phone number' ,
62+ } ) ;
63+ setLoading ( false ) ;
64+ return ;
65+ }
66+ const { data : res , errors } = await authorizerRef . forgotPassword ( {
67+ email : email ,
68+ phone_number : phone_number ,
4269 state : urlProps ?. state || '' ,
4370 redirect_uri :
4471 urlProps ?. redirect_uri ||
4572 config . redirectURL ||
4673 window . location . origin ,
4774 } ) ;
4875 setLoading ( false ) ;
49-
50- if ( res && res . message ) {
76+ if ( errors && errors . length ) {
77+ setError ( formatErrorMessage ( errors [ 0 ] ?. message ) ) ;
78+ return ;
79+ }
80+ if ( res ?. message ) {
5181 setError ( `` ) ;
5282 setSuccessMessage ( res . message ) ;
83+ if ( res ?. should_show_mobile_otp_screen ) {
84+ setOtpData ( {
85+ ...otpData ,
86+ is_screen_visible : true ,
87+ email : email ,
88+ phone_number : phone_number ,
89+ } ) ;
90+ return ;
91+ }
5392 }
54-
5593 if ( onForgotPassword ) {
5694 onForgotPassword ( res ) ;
5795 }
@@ -66,19 +104,43 @@ export const AuthorizerForgotPassword: FC<{
66104 } ;
67105
68106 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' } ) ;
107+ if ( formData . email_or_phone_number === '' ) {
108+ setErrorData ( {
109+ ...errorData ,
110+ email_or_phone_number : 'Email OR Phone Number is required' ,
111+ } ) ;
112+ } else if (
113+ ! isEmail ( formData . email_or_phone_number || '' ) &&
114+ ! isMobilePhone ( formData . email_or_phone_number || '' )
115+ ) {
116+ setErrorData ( {
117+ ...errorData ,
118+ email_or_phone_number : 'Invalid Email OR Phone Number' ,
119+ } ) ;
73120 } else {
74- setErrorData ( { ...errorData , email : null } ) ;
121+ setErrorData ( { ...errorData , email_or_phone_number : null } ) ;
75122 }
76- } , [ formData . email ] ) ;
123+ } , [ formData . email_or_phone_number ] ) ;
77124
78125 if ( successMessage ) {
79126 return < Message type = { MessageType . Success } text = { successMessage } /> ;
80127 }
81128
129+ if ( otpData . is_screen_visible ) {
130+ return (
131+ < AuthorizerVerifyOtp
132+ email = { otpData . email }
133+ phone_number = { otpData . phone_number }
134+ urlProps = { urlProps }
135+ onLogin = { ( ) => {
136+ if ( onForgotPassword ) {
137+ onForgotPassword ( { } ) ;
138+ }
139+ } }
140+ />
141+ ) ;
142+ }
143+
82144 return (
83145 < >
84146 { error && (
@@ -93,29 +155,39 @@ export const AuthorizerForgotPassword: FC<{
93155 < div className = { styles [ 'styled-form-group' ] } >
94156 < label
95157 className = { styles [ 'form-input-label' ] }
96- htmlFor = "authorizer-forgot-password-email"
158+ htmlFor = "authorizer-forgot-password-email-or-phone-number "
97159 >
98160 < span > * </ span > Email
99161 </ label >
100162 < input
101- name = "email "
102- id = "authorizer-forgot-password-email"
163+ name = "email_or_phone_number "
164+ id = "authorizer-forgot-password-email-or- "
103165 className = { `${ styles [ 'form-input-field' ] } ${
104- errorData . email ? styles [ 'input-error-content' ] : null
166+ errorData . email_or_phone_number
167+ ? styles [ 'input-error-content' ]
168+ : null
105169 } `}
106170 placeholder = "eg. foo@bar.com"
107- type = "email"
108- value = { formData . email || '' }
109- onChange = { ( e ) => onInputChange ( 'email' , e . target . value ) }
171+ type = "text"
172+ value = { formData . email_or_phone_number || '' }
173+ onChange = { ( e ) =>
174+ onInputChange ( 'email_or_phone_number' , e . target . value )
175+ }
110176 />
111- { errorData . email && (
112- < div className = { styles [ 'form-input-error' ] } > { errorData . email } </ div >
177+ { errorData . email_or_phone_number && (
178+ < div className = { styles [ 'form-input-error' ] } >
179+ { errorData . email_or_phone_number }
180+ </ div >
113181 ) }
114182 </ div >
115183 < br />
116184 < StyledButton
117185 type = "submit"
118- disabled = { loading || ! ! errorData . email || ! formData . email }
186+ disabled = {
187+ loading ||
188+ ! ! errorData . email_or_phone_number ||
189+ ! formData . email_or_phone_number
190+ }
119191 appearance = { ButtonAppearance . Primary }
120192 >
121193 { loading ? `Processing ...` : `Send Email` }
0 commit comments