Move card details and shipping address to the Redux store

This commit is contained in:
Daniel Dudzic 2024-09-24 02:09:38 +02:00
parent 75960fc4a4
commit 5a31fdd183
No known key found for this signature in database
GPG key ID: 31B40D33E3465483
6 changed files with 122 additions and 72 deletions

View file

@ -6,7 +6,7 @@ import { setIsGuest, setIsEmailLookupCompleted } from '../stores/axoStore';
export const createEmailLookupHandler = (
fastlaneSdk,
setShippingAddress,
setCard,
setCardDetails,
snapshotFields,
wooShippingAddress,
wooBillingAddress,
@ -68,7 +68,7 @@ export const createEmailLookupHandler = (
setShippingAddress( profileData.shippingAddress );
}
if ( profileData && profileData.card ) {
setCard( profileData.card );
setCardDetails( profileData.card );
}
console.log( 'Profile Data:', profileData );

View file

@ -15,11 +15,14 @@ const useAxoSetup = (
ppcpConfig,
fastlaneSdk,
paymentComponent,
onChangeCardButtonClick,
setShippingAddress,
setCard
onChangeCardButtonClick
) => {
const { setIsAxoActive, setIsAxoScriptLoaded } = useDispatch( STORE_NAME );
const {
setIsAxoActive,
setIsAxoScriptLoaded,
setShippingAddress,
setCardDetails,
} = useDispatch( STORE_NAME );
const paypalLoaded = usePayPalScript( ppcpConfig );
const onChangeShippingAddressClick = useShippingAddressChange(
@ -53,7 +56,7 @@ const useAxoSetup = (
const emailLookupHandler = createEmailLookupHandler(
fastlaneSdk,
setShippingAddress,
setCard,
setCardDetails,
snapshotFields,
wooShippingAddress,
wooBillingAddress,
@ -76,7 +79,7 @@ const useAxoSetup = (
onChangeShippingAddressClick,
onChangeCardButtonClick,
setShippingAddress,
setCard,
setCardDetails,
paymentComponent,
] );

View file

@ -1,53 +1,73 @@
import { useCallback } from '@wordpress/element';
import { useDispatch } from '@wordpress/data';
import { useAddressEditing } from './useAddressEditing';
import useCustomerData from './useCustomerData';
import { STORE_NAME } from '../stores/axoStore';
export const useCardChange = ( fastlaneSdk, setCard ) => {
export const useCardChange = ( fastlaneSdk ) => {
const { setBillingAddressEditing } = useAddressEditing();
const { setBillingAddress: setWooBillingAddress } = useCustomerData();
const { setCardDetails, setShippingAddress } = useDispatch( STORE_NAME );
return useCallback( async () => {
if ( fastlaneSdk ) {
const { selectionChanged, selectedCard } =
await fastlaneSdk.profile.showCardSelector();
if ( selectionChanged ) {
setCard( selectedCard );
console.log( 'Selected card changed:', selectedCard );
console.log( 'Setting new billing details:', selectedCard );
if ( selectionChanged && selectedCard?.paymentSource?.card ) {
// Use the fallback logic for cardholder's name.
const { name, billingAddress } =
selectedCard.paymentSource.card;
// Split the full name into first and last name
const nameParts = name.split( ' ' );
const firstName = nameParts[ 0 ];
const lastName = nameParts.slice( 1 ).join( ' ' );
// If name is missing, use billing details as a fallback for the name.
let firstName = '';
let lastName = '';
if ( name ) {
const nameParts = name.split( ' ' );
firstName = nameParts[ 0 ];
lastName = nameParts.slice( 1 ).join( ' ' );
}
const newBillingAddress = {
first_name: firstName,
last_name: lastName,
address_1: billingAddress.addressLine1,
address_2: billingAddress.addressLine2 || '',
city: billingAddress.adminArea2,
state: billingAddress.adminArea1,
postcode: billingAddress.postalCode,
country: billingAddress.countryCode,
address_1: billingAddress?.addressLine1 || '',
address_2: billingAddress?.addressLine2 || '',
city: billingAddress?.adminArea2 || '',
state: billingAddress?.adminArea1 || '',
postcode: billingAddress?.postalCode || '',
country: billingAddress?.countryCode || '',
};
await new Promise( ( resolve ) => {
setWooBillingAddress( newBillingAddress );
resolve();
} );
await new Promise( ( resolve ) => {
setBillingAddressEditing( false );
resolve();
} );
// Batch state updates.
await Promise.all( [
new Promise( ( resolve ) => {
setCardDetails( selectedCard );
resolve();
} ),
new Promise( ( resolve ) => {
setWooBillingAddress( newBillingAddress );
resolve();
} ),
new Promise( ( resolve ) => {
setShippingAddress( newBillingAddress );
resolve();
} ),
new Promise( ( resolve ) => {
setBillingAddressEditing( false );
resolve();
} ),
] );
} else {
console.error( 'Selected card or billing address is missing.' );
}
}
}, [
fastlaneSdk,
setCard,
setCardDetails,
setWooBillingAddress,
setShippingAddress,
setBillingAddressEditing,
] );
};

View file

@ -1,14 +1,23 @@
import { useCallback } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { STORE_NAME } from '../stores/axoStore';
const useHandlePaymentSetup = (
emitResponse,
card,
paymentComponent,
tokenizedCustomerData
) => {
const { cardDetails } = useSelect(
( select ) => ( {
shippingAddress: select( STORE_NAME ).getShippingAddress(),
cardDetails: select( STORE_NAME ).getCardDetails(),
} ),
[]
);
return useCallback( async () => {
const isRyanFlow = !! card?.id;
let cardToken = card?.id;
const isRyanFlow = !! cardDetails?.id;
let cardToken = cardDetails?.id;
if ( ! cardToken && paymentComponent ) {
cardToken = await paymentComponent
@ -38,7 +47,13 @@ const useHandlePaymentSetup = (
},
},
};
}, [ card, paymentComponent, tokenizedCustomerData ] );
}, [
cardDetails?.id,
emitResponse.responseTypes.ERROR,
emitResponse.responseTypes.SUCCESS,
paymentComponent,
tokenizedCustomerData,
] );
};
export default useHandlePaymentSetup;

View file

@ -1,4 +1,5 @@
import { useState } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { registerPaymentMethod } from '@woocommerce/blocks-registry';
// Hooks
@ -13,6 +14,9 @@ import useHandlePaymentSetup from './hooks/useHandlePaymentSetup';
import { Payment } from './components/Payment/Payment';
import usePaymentSetupEffect from './hooks/usePaymentSetupEffect';
// Store
import { STORE_NAME } from './stores/axoStore';
const gatewayHandle = 'ppcp-axo-gateway';
const ppcpConfig = wc.wcSettings.getSetting( `${ gatewayHandle }_data` );
@ -25,16 +29,20 @@ const axoConfig = window.wc_ppcp_axo;
const Axo = ( props ) => {
const { eventRegistration, emitResponse } = props;
const { onPaymentSetup } = eventRegistration;
const [ shippingAddress, setShippingAddress ] = useState( null );
const [ card, setCard ] = useState( null );
const [ paymentComponent, setPaymentComponent ] = useState( null );
const { cardDetails } = useSelect(
( select ) => ( {
cardDetails: select( STORE_NAME ).getCardDetails(),
} ),
[]
);
const fastlaneSdk = useFastlaneSdk( axoConfig, ppcpConfig );
const tokenizedCustomerData = useTokenizeCustomerData();
const onChangeCardButtonClick = useCardChange( fastlaneSdk, setCard );
const onChangeCardButtonClick = useCardChange( fastlaneSdk );
const handlePaymentSetup = useHandlePaymentSetup(
emitResponse,
card,
paymentComponent,
tokenizedCustomerData
);
@ -43,9 +51,7 @@ const Axo = ( props ) => {
ppcpConfig,
fastlaneSdk,
paymentComponent,
onChangeCardButtonClick,
setShippingAddress,
setCard
onChangeCardButtonClick
);
const { handlePaymentLoad } = usePaymentSetupEffect(
@ -56,22 +62,15 @@ const Axo = ( props ) => {
useAxoCleanup();
const handleCardChange = ( selectedCard ) => {
console.log( 'Card selection changed', selectedCard );
setCard( selectedCard );
};
console.log( 'Rendering Axo component', {
fastlaneSdk,
card,
shippingAddress,
} );
return fastlaneSdk ? (
<Payment
fastlaneSdk={ fastlaneSdk }
card={ card }
onChange={ handleCardChange }
card={ cardDetails }
onChange={ onChangeCardButtonClick }
onPaymentLoad={ handlePaymentLoad }
onChangeButtonClick={ onChangeCardButtonClick }
/>

View file

@ -1,19 +1,19 @@
// File: axoStore.js
import { createReduxStore, register, dispatch } from '@wordpress/data';
export const STORE_NAME = 'woocommerce-paypal-payments/axo-block';
// Initial state
// Initial state.
const DEFAULT_STATE = {
isGuest: true,
isAxoActive: false,
isAxoScriptLoaded: false,
isEmailSubmitted: false,
isEmailLookupCompleted: false,
shippingAddress: null,
cardDetails: null,
};
// Actions
// Actions.
const actions = {
setIsGuest: ( isGuest ) => ( {
type: 'SET_IS_GUEST',
@ -35,9 +35,17 @@ const actions = {
type: 'SET_IS_EMAIL_LOOKUP_COMPLETED',
payload: isEmailLookupCompleted,
} ),
setShippingAddress: ( shippingAddress ) => ( {
type: 'SET_SHIPPING_ADDRESS',
payload: shippingAddress,
} ),
setCardDetails: ( cardDetails ) => ( {
type: 'SET_CARD_DETAILS',
payload: cardDetails,
} ),
};
// Reducer
// Reducer.
const reducer = ( state = DEFAULT_STATE, action ) => {
switch ( action.type ) {
case 'SET_IS_GUEST':
@ -50,21 +58,27 @@ const reducer = ( state = DEFAULT_STATE, action ) => {
return { ...state, isEmailSubmitted: action.payload };
case 'SET_IS_EMAIL_LOOKUP_COMPLETED':
return { ...state, isEmailLookupCompleted: action.payload };
case 'SET_SHIPPING_ADDRESS':
return { ...state, shippingAddress: action.payload };
case 'SET_CARD_DETAILS':
return { ...state, cardDetails: action.payload };
default:
return state;
}
};
// Selectors
// Selectors.
const selectors = {
getIsGuest: ( state ) => state.isGuest,
getIsAxoActive: ( state ) => state.isAxoActive,
getIsAxoScriptLoaded: ( state ) => state.isAxoScriptLoaded,
getIsEmailSubmitted: ( state ) => state.isEmailSubmitted,
getIsEmailLookupCompleted: ( state ) => state.isEmailLookupCompleted,
getShippingAddress: ( state ) => state.shippingAddress,
getCardDetails: ( state ) => state.cardDetails,
};
// Create and register the store
// Create and register the store.
const store = createReduxStore( STORE_NAME, {
reducer,
actions,
@ -73,20 +87,19 @@ const store = createReduxStore( STORE_NAME, {
register( store );
// Action dispatchers.
export const setIsGuest = ( isGuest ) => {
try {
dispatch( STORE_NAME ).setIsGuest( isGuest );
} catch ( error ) {
console.error( 'Error updating isGuest state:', error );
}
dispatch( STORE_NAME ).setIsGuest( isGuest );
};
export const setIsEmailLookupCompleted = ( isEmailLookupCompleted ) => {
try {
dispatch( STORE_NAME ).setIsEmailLookupCompleted(
isEmailLookupCompleted
);
} catch ( error ) {
console.error( 'Error updating isEmailLookupCompleted state:', error );
}
dispatch( STORE_NAME ).setIsEmailLookupCompleted( isEmailLookupCompleted );
};
export const setShippingAddress = ( shippingAddress ) => {
dispatch( STORE_NAME ).setShippingAddress( shippingAddress );
};
export const setCardDetails = ( cardDetails ) => {
dispatch( STORE_NAME ).setCardDetails( cardDetails );
};