Skip to content

Commit

Permalink
WebApp - Open paypal in the same tab (#1209)
Browse files Browse the repository at this point in the history
  • Loading branch information
Maks19 authored Oct 2, 2024
1 parent a804e5e commit cf347cf
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ const mapStoreToProps = (store: RootStore): any => ({
isTermsAndConditionsAccepted: store.termsAndConditions.isTermsAndConditionsAccepted,
onSubmitTermsAndConditions: store.termsAndConditions.submitTermsAndConditions,
onToggleAcceptTermsAndConditions: store.termsAndConditions.toggleAcceptTermsAndConditions,
checkPayPalIdWithInterval: store.profile.checkPayPalIdWithInterval,
signInWithGoogleChallengeSudoMode: store.auth.signInWithGoogleChallengeSudoMode,
logInWithPayPalChallengeSudoMode: store.auth.logInWithPayPalChallengeSudoMode,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ interface Props extends WithStyles<typeof styles> {
fetchPasskeys: () => void
onAddPasskeyClick: () => void
onDeletePasskeyClick: (passkeyId: string) => void
checkPayPalIdWithInterval: () => void
logInWithPayPalChallengeSudoMode: () => void
signInWithGoogleChallengeSudoMode: (signInWithGoogle: () => void) => void
}
Expand Down Expand Up @@ -146,25 +145,17 @@ const _Account: FC<Props> = ({
isTermsAndConditionsAccepted,
onSubmitTermsAndConditions,
onToggleAcceptTermsAndConditions,
checkPayPalIdWithInterval,
logInWithPayPalChallengeSudoMode,
signInWithGoogleChallengeSudoMode,
}) => {
const location = useLocation<{ isGoogleSignInFormTriggered: string; isPayPalLogInTriggered: string }>()
const location = useLocation<{ isGoogleSignInFormTriggered: string }>()
const isGoogleSignInFormTriggered = !!location.state?.isGoogleSignInFormTriggered
const isPayPalLogInTriggered = !!location.state?.isPayPalLogInTriggered

useEffect(() => {
loadPayPalId()
loadGoogleAccountConnection()
}, [loadGoogleAccountConnection, loadPayPalId])

useEffect(() => {
if (isPayPalLogInTriggered) {
checkPayPalIdWithInterval()
}
}, [isPayPalLogInTriggered, checkPayPalIdWithInterval])

const shouldShowUpdateAccountTermsAndConditions = !!profile?.pendingTermsVersion
const handleSubmitButtonReset = () => {
isUserNameSubmitSuccess && onResetUsernameSuccess()
Expand Down
3 changes: 1 addition & 2 deletions packages/web-app/src/modules/auth/AuthStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,7 @@ export class AuthStore {
try {
const response = await this.challengeSudoMode(ChallengeSudoModeTrigger.PayPalLogIn)
if (response) {
this.store.profile.checkPayPalIdWithInterval()
window.open(config.paypalUrl)
window.location.href = config.paypalUrl
}
} catch (error) {
console.error('AuthStore -> logInWithPayPalChallengeSudoMode: ', error)
Expand Down
58 changes: 5 additions & 53 deletions packages/web-app/src/modules/profile/ProfileStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@ import * as Storage from '../../Storage'
import type { RootStore } from '../../Store'
import type { FormValues } from '../account-views/account-views/components/'
import { NotificationMessageCategory } from '../notifications/models'
import type { PaypalActionStatus } from './constants'
import {
authenticationExternalEndpointPath,
avatarsEndpointPath,
avatarsSelectedEndpointPath,
getPaypalNotification,
novuSignaturesEndpointPath,
paypalAccountInUseNotification,
paypalFailureNotification,
paypalRetryNotification,
paypalSuccessNotification,
paypalUsersEndpointPath,
profileEndpointPath,
protectRewardsRedemptionEndpointPath,
Expand All @@ -23,8 +21,8 @@ import {
ExternalAuthProviderLoginStatus,
type Avatar,
type ExternalAuthProvider,
type Profile,
type payPalResponse,
type Profile,
} from './models'

export type ProtectRewardsRedemptionStatus = 'success' | 'failure' | 'loading' | 'unknown'
Expand Down Expand Up @@ -83,8 +81,6 @@ export class ProfileStore {
@observable
public payPalId?: string

private timeoutId?: NodeJS.Timeout

@observable
public connectedGoogleAccountEmail?: string

Expand Down Expand Up @@ -298,65 +294,21 @@ export class ProfileStore {

if (paypalActionStatus) {
this.store.routing.replace('/account/summary')

switch (paypalActionStatus) {
case 'success':
this.store.notifications.sendNotification(paypalSuccessNotification)
break
case 'retry':
this.store.notifications.sendNotification(paypalRetryNotification)
break
case 'failure':
this.store.notifications.sendNotification(paypalFailureNotification)
break
case 'account_in_use':
this.store.notifications.sendNotification(paypalAccountInUseNotification)
break
}
this.store.notifications.sendNotification(getPaypalNotification(paypalActionStatus as PaypalActionStatus))
}
}

@action.bound
loadPayPalId = flow(function* (this: ProfileStore) {
this.showPaypalNotification()
try {
const res: AxiosResponse<payPalResponse> = yield this.axios.get(paypalUsersEndpointPath) as payPalResponse
this.payPalId = res?.data?.email
this.showPaypalNotification()
} catch (err) {
console.log(err)
}
})

checkPayPalIdWithInterval = async (): Promise<void> => {
let payPalLoadRetries = 0
const maxPaypalLoadRetries = 50

const loadPayPalIdWithRetry = async () => {
try {
if (payPalLoadRetries >= maxPaypalLoadRetries || this.payPalId) {
clearTimeout(this.timeoutId)
return
}

await this.loadPayPalId()

if (!this.payPalId) {
payPalLoadRetries++
this.timeoutId = setTimeout(loadPayPalIdWithRetry, 5000)
} else {
this.store.notifications.sendNotification(paypalSuccessNotification)
clearTimeout(this.timeoutId)
return
}
} catch (error) {
console.error('ProfileStore -> checkPayPalIdWithInterval: ', error)
}
}

clearTimeout(this.timeoutId)
loadPayPalIdWithRetry()
}

@action.bound
connectExternalAccountProvider = () => {
const urlSearchParams = new URLSearchParams(window.location.search)
Expand Down
29 changes: 25 additions & 4 deletions packages/web-app/src/modules/profile/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,20 @@ export const paypalUsersEndpointPath = '/api/v2/paypal/users'
export const authenticationExternalEndpointPath = '/api/v2/authentication/external'
export const protectRewardsRedemptionEndpointPath = '/api/v1/profile/redemptions/tfa'

export const paypalSuccessNotification: NotificationMessage = {
export enum PaypalActionStatus {
Success = 'success',
Retry = 'retry',
Failure = 'failure',
AccountInUse = 'account_in_use',
}

const paypalSuccessNotification: NotificationMessage = {
category: NotificationMessageCategory.PayPalSuccess,
title: 'Congratulations!',
message: 'You have successfully linked your PayPal account to Salad.',
}

export const paypalRetryNotification: NotificationMessage = {
const paypalRetryNotification: NotificationMessage = {
category: NotificationMessageCategory.PayPalRetry,
title: `Oops! Let's fix that`,
message:
Expand All @@ -29,7 +36,7 @@ export const paypalRetryNotification: NotificationMessage = {
),
}

export const paypalFailureNotification: NotificationMessage = {
const paypalFailureNotification: NotificationMessage = {
category: NotificationMessageCategory.PayPalFailure,
title: `Let's try that again`,
message: `We weren't able to connect your PayPal account to Salad. Feel free to try again whenever you like. If the problem persists, please contact Salad Support.`,
Expand All @@ -42,7 +49,7 @@ export const paypalFailureNotification: NotificationMessage = {
),
}

export const paypalAccountInUseNotification: NotificationMessage = {
const paypalAccountInUseNotification: NotificationMessage = {
category: NotificationMessageCategory.PayPalAccountInUse,
title: `Let's try that again`,
message: 'This PayPal account cannot be linked to this Salad account. Learn More.',
Expand All @@ -54,3 +61,17 @@ export const paypalAccountInUseNotification: NotificationMessage = {
'noopener, noreferrer',
),
}

export const getPaypalNotification = (paypalActionStatus: PaypalActionStatus) => {
switch (paypalActionStatus) {
case PaypalActionStatus.Success:
return paypalSuccessNotification
case PaypalActionStatus.Retry:
return paypalRetryNotification
case PaypalActionStatus.AccountInUse:
return paypalAccountInUseNotification
case PaypalActionStatus.Failure:
default:
return paypalFailureNotification
}
}
3 changes: 1 addition & 2 deletions packages/web-app/src/modules/protected-action/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ const handleChallengeSudoModeTrigger = (store: RootStore) => {
store.routing.push('/account/summary', { isGoogleSignInFormTriggered: true })
break
case ChallengeSudoModeTrigger.PayPalLogIn:
window.open(config.paypalUrl)
store.routing.push('/account/summary', { isPayPalLogInTriggered: true })
window.location.href = config.paypalUrl
break
case ChallengeSudoModeTrigger.RewardRedeem:
const pendingLastReward = store.rewards.getReward(store.rewards.lastRewardId)
Expand Down

0 comments on commit cf347cf

Please sign in to comment.