mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 10:55:00 +08:00
Add better state management utilizing Redux
This commit is contained in:
parent
db449b5d70
commit
bccfe4c436
11 changed files with 432 additions and 172 deletions
|
@ -11,7 +11,12 @@ const cardIcons = {
|
||||||
UNIONPAY: 'unionpay-light.svg',
|
UNIONPAY: 'unionpay-light.svg',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CreditCard = ( { card, shippingAddress, fastlaneSdk } ) => {
|
export const CreditCard = ( {
|
||||||
|
card,
|
||||||
|
shippingAddress,
|
||||||
|
fastlaneSdk,
|
||||||
|
showWatermark = true,
|
||||||
|
} ) => {
|
||||||
const { brand, lastDigits, expiry } = card?.paymentSource?.card ?? {};
|
const { brand, lastDigits, expiry } = card?.paymentSource?.card ?? {};
|
||||||
const { fullName } = shippingAddress?.name ?? {};
|
const { fullName } = shippingAddress?.name ?? {};
|
||||||
|
|
||||||
|
@ -48,11 +53,13 @@ export const CreditCard = ( { card, shippingAddress, fastlaneSdk } ) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="wc-block-checkout-axo-block-card__watermark">
|
<div className="wc-block-checkout-axo-block-card__watermark">
|
||||||
<FastlaneWatermark
|
{ showWatermark && (
|
||||||
fastlaneSdk={ fastlaneSdk }
|
<FastlaneWatermark
|
||||||
name="wc-block-checkout-axo-card-watermark"
|
fastlaneSdk={ fastlaneSdk }
|
||||||
includeAdditionalInfo={ false }
|
name="wc-block-checkout-axo-card-watermark"
|
||||||
/>
|
includeAdditionalInfo={ false }
|
||||||
|
/>
|
||||||
|
) }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,21 +1,46 @@
|
||||||
import { useEffect } from '@wordpress/element';
|
import { useEffect, useRef } from '@wordpress/element';
|
||||||
|
|
||||||
export const FastlaneWatermark = ( {
|
export const FastlaneWatermark = ( {
|
||||||
fastlaneSdk,
|
fastlaneSdk,
|
||||||
name = 'fastlane-watermark-container',
|
name = 'fastlane-watermark-container',
|
||||||
includeAdditionalInfo = true,
|
includeAdditionalInfo = true,
|
||||||
} ) => {
|
} ) => {
|
||||||
// This web component can be instantiated inside of a useEffect.
|
const containerRef = useRef( null );
|
||||||
useEffect( () => {
|
const watermarkRef = useRef( null );
|
||||||
( async () => {
|
|
||||||
const watermark = await fastlaneSdk.FastlaneWatermarkComponent( {
|
|
||||||
includeAdditionalInfo,
|
|
||||||
} );
|
|
||||||
// The ID can be a react element
|
|
||||||
watermark.render( `#${ name }` );
|
|
||||||
} )();
|
|
||||||
}, [] );
|
|
||||||
|
|
||||||
// Give the react element the ID that you will render the watermark component into.
|
useEffect( () => {
|
||||||
return <div id={ name } />;
|
const renderWatermark = async () => {
|
||||||
|
if ( ! containerRef.current ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the container
|
||||||
|
containerRef.current.innerHTML = '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const watermark = await fastlaneSdk.FastlaneWatermarkComponent(
|
||||||
|
{
|
||||||
|
includeAdditionalInfo,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watermarkRef.current = watermark;
|
||||||
|
watermark.render( `#${ name }` );
|
||||||
|
|
||||||
|
console.log( 'Watermark rendered successfully' );
|
||||||
|
} catch ( error ) {
|
||||||
|
console.error( 'Error rendering watermark:', error );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
renderWatermark();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if ( containerRef.current ) {
|
||||||
|
containerRef.current.innerHTML = '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [ fastlaneSdk, name, includeAdditionalInfo ] );
|
||||||
|
|
||||||
|
return <div id={ name } ref={ containerRef } />;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
import { useEffect, useCallback } from '@wordpress/element';
|
import { useEffect, useCallback } from '@wordpress/element';
|
||||||
|
import { useSelect } from '@wordpress/data';
|
||||||
import { CreditCard } from './CreditCard';
|
import { CreditCard } from './CreditCard';
|
||||||
|
import { STORE_NAME } from '../stores/axoStore';
|
||||||
|
|
||||||
export const Payment = ( {
|
export const Payment = ( {
|
||||||
fastlaneSdk,
|
fastlaneSdk,
|
||||||
card,
|
card,
|
||||||
shippingAddress,
|
shippingAddress,
|
||||||
isGuest,
|
|
||||||
onPaymentLoad,
|
onPaymentLoad,
|
||||||
} ) => {
|
} ) => {
|
||||||
|
const isGuest = useSelect( ( select ) =>
|
||||||
|
select( STORE_NAME ).getIsGuest()
|
||||||
|
);
|
||||||
|
|
||||||
// Memoized Fastlane card rendering
|
// Memoized Fastlane card rendering
|
||||||
const loadPaymentComponent = useCallback( async () => {
|
const loadPaymentComponent = useCallback( async () => {
|
||||||
if ( isGuest ) {
|
if ( isGuest ) {
|
||||||
|
@ -31,6 +36,7 @@ export const Payment = ( {
|
||||||
card={ card }
|
card={ card }
|
||||||
shippingAddress={ shippingAddress }
|
shippingAddress={ shippingAddress }
|
||||||
fastlaneSdk={ fastlaneSdk }
|
fastlaneSdk={ fastlaneSdk }
|
||||||
|
showWatermark={ ! isGuest }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { populateWooFields } from '../helpers/fieldHelpers';
|
import { populateWooFields } from '../helpers/fieldHelpers';
|
||||||
import { injectShippingChangeButton } from '../helpers/shippingChangeButtonManager';
|
import { injectShippingChangeButton } from '../helpers/shippingChangeButtonManager';
|
||||||
import { injectCardChangeButton } from '../helpers/cardChangeButtonManager';
|
import { injectCardChangeButton } from '../helpers/cardChangeButtonManager';
|
||||||
|
import { setIsGuest } from '../stores/axoStore';
|
||||||
|
|
||||||
|
// Handle the logic for email submission and customer data retrieval
|
||||||
export const onEmailSubmit = async (
|
export const onEmailSubmit = async (
|
||||||
email,
|
email,
|
||||||
fastlaneSdk,
|
fastlaneSdk,
|
||||||
setIsGuest,
|
|
||||||
isGuest,
|
|
||||||
setShippingAddress,
|
setShippingAddress,
|
||||||
setCard,
|
setCard,
|
||||||
snapshotFields,
|
snapshotFields,
|
||||||
|
@ -15,9 +15,7 @@ export const onEmailSubmit = async (
|
||||||
setWooShippingAddress,
|
setWooShippingAddress,
|
||||||
setWooBillingAddress,
|
setWooBillingAddress,
|
||||||
onChangeShippingAddressClick,
|
onChangeShippingAddressClick,
|
||||||
onChangeButtonClick,
|
onChangeButtonClick
|
||||||
shouldIncludeAdditionalInfo,
|
|
||||||
setShouldIncludeAdditionalInfo
|
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
console.log( 'Email value being looked up:', email );
|
console.log( 'Email value being looked up:', email );
|
||||||
|
@ -42,10 +40,11 @@ export const onEmailSubmit = async (
|
||||||
// Capture the existing WooCommerce data before updating it
|
// Capture the existing WooCommerce data before updating it
|
||||||
snapshotFields( wooShippingAddress, wooBillingAddress );
|
snapshotFields( wooShippingAddress, wooBillingAddress );
|
||||||
|
|
||||||
|
console.log( 'Setting isGuest to false' );
|
||||||
setIsGuest( false );
|
setIsGuest( false );
|
||||||
|
|
||||||
setShippingAddress( profileData.shippingAddress );
|
setShippingAddress( profileData.shippingAddress );
|
||||||
setCard( profileData.card );
|
setCard( profileData.card );
|
||||||
setShouldIncludeAdditionalInfo( false );
|
|
||||||
|
|
||||||
console.log( 'Profile Data:', profileData );
|
console.log( 'Profile Data:', profileData );
|
||||||
|
|
|
@ -56,6 +56,7 @@ export const injectCardChangeButton = ( onChangeButtonClick ) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeCardChangeButton = () => {
|
export const removeCardChangeButton = () => {
|
||||||
|
console.log('removeCardChangeButton running');
|
||||||
const button = document.querySelector(
|
const button = document.querySelector(
|
||||||
'.wc-block-checkout-axo-block-card__edit'
|
'.wc-block-checkout-axo-block-card__edit'
|
||||||
);
|
);
|
||||||
|
|
57
modules/ppcp-axo-block/resources/js/helpers/emailHelpers.js
Normal file
57
modules/ppcp-axo-block/resources/js/helpers/emailHelpers.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
let emailInput = null;
|
||||||
|
let currentHandler = null;
|
||||||
|
|
||||||
|
const getEmailInput = () => {
|
||||||
|
if ( ! emailInput ) {
|
||||||
|
emailInput = document.getElementById( 'email' );
|
||||||
|
}
|
||||||
|
return emailInput;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setupEmailEvent = ( onEmailSubmit ) => {
|
||||||
|
const input = getEmailInput();
|
||||||
|
if ( ! input ) {
|
||||||
|
console.warn(
|
||||||
|
'Email input element not found. Event listener not added.'
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( currentHandler ) {
|
||||||
|
console.warn(
|
||||||
|
'Email event listener already exists. Removing old listener before adding new one.'
|
||||||
|
);
|
||||||
|
removeEmailEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleEmailInput = async ( event ) => {
|
||||||
|
const email = event.target.value;
|
||||||
|
if ( email ) {
|
||||||
|
await onEmailSubmit( email );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
input.addEventListener( 'keyup', handleEmailInput );
|
||||||
|
currentHandler = handleEmailInput;
|
||||||
|
console.log( 'Email event listener added' );
|
||||||
|
};
|
||||||
|
|
||||||
|
export const removeEmailEvent = () => {
|
||||||
|
const input = getEmailInput();
|
||||||
|
if ( input && currentHandler ) {
|
||||||
|
input.removeEventListener( 'keyup', currentHandler );
|
||||||
|
currentHandler = null;
|
||||||
|
console.log( 'Email event listener removed' );
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
'Could not remove email event listener. Input:',
|
||||||
|
input,
|
||||||
|
'Handler:',
|
||||||
|
currentHandler
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isEmailEventSetup = () => {
|
||||||
|
return !! currentHandler;
|
||||||
|
};
|
|
@ -56,13 +56,24 @@ const ShippingChangeButtonManager = ( { onChangeShippingAddressClick } ) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const injectShippingChangeButton = ( onChangeShippingAddressClick ) => {
|
export const injectShippingChangeButton = ( onChangeShippingAddressClick ) => {
|
||||||
const container = document.createElement( 'div' );
|
// Check if the button already exists
|
||||||
document.body.appendChild( container );
|
const existingButton = document.querySelector(
|
||||||
createRoot( container ).render(
|
'#shipping-fields .wc-block-checkout-axo-block-card__edit'
|
||||||
createElement( ShippingChangeButtonManager, {
|
|
||||||
onChangeShippingAddressClick,
|
|
||||||
} )
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ( ! existingButton ) {
|
||||||
|
const container = document.createElement( 'div' );
|
||||||
|
document.body.appendChild( container );
|
||||||
|
createRoot( container ).render(
|
||||||
|
createElement( ShippingChangeButtonManager, {
|
||||||
|
onChangeShippingAddressClick,
|
||||||
|
} )
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
'Shipping change button already exists. Skipping injection.'
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeShippingChangeButton = () => {
|
export const removeShippingChangeButton = () => {
|
||||||
|
|
|
@ -1,96 +1,91 @@
|
||||||
import { createElement, useEffect, createRoot } from '@wordpress/element';
|
import { createElement, useEffect, createRoot } from '@wordpress/element';
|
||||||
|
import { useSelect } from '@wordpress/data';
|
||||||
import { FastlaneWatermark } from '../components/FastlaneWatermark';
|
import { FastlaneWatermark } from '../components/FastlaneWatermark';
|
||||||
|
import { STORE_NAME } from '../stores/axoStore';
|
||||||
|
|
||||||
|
let watermarkReference = {
|
||||||
|
container: null,
|
||||||
|
root: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const WatermarkManager = ( { fastlaneSdk } ) => {
|
||||||
|
const isGuest = useSelect( ( select ) =>
|
||||||
|
select( STORE_NAME ).getIsGuest()
|
||||||
|
);
|
||||||
|
const isAxoActive = useSelect( ( select ) =>
|
||||||
|
select( STORE_NAME ).getIsAxoActive()
|
||||||
|
);
|
||||||
|
|
||||||
const WatermarkManager = ( {
|
|
||||||
fastlaneSdk,
|
|
||||||
shouldIncludeAdditionalInfo,
|
|
||||||
onEmailSubmit,
|
|
||||||
} ) => {
|
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
const emailInput = document.getElementById( 'email' );
|
const emailInput = document.getElementById( 'email' );
|
||||||
let watermarkRoot = null;
|
|
||||||
let watermarkContainer = null;
|
|
||||||
|
|
||||||
if ( emailInput ) {
|
if ( emailInput ) {
|
||||||
const emailLabel =
|
if ( ! watermarkReference.container ) {
|
||||||
emailInput.parentNode.querySelector( 'label[for="email"]' );
|
watermarkReference.container = document.createElement( 'div' );
|
||||||
watermarkContainer = document.createElement( 'div' );
|
watermarkReference.container.setAttribute(
|
||||||
watermarkContainer.setAttribute(
|
'class',
|
||||||
'class',
|
'ppcp-axo-block-watermark-container'
|
||||||
'ppcp-axo-block-watermark-container'
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( emailLabel ) {
|
|
||||||
emailLabel.parentNode.insertBefore(
|
|
||||||
watermarkContainer,
|
|
||||||
emailLabel.nextSibling
|
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
emailInput.parentNode.appendChild( watermarkContainer );
|
|
||||||
}
|
|
||||||
|
|
||||||
watermarkRoot = createRoot( watermarkContainer );
|
const emailLabel =
|
||||||
watermarkRoot.render(
|
emailInput.parentNode.querySelector( 'label[for="email"]' );
|
||||||
createElement( FastlaneWatermark, {
|
if ( emailLabel ) {
|
||||||
fastlaneSdk,
|
emailLabel.parentNode.insertBefore(
|
||||||
name: 'fastlane-watermark-email',
|
watermarkReference.container,
|
||||||
includeAdditionalInfo: shouldIncludeAdditionalInfo,
|
emailLabel.nextSibling
|
||||||
} )
|
);
|
||||||
);
|
} else {
|
||||||
|
emailInput.parentNode.insertBefore(
|
||||||
const handleEmailInput = async ( event ) => {
|
watermarkReference.container,
|
||||||
const email = event.target.value;
|
emailInput.nextSibling
|
||||||
if ( email ) {
|
|
||||||
await onEmailSubmit( email );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
emailInput.addEventListener( 'keyup', handleEmailInput );
|
|
||||||
|
|
||||||
// Cleanup function
|
|
||||||
return () => {
|
|
||||||
if ( watermarkRoot ) {
|
|
||||||
watermarkRoot.unmount();
|
|
||||||
}
|
|
||||||
if ( watermarkContainer && watermarkContainer.parentNode ) {
|
|
||||||
watermarkContainer.parentNode.removeChild(
|
|
||||||
watermarkContainer
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ( emailInput ) {
|
|
||||||
emailInput.removeEventListener( 'keyup', handleEmailInput );
|
watermarkReference.root = createRoot(
|
||||||
}
|
watermarkReference.container
|
||||||
console.log( 'Fastlane watermark removed' );
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
if ( watermarkReference.root && isAxoActive ) {
|
||||||
|
watermarkReference.root.render(
|
||||||
|
createElement( FastlaneWatermark, {
|
||||||
|
fastlaneSdk,
|
||||||
|
name: 'fastlane-watermark-email',
|
||||||
|
includeAdditionalInfo: isGuest,
|
||||||
|
} )
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.warn( 'Watermark root not found' );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn( 'Email input not found' );
|
||||||
}
|
}
|
||||||
}, [ fastlaneSdk, shouldIncludeAdditionalInfo, onEmailSubmit ] );
|
}, [ fastlaneSdk, isGuest ] );
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setupWatermark = (
|
export const setupWatermark = ( fastlaneSdk ) => {
|
||||||
fastlaneSdk,
|
|
||||||
shouldIncludeAdditionalInfo,
|
|
||||||
onEmailSubmit
|
|
||||||
) => {
|
|
||||||
const container = document.createElement( 'div' );
|
const container = document.createElement( 'div' );
|
||||||
document.body.appendChild( container );
|
document.body.appendChild( container );
|
||||||
createRoot( container ).render(
|
createRoot( container ).render(
|
||||||
createElement( WatermarkManager, {
|
createElement( WatermarkManager, { fastlaneSdk } )
|
||||||
fastlaneSdk,
|
|
||||||
shouldIncludeAdditionalInfo,
|
|
||||||
onEmailSubmit,
|
|
||||||
} )
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeWatermark = () => {
|
export const removeWatermark = () => {
|
||||||
const watermarkContainer = document.querySelector(
|
if ( watermarkReference.root ) {
|
||||||
'.ppcp-axo-block-watermark-container'
|
watermarkReference.root.unmount();
|
||||||
);
|
|
||||||
if ( watermarkContainer && watermarkContainer.parentNode ) {
|
|
||||||
watermarkContainer.parentNode.removeChild( watermarkContainer );
|
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
watermarkReference.container &&
|
||||||
|
watermarkReference.container.parentNode
|
||||||
|
) {
|
||||||
|
watermarkReference.container.parentNode.removeChild(
|
||||||
|
watermarkReference.container
|
||||||
|
);
|
||||||
|
}
|
||||||
|
watermarkReference = { container: null, root: null };
|
||||||
};
|
};
|
||||||
|
|
||||||
export default WatermarkManager;
|
export default WatermarkManager;
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { useCallback } from '@wordpress/element';
|
||||||
|
|
||||||
|
export const useShippingAddressChange = (
|
||||||
|
fastlaneSdk,
|
||||||
|
setShippingAddress,
|
||||||
|
setWooShippingAddress
|
||||||
|
) => {
|
||||||
|
return useCallback( async () => {
|
||||||
|
if ( fastlaneSdk ) {
|
||||||
|
const { selectionChanged, selectedAddress } =
|
||||||
|
await fastlaneSdk.profile.showShippingAddressSelector();
|
||||||
|
if ( selectionChanged ) {
|
||||||
|
setShippingAddress( selectedAddress );
|
||||||
|
console.log(
|
||||||
|
'Selected shipping address changed:',
|
||||||
|
selectedAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
const { address, name, phoneNumber } = selectedAddress;
|
||||||
|
|
||||||
|
setWooShippingAddress( {
|
||||||
|
first_name: name.firstName,
|
||||||
|
last_name: name.lastName,
|
||||||
|
address_1: address.addressLine1,
|
||||||
|
address_2: address.addressLine2 || '',
|
||||||
|
city: address.adminArea2,
|
||||||
|
state: address.adminArea1,
|
||||||
|
postcode: address.postalCode,
|
||||||
|
country: address.countryCode,
|
||||||
|
phone: phoneNumber.nationalNumber,
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [ fastlaneSdk, setShippingAddress, setWooShippingAddress ] );
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useCardChange = ( fastlaneSdk, setCard ) => {
|
||||||
|
return useCallback( async () => {
|
||||||
|
if ( fastlaneSdk ) {
|
||||||
|
const { selectionChanged, selectedCard } =
|
||||||
|
await fastlaneSdk.profile.showCardSelector();
|
||||||
|
if ( selectionChanged ) {
|
||||||
|
setCard( selectedCard );
|
||||||
|
console.log( 'Selected card changed:', selectedCard );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [ fastlaneSdk, setCard ] );
|
||||||
|
};
|
|
@ -1,4 +1,6 @@
|
||||||
import { useCallback, useEffect, useState } from '@wordpress/element';
|
import { useCallback, useEffect, useState, useRef } from '@wordpress/element';
|
||||||
|
import { useSelect, useDispatch } from '@wordpress/data';
|
||||||
|
|
||||||
import { registerPaymentMethod } from '@woocommerce/blocks-registry';
|
import { registerPaymentMethod } from '@woocommerce/blocks-registry';
|
||||||
|
|
||||||
import { loadPaypalScript } from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading';
|
import { loadPaypalScript } from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading';
|
||||||
|
@ -6,18 +8,30 @@ import { loadPaypalScript } from '../../../ppcp-button/resources/js/modules/Help
|
||||||
// Hooks
|
// Hooks
|
||||||
import useAxoBlockManager from './hooks/useAxoBlockManager';
|
import useAxoBlockManager from './hooks/useAxoBlockManager';
|
||||||
import { useCustomerData } from './hooks/useCustomerData';
|
import { useCustomerData } from './hooks/useCustomerData';
|
||||||
|
import {
|
||||||
|
useShippingAddressChange,
|
||||||
|
useCardChange,
|
||||||
|
} from './hooks/useUserInfoChange';
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import { Payment } from './components/Payment';
|
import { Payment } from './components/Payment';
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
import { snapshotFields, restoreOriginalFields } from './helpers/fieldHelpers';
|
import { snapshotFields, restoreOriginalFields } from './helpers/fieldHelpers';
|
||||||
import { setupWatermark, removeWatermark } from './helpers/watermarkHelpers';
|
import { removeWatermark, setupWatermark } from './helpers/watermarkHelpers';
|
||||||
import { removeCardChangeButton } from './helpers/cardChangeButtonManager';
|
import { removeCardChangeButton } from './helpers/cardChangeButtonManager';
|
||||||
import { removeShippingChangeButton } from './helpers/shippingChangeButtonManager';
|
import { removeShippingChangeButton } from './helpers/shippingChangeButtonManager';
|
||||||
|
|
||||||
|
// Stores
|
||||||
|
import { STORE_NAME } from './stores/axoStore';
|
||||||
|
|
||||||
// Event handlers
|
// Event handlers
|
||||||
import { onEmailSubmit } from './events/fastlaneEmailManager';
|
import { onEmailSubmit } from './events/emailLookupManager';
|
||||||
|
import {
|
||||||
|
setupEmailEvent,
|
||||||
|
removeEmailEvent,
|
||||||
|
isEmailEventSetup,
|
||||||
|
} from './helpers/emailHelpers';
|
||||||
|
|
||||||
const ppcpConfig = wc.wcSettings.getSetting( 'ppcp-credit-card-gateway_data' );
|
const ppcpConfig = wc.wcSettings.getSetting( 'ppcp-credit-card-gateway_data' );
|
||||||
|
|
||||||
|
@ -29,13 +43,17 @@ const axoConfig = window.wc_ppcp_axo;
|
||||||
|
|
||||||
const Axo = () => {
|
const Axo = () => {
|
||||||
const [ paypalLoaded, setPaypalLoaded ] = useState( false );
|
const [ paypalLoaded, setPaypalLoaded ] = useState( false );
|
||||||
const [ isGuest, setIsGuest ] = useState( true );
|
|
||||||
const [ shippingAddress, setShippingAddress ] = useState( null );
|
const [ shippingAddress, setShippingAddress ] = useState( null );
|
||||||
const [ card, setCard ] = useState( null );
|
const [ card, setCard ] = useState( null );
|
||||||
const [ shouldIncludeAdditionalInfo, setShouldIncludeAdditionalInfo ] =
|
|
||||||
useState( true );
|
|
||||||
const fastlaneSdk = useAxoBlockManager( axoConfig, ppcpConfig );
|
const fastlaneSdk = useAxoBlockManager( axoConfig, ppcpConfig );
|
||||||
|
|
||||||
|
const isAxoActive = useSelect( ( select ) =>
|
||||||
|
select( STORE_NAME ).getIsAxoActive()
|
||||||
|
);
|
||||||
|
const { setIsAxoActive, setIsGuest } = useDispatch( STORE_NAME );
|
||||||
|
|
||||||
|
const handleEmailInputRef = useRef( null );
|
||||||
|
|
||||||
// Access WooCommerce customer data
|
// Access WooCommerce customer data
|
||||||
const {
|
const {
|
||||||
shippingAddress: wooShippingAddress,
|
shippingAddress: wooShippingAddress,
|
||||||
|
@ -44,13 +62,12 @@ const Axo = () => {
|
||||||
setBillingAddress: updateWooBillingAddress,
|
setBillingAddress: updateWooBillingAddress,
|
||||||
} = useCustomerData();
|
} = useCustomerData();
|
||||||
|
|
||||||
// Cleanup logic for Change buttons
|
useEffect( () => {
|
||||||
|
console.log( 'isAxoActive updated:', isAxoActive );
|
||||||
|
}, [ isAxoActive ] );
|
||||||
|
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
return () => {
|
return () => {
|
||||||
removeShippingChangeButton();
|
|
||||||
removeCardChangeButton();
|
|
||||||
removeWatermark();
|
|
||||||
|
|
||||||
// Restore WooCommerce fields
|
// Restore WooCommerce fields
|
||||||
restoreOriginalFields(
|
restoreOriginalFields(
|
||||||
updateWooShippingAddress,
|
updateWooShippingAddress,
|
||||||
|
@ -74,75 +91,111 @@ const Axo = () => {
|
||||||
}
|
}
|
||||||
}, [ paypalLoaded, ppcpConfig ] );
|
}, [ paypalLoaded, ppcpConfig ] );
|
||||||
|
|
||||||
|
const onChangeShippingAddressClick = useShippingAddressChange(
|
||||||
|
fastlaneSdk,
|
||||||
|
setShippingAddress,
|
||||||
|
updateWooShippingAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
const onChangeCardButtonClick = useCardChange( fastlaneSdk, setCard );
|
||||||
|
|
||||||
|
const handleEmailInput = useCallback(
|
||||||
|
async ( email ) => {
|
||||||
|
if ( fastlaneSdk ) {
|
||||||
|
await onEmailSubmit(
|
||||||
|
email,
|
||||||
|
fastlaneSdk,
|
||||||
|
setShippingAddress,
|
||||||
|
setCard,
|
||||||
|
snapshotFields,
|
||||||
|
wooShippingAddress,
|
||||||
|
wooBillingAddress,
|
||||||
|
setWooShippingAddress,
|
||||||
|
setWooBillingAddress,
|
||||||
|
onChangeShippingAddressClick,
|
||||||
|
onChangeCardButtonClick
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.warn( 'FastLane SDK is not available' );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
fastlaneSdk,
|
||||||
|
setShippingAddress,
|
||||||
|
setCard,
|
||||||
|
wooShippingAddress,
|
||||||
|
wooBillingAddress,
|
||||||
|
setWooShippingAddress,
|
||||||
|
setWooBillingAddress,
|
||||||
|
onChangeShippingAddressClick,
|
||||||
|
onChangeCardButtonClick,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect( () => {
|
||||||
|
handleEmailInputRef.current = handleEmailInput;
|
||||||
|
}, [ handleEmailInput ] );
|
||||||
|
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
if ( paypalLoaded && fastlaneSdk ) {
|
if ( paypalLoaded && fastlaneSdk ) {
|
||||||
console.log( 'Fastlane SDK and PayPal loaded' );
|
console.log( 'Enabling Axo' );
|
||||||
setupWatermark(
|
setIsAxoActive( true );
|
||||||
fastlaneSdk,
|
setupWatermark( fastlaneSdk );
|
||||||
shouldIncludeAdditionalInfo,
|
setupEmailEvent( handleEmailInputRef.current );
|
||||||
async ( email ) => {
|
|
||||||
await onEmailSubmit(
|
|
||||||
email,
|
|
||||||
fastlaneSdk,
|
|
||||||
setIsGuest,
|
|
||||||
isGuest,
|
|
||||||
setShippingAddress,
|
|
||||||
setCard,
|
|
||||||
snapshotFields,
|
|
||||||
wooShippingAddress,
|
|
||||||
wooBillingAddress,
|
|
||||||
setWooShippingAddress,
|
|
||||||
setWooBillingAddress,
|
|
||||||
onChangeShippingAddressClick,
|
|
||||||
onChangeButtonClick,
|
|
||||||
shouldIncludeAdditionalInfo,
|
|
||||||
setShouldIncludeAdditionalInfo
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
}, [ paypalLoaded, fastlaneSdk, setIsAxoActive ] );
|
||||||
|
|
||||||
|
useEffect( () => {
|
||||||
return () => {
|
return () => {
|
||||||
|
console.log( 'Disabling Axo' );
|
||||||
|
console.log( 'Axo component unmounting' );
|
||||||
|
setIsAxoActive( false );
|
||||||
|
setIsGuest( true );
|
||||||
|
|
||||||
|
console.log( 'isAxoActive', isAxoActive );
|
||||||
|
|
||||||
|
console.log( 'isEmailEventSetup', isEmailEventSetup() );
|
||||||
|
|
||||||
|
removeShippingChangeButton();
|
||||||
|
removeCardChangeButton();
|
||||||
removeWatermark();
|
removeWatermark();
|
||||||
};
|
|
||||||
}, [ paypalLoaded, fastlaneSdk, shouldIncludeAdditionalInfo ] );
|
|
||||||
|
|
||||||
const onChangeShippingAddressClick = useCallback( async () => {
|
if ( isEmailEventSetup() ) {
|
||||||
// Updated
|
|
||||||
if ( fastlaneSdk ) {
|
|
||||||
const { selectionChanged, selectedAddress } =
|
|
||||||
await fastlaneSdk.profile.showShippingAddressSelector();
|
|
||||||
if ( selectionChanged ) {
|
|
||||||
setShippingAddress( selectedAddress );
|
|
||||||
console.log(
|
console.log(
|
||||||
'Selected shipping address changed:',
|
'Axo became inactive, removing email event listener'
|
||||||
selectedAddress
|
|
||||||
);
|
);
|
||||||
|
removeEmailEvent( handleEmailInputRef.current );
|
||||||
const { address, name, phoneNumber } = selectedAddress;
|
|
||||||
|
|
||||||
setWooShippingAddress( {
|
|
||||||
first_name: name.firstName,
|
|
||||||
last_name: name.lastName,
|
|
||||||
address_1: address.addressLine1,
|
|
||||||
address_2: address.addressLine2 || '',
|
|
||||||
city: address.adminArea2,
|
|
||||||
state: address.adminArea1,
|
|
||||||
postcode: address.postalCode,
|
|
||||||
country: address.countryCode,
|
|
||||||
phone: phoneNumber.nationalNumber,
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}, [ fastlaneSdk, setWooShippingAddress ] );
|
}, [
|
||||||
|
setIsAxoActive,
|
||||||
|
setIsGuest,
|
||||||
|
updateWooShippingAddress,
|
||||||
|
updateWooBillingAddress,
|
||||||
|
] );
|
||||||
|
|
||||||
const onChangeButtonClick = useCallback( async () => {
|
useEffect( () => {
|
||||||
const { selectionChanged, selectedCard } =
|
return () => {
|
||||||
await fastlaneSdk.profile.showCardSelector();
|
console.log( 'Disabling Axo' );
|
||||||
if ( selectionChanged ) {
|
setIsAxoActive( false );
|
||||||
setCard( selectedCard );
|
setIsGuest( true );
|
||||||
}
|
|
||||||
}, [ fastlaneSdk ] );
|
console.log( 'isAxoActive', isAxoActive );
|
||||||
|
|
||||||
|
console.log( 'isEmailEventSetup', isEmailEventSetup() );
|
||||||
|
|
||||||
|
removeShippingChangeButton();
|
||||||
|
removeCardChangeButton();
|
||||||
|
removeWatermark();
|
||||||
|
|
||||||
|
if ( isEmailEventSetup() ) {
|
||||||
|
console.log(
|
||||||
|
'Axo became inactive, removing email event listener'
|
||||||
|
);
|
||||||
|
removeEmailEvent( handleEmailInputRef.current );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [] );
|
||||||
|
|
||||||
const handlePaymentLoad = useCallback(
|
const handlePaymentLoad = useCallback(
|
||||||
( paymentComponent ) => {
|
( paymentComponent ) => {
|
||||||
|
@ -162,9 +215,8 @@ const Axo = () => {
|
||||||
card={ card }
|
card={ card }
|
||||||
shippingAddress={ shippingAddress }
|
shippingAddress={ shippingAddress }
|
||||||
onChange={ handleChange }
|
onChange={ handleChange }
|
||||||
isGuest={ isGuest }
|
|
||||||
onPaymentLoad={ handlePaymentLoad }
|
onPaymentLoad={ handlePaymentLoad }
|
||||||
onChangeButtonClick={ onChangeButtonClick }
|
onChangeButtonClick={ onChangeCardButtonClick }
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div>Loading Fastlane...</div>
|
<div>Loading Fastlane...</div>
|
||||||
|
|
59
modules/ppcp-axo-block/resources/js/stores/axoStore.js
Normal file
59
modules/ppcp-axo-block/resources/js/stores/axoStore.js
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
// File: axoStore.js
|
||||||
|
|
||||||
|
import { createReduxStore, register, dispatch } from '@wordpress/data';
|
||||||
|
|
||||||
|
export const STORE_NAME = 'woocommerce-paypal-payments/axo-block';
|
||||||
|
|
||||||
|
// Initial state
|
||||||
|
const DEFAULT_STATE = {
|
||||||
|
isGuest: true,
|
||||||
|
isAxoActive: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
const actions = {
|
||||||
|
setIsGuest: ( isGuest ) => ( {
|
||||||
|
type: 'SET_IS_GUEST',
|
||||||
|
payload: isGuest,
|
||||||
|
} ),
|
||||||
|
setIsAxoActive: ( isAxoActive ) => ( {
|
||||||
|
type: 'SET_IS_AXO_ACTIVE',
|
||||||
|
payload: isAxoActive,
|
||||||
|
} ),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reducer
|
||||||
|
const reducer = ( state = DEFAULT_STATE, action ) => {
|
||||||
|
switch ( action.type ) {
|
||||||
|
case 'SET_IS_GUEST':
|
||||||
|
return { ...state, isGuest: action.payload };
|
||||||
|
case 'SET_IS_AXO_ACTIVE':
|
||||||
|
return { ...state, isAxoActive: action.payload };
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
const selectors = {
|
||||||
|
getIsGuest: ( state ) => state.isGuest,
|
||||||
|
getIsAxoActive: ( state ) => state.isAxoActive,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create and register the store
|
||||||
|
const store = createReduxStore( STORE_NAME, {
|
||||||
|
reducer,
|
||||||
|
actions,
|
||||||
|
selectors,
|
||||||
|
} );
|
||||||
|
|
||||||
|
register( store );
|
||||||
|
|
||||||
|
// Utility functions
|
||||||
|
export const setIsGuest = ( isGuest ) => {
|
||||||
|
try {
|
||||||
|
dispatch( STORE_NAME ).setIsGuest( isGuest );
|
||||||
|
} catch ( error ) {
|
||||||
|
console.error( 'Error updating isGuest state:', error );
|
||||||
|
}
|
||||||
|
};
|
Loading…
Add table
Add a link
Reference in a new issue