@@ -35,7 +35,6 @@ import {
3535 API_ERROR_MESSAGE ,
3636 CREATE_ACCOUNT_FIRST_ERROR_MESSAGE ,
3737 FEATURE_UNAVAILABLE_ERROR_MESSAGE ,
38- LOGIN_TYPES ,
3938 PASSWORDLESS_ERROR_MESSAGES ,
4039 USER_NOT_FOUND_ERROR
4140} from '@salesforce/retail-react-app/app/constants'
@@ -88,8 +87,6 @@ export const AuthModal = ({
8887 const register = useAuthHelper ( AuthHelpers . Register )
8988 const appOrigin = useAppOrigin ( )
9089
91- const [ loginType , setLoginType ] = useState ( LOGIN_TYPES . PASSWORD )
92- const [ passwordlessLoginEmail , setPasswordlessLoginEmail ] = useState ( initialEmail )
9390 const { getPasswordResetToken} = usePasswordReset ( )
9491 const authorizePasswordlessLogin = useAuthHelper ( AuthHelpers . AuthorizePasswordless )
9592 const passwordlessConfigCallback = getConfig ( ) . app . login ?. passwordless ?. callbackURI
@@ -103,66 +100,67 @@ export const AuthModal = ({
103100 )
104101 const mergeBasket = useShopperBasketsMutation ( 'mergeBasket' )
105102
106- const submitForm = async ( data ) => {
103+ const handlePasswordlessLogin = async ( email ) => {
104+ try {
105+ const redirectPath = window . location . pathname + ( window . location . search || '' )
106+ await authorizePasswordlessLogin . mutateAsync ( {
107+ userid : email ,
108+ callbackURI : `${ callbackURL } ?redirectUrl=${ redirectPath } `
109+ } )
110+ setCurrentView ( EMAIL_VIEW )
111+ } catch ( error ) {
112+ const message = USER_NOT_FOUND_ERROR . test ( error . message )
113+ ? formatMessage ( CREATE_ACCOUNT_FIRST_ERROR_MESSAGE )
114+ : PASSWORDLESS_ERROR_MESSAGES . some ( ( msg ) => msg . test ( error . message ) )
115+ ? formatMessage ( FEATURE_UNAVAILABLE_ERROR_MESSAGE )
116+ : formatMessage ( API_ERROR_MESSAGE )
117+ form . setError ( 'global' , { type : 'manual' , message} )
118+ }
119+ }
120+
121+ const submitForm = async ( data , isPasswordless = false ) => {
107122 form . clearErrors ( )
108123
109124 const onLoginSuccess = ( ) => {
110125 navigate ( '/account' )
111126 }
112127
113- const handlePasswordlessLogin = async ( email ) => {
114- try {
115- const redirectPath = window . location . pathname + window . location . search
116- await authorizePasswordlessLogin . mutateAsync ( {
117- userid : email ,
118- callbackURI : `${ callbackURL } ?redirectUrl=${ redirectPath } `
119- } )
120- setCurrentView ( EMAIL_VIEW )
121- } catch ( error ) {
122- const message = USER_NOT_FOUND_ERROR . test ( error . message )
123- ? formatMessage ( CREATE_ACCOUNT_FIRST_ERROR_MESSAGE )
124- : PASSWORDLESS_ERROR_MESSAGES . some ( ( msg ) => msg . test ( error . message ) )
125- ? formatMessage ( FEATURE_UNAVAILABLE_ERROR_MESSAGE )
126- : formatMessage ( API_ERROR_MESSAGE )
127- form . setError ( 'global' , { type : 'manual' , message} )
128- }
129- }
130-
131128 return {
132129 login : async ( data ) => {
133- if ( loginType === LOGIN_TYPES . PASSWORD ) {
134- try {
135- await login . mutateAsync ( {
136- username : data . email ,
137- password : data . password
130+ if ( isPasswordless ) {
131+ const email = data . email
132+ await handlePasswordlessLogin ( email )
133+ return
134+ }
135+
136+ try {
137+ await login . mutateAsync ( {
138+ username : data . email ,
139+ password : data . password
140+ } )
141+ const hasBasketItem = baskets ?. baskets ?. [ 0 ] ?. productItems ?. length > 0
142+ // we only want to merge basket when the user is logged in as a recurring user
143+ // only recurring users trigger the login mutation, new user triggers register mutation
144+ // this logic needs to stay in this block because this is the only place that tells if a user is a recurring user
145+ // if you change logic here, also change it in login page
146+ const shouldMergeBasket = hasBasketItem && prevAuthType === 'guest'
147+ if ( shouldMergeBasket ) {
148+ mergeBasket . mutate ( {
149+ headers : {
150+ // This is not required since the request has no body
151+ // but CommerceAPI throws a '419 - Unsupported Media Type' error if this header is removed.
152+ 'Content-Type' : 'application/json'
153+ } ,
154+ parameters : {
155+ createDestinationBasket : true
156+ }
138157 } )
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- }
155- } )
156- }
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} )
162158 }
163- } else if ( loginType === LOGIN_TYPES . PASSWORDLESS ) {
164- setPasswordlessLoginEmail ( data . email )
165- await handlePasswordlessLogin ( data . email )
159+ } catch ( error ) {
160+ const message = / U n a u t h o r i z e d / i. test ( error . message )
161+ ? formatMessage ( LOGIN_ERROR )
162+ : formatMessage ( API_ERROR_MESSAGE )
163+ form . setError ( 'global' , { type : 'manual' , message} )
166164 }
167165 } ,
168166 register : async ( data ) => {
@@ -198,15 +196,15 @@ export const AuthModal = ({
198196 }
199197 } ,
200198 email : async ( ) => {
201- await handlePasswordlessLogin ( passwordlessLoginEmail )
199+ const email = form . getValues ( ) . email || initialEmail
200+ await handlePasswordlessLogin ( email )
202201 }
203202 } [ currentView ] ( data )
204203 }
205204
206205 // Reset form and local state when opening the modal
207206 useEffect ( ( ) => {
208207 if ( isOpen ) {
209- setLoginType ( LOGIN_TYPES . PASSWORD )
210208 setCurrentView ( initialView )
211209 form . reset ( )
212210 }
@@ -223,15 +221,14 @@ export const AuthModal = ({
223221 fieldsRef ?. [ initialField ] ?. ref . focus ( )
224222 } , [ form . control ?. fieldsRef ?. current ] )
225223
226- // Clear form state when changing views
227224 useEffect ( ( ) => {
228- form . reset ( )
225+ // we don't want to reset the form on email view
226+ // because we want to pass the email to PasswordlessEmailConfirmation
227+ if ( currentView !== EMAIL_VIEW ) {
228+ form . reset ( )
229+ }
229230 } , [ currentView ] )
230231
231- useEffect ( ( ) => {
232- setPasswordlessLoginEmail ( initialEmail )
233- } , [ initialEmail ] )
234-
235232 useEffect ( ( ) => {
236233 // Lets determine if the user has either logged in, or registed.
237234 const loggingIn = currentView === LOGIN_VIEW
@@ -302,16 +299,20 @@ export const AuthModal = ({
302299 { ! form . formState . isSubmitSuccessful && currentView === LOGIN_VIEW && (
303300 < LoginForm
304301 form = { form }
305- submitForm = { submitForm }
302+ submitForm = { ( data ) => {
303+ const shouldUsePasswordless =
304+ isPasswordlessEnabled && ! data . password
305+ return submitForm ( data , shouldUsePasswordless )
306+ } }
306307 clickCreateAccount = { ( ) => setCurrentView ( REGISTER_VIEW ) }
307- handlePasswordlessLoginClick = { ( ) =>
308- setLoginType ( LOGIN_TYPES . PASSWORDLESS )
309- }
308+ //TODO: potentially remove this prop in the next major release since
309+ // we don't need to use this props anymore
310+ handlePasswordlessLoginClick = { noop }
310311 handleForgotPasswordClick = { ( ) => setCurrentView ( PASSWORD_VIEW ) }
311312 isPasswordlessEnabled = { isPasswordlessEnabled }
312313 isSocialEnabled = { isSocialEnabled }
313314 idps = { idps }
314- setLoginType = { setLoginType }
315+ setLoginType = { noop }
315316 />
316317 ) }
317318 { ! form . formState . isSubmitSuccessful && currentView === REGISTER_VIEW && (
@@ -332,7 +333,7 @@ export const AuthModal = ({
332333 < PasswordlessEmailConfirmation
333334 form = { form }
334335 submitForm = { submitForm }
335- email = { passwordlessLoginEmail }
336+ email = { form . getValues ( ) . email || initialEmail }
336337 />
337338 ) }
338339 </ ModalBody >
0 commit comments