@@ -28,7 +28,6 @@ import {
2828 API_ERROR_MESSAGE ,
2929 CREATE_ACCOUNT_FIRST_ERROR_MESSAGE ,
3030 FEATURE_UNAVAILABLE_ERROR_MESSAGE ,
31- LOGIN_TYPES ,
3231 PASSWORDLESS_ERROR_MESSAGES ,
3332 USER_NOT_FOUND_ERROR
3433} from '../constants'
@@ -83,8 +82,6 @@ export const AuthModal = ({
8382 const appOrigin = useAppOrigin ( )
8483 const config = useExtensionConfig ( )
8584
86- const [ loginType , setLoginType ] = useState ( LOGIN_TYPES . PASSWORD )
87- const [ passwordlessLoginEmail , setPasswordlessLoginEmail ] = useState ( initialEmail )
8885 const { getPasswordResetToken} = usePasswordReset ( )
8986 const authorizePasswordlessLogin = useAuthHelper ( AuthHelpers . AuthorizePasswordless )
9087 const passwordlessConfigCallback = config . login ?. passwordless ?. callbackURI
@@ -101,66 +98,67 @@ export const AuthModal = ({
10198 )
10299 const mergeBasket = useShopperBasketsMutation ( 'mergeBasket' )
103100
104- const submitForm = async ( data ) => {
101+ const handlePasswordlessLogin = async ( email ) => {
102+ try {
103+ const redirectPath = window . location . pathname + ( window . location . search || '' )
104+ await authorizePasswordlessLogin . mutateAsync ( {
105+ userid : email ,
106+ callbackURI : `${ callbackURL } ?redirectUrl=${ redirectPath } `
107+ } )
108+ setCurrentView ( EMAIL_VIEW )
109+ } catch ( error ) {
110+ const message = USER_NOT_FOUND_ERROR . test ( error . message )
111+ ? formatMessage ( CREATE_ACCOUNT_FIRST_ERROR_MESSAGE )
112+ : PASSWORDLESS_ERROR_MESSAGES . some ( ( msg ) => msg . test ( error . message ) )
113+ ? formatMessage ( FEATURE_UNAVAILABLE_ERROR_MESSAGE )
114+ : formatMessage ( API_ERROR_MESSAGE )
115+ form . setError ( 'global' , { type : 'manual' , message} )
116+ }
117+ }
118+
119+ const submitForm = async ( data , isPasswordless = false ) => {
105120 form . clearErrors ( )
106121
107122 const onLoginSuccess = ( ) => {
108123 navigate ( '/account' )
109124 }
110125
111- const handlePasswordlessLogin = async ( email ) => {
112- try {
113- const redirectPath = window . location . pathname + window . location . search
114- await authorizePasswordlessLogin . mutateAsync ( {
115- userid : email ,
116- callbackURI : `${ callbackURL } ?redirectUrl=${ redirectPath } `
117- } )
118- setCurrentView ( EMAIL_VIEW )
119- } catch ( error ) {
120- const message = USER_NOT_FOUND_ERROR . test ( error . message )
121- ? formatMessage ( CREATE_ACCOUNT_FIRST_ERROR_MESSAGE )
122- : PASSWORDLESS_ERROR_MESSAGES . some ( ( msg ) => msg . test ( error . message ) )
123- ? formatMessage ( FEATURE_UNAVAILABLE_ERROR_MESSAGE )
124- : formatMessage ( API_ERROR_MESSAGE )
125- form . setError ( 'global' , { type : 'manual' , message} )
126- }
127- }
128-
129126 return {
130127 login : async ( data ) => {
131- if ( loginType === LOGIN_TYPES . PASSWORD ) {
132- try {
133- await login . mutateAsync ( {
134- username : data . email ,
135- password : data . password
128+ if ( isPasswordless ) {
129+ const email = data . email
130+ await handlePasswordlessLogin ( email )
131+ return
132+ }
133+
134+ try {
135+ await login . mutateAsync ( {
136+ username : data . email ,
137+ password : data . password
138+ } )
139+ const hasBasketItem = baskets ?. baskets ?. [ 0 ] ?. productItems ?. length > 0
140+ // we only want to merge basket when the user is logged in as a recurring user
141+ // only recurring users trigger the login mutation, new user triggers register mutation
142+ // this logic needs to stay in this block because this is the only place that tells if a user is a recurring user
143+ // if you change logic here, also change it in login page
144+ const shouldMergeBasket = hasBasketItem && prevAuthType === 'guest'
145+ if ( shouldMergeBasket ) {
146+ mergeBasket . mutate ( {
147+ headers : {
148+ // This is not required since the request has no body
149+ // but CommerceAPI throws a '419 - Unsupported Media Type' error if this header is removed.
150+ 'Content-Type' : 'application/json'
151+ } ,
152+ parameters : {
153+ createDestinationBasket : true
154+ }
136155 } )
137- const hasBasketItem = baskets ?. baskets ?. [ 0 ] ?. productItems ?. length > 0
138- // we only want to merge basket when the user is logged in as a recurring user
139- // only recurring users trigger the login mutation, new user triggers register mutation
140- // this logic needs to stay in this block because this is the only place that tells if a user is a recurring user
141- // if you change logic here, also change it in login page
142- const shouldMergeBasket = hasBasketItem && prevAuthType === 'guest'
143- if ( shouldMergeBasket ) {
144- mergeBasket . mutate ( {
145- headers : {
146- // This is not required since the request has no body
147- // but CommerceAPI throws a '419 - Unsupported Media Type' error if this header is removed.
148- 'Content-Type' : 'application/json'
149- } ,
150- parameters : {
151- createDestinationBasket : true
152- }
153- } )
154- }
155- } catch ( error ) {
156- const message = / U n a u t h o r i z e d / i. test ( error . message )
157- ? formatMessage ( LOGIN_ERROR )
158- : formatMessage ( API_ERROR_MESSAGE )
159- form . setError ( 'global' , { type : 'manual' , message} )
160156 }
161- } else if ( loginType === LOGIN_TYPES . PASSWORDLESS ) {
162- setPasswordlessLoginEmail ( data . email )
163- await handlePasswordlessLogin ( data . email )
157+ } catch ( error ) {
158+ const message = / U n a u t h o r i z e d / i. test ( error . message )
159+ ? formatMessage ( LOGIN_ERROR )
160+ : formatMessage ( API_ERROR_MESSAGE )
161+ form . setError ( 'global' , { type : 'manual' , message} )
164162 }
165163 } ,
166164 register : async ( data ) => {
@@ -196,15 +194,15 @@ export const AuthModal = ({
196194 }
197195 } ,
198196 email : async ( ) => {
199- await handlePasswordlessLogin ( passwordlessLoginEmail )
197+ const email = form . getValues ( ) . email || initialEmail
198+ await handlePasswordlessLogin ( email )
200199 }
201200 } [ currentView ] ( data )
202201 }
203202
204203 // Reset form and local state when opening the modal
205204 useEffect ( ( ) => {
206205 if ( isOpen ) {
207- setLoginType ( LOGIN_TYPES . PASSWORD )
208206 setCurrentView ( initialView )
209207 form . reset ( )
210208 }
@@ -223,13 +221,13 @@ export const AuthModal = ({
223221
224222 // Clear form state when changing views
225223 useEffect ( ( ) => {
226- form . reset ( )
224+ // we don't want to reset the form on email view
225+ // because we want to pass the email to PasswordlessEmailConfirmation
226+ if ( currentView !== EMAIL_VIEW ) {
227+ form . reset ( )
228+ }
227229 } , [ currentView ] )
228230
229- useEffect ( ( ) => {
230- setPasswordlessLoginEmail ( initialEmail )
231- } , [ initialEmail ] )
232-
233231 useEffect ( ( ) => {
234232 // Lets determine if the user has either logged in, or registed.
235233 const loggingIn = currentView === LOGIN_VIEW
@@ -302,16 +300,16 @@ export const AuthModal = ({
302300 { ! form . formState . isSubmitSuccessful && currentView === LOGIN_VIEW && (
303301 < LoginForm
304302 form = { form }
305- submitForm = { submitForm }
303+ submitForm = { ( data ) => {
304+ const shouldUsePasswordless =
305+ isPasswordlessEnabled && ! data . password
306+ return submitForm ( data , shouldUsePasswordless )
307+ } }
306308 clickCreateAccount = { ( ) => setCurrentView ( REGISTER_VIEW ) }
307- handlePasswordlessLoginClick = { ( ) =>
308- setLoginType ( LOGIN_TYPES . PASSWORDLESS )
309- }
310309 handleForgotPasswordClick = { ( ) => setCurrentView ( PASSWORD_VIEW ) }
311310 isPasswordlessEnabled = { isPasswordlessEnabled }
312311 isSocialEnabled = { isSocialEnabled }
313312 idps = { idps }
314- setLoginType = { setLoginType }
315313 />
316314 ) }
317315
@@ -336,7 +334,7 @@ export const AuthModal = ({
336334 < PasswordlessEmailConfirmation
337335 form = { form }
338336 submitForm = { submitForm }
339- email = { passwordlessLoginEmail }
337+ email = { form . getValues ( ) . email || initialEmail }
340338 />
341339 ) }
342340 </ Dialog . Body >
0 commit comments