diff --git a/modules/ppcp-axo-block/resources/js/components/AxoBlock.js b/modules/ppcp-axo-block/resources/js/components/AxoBlock.js index 1a1e91dff..3e243c4c8 100644 --- a/modules/ppcp-axo-block/resources/js/components/AxoBlock.js +++ b/modules/ppcp-axo-block/resources/js/components/AxoBlock.js @@ -1,6 +1,6 @@ import { useEffect, useState } from '@wordpress/element'; import { useCustomerData } from './useCustomerData'; -import { ShippingChangeButton } from './ShippingChangeButton'; +import { ShippingChangeButton } from './shippingChangeButtonManager'; import { loadPaypalScript } from '../utils/ScriptLoading'; import Payment from './Payment'; import useAxoBlockManager from './useAxoBlockManager'; diff --git a/modules/ppcp-axo-block/resources/js/components/ShippingChangeButton.js b/modules/ppcp-axo-block/resources/js/components/ShippingChangeButton.js deleted file mode 100644 index 5c5aaa467..000000000 --- a/modules/ppcp-axo-block/resources/js/components/ShippingChangeButton.js +++ /dev/null @@ -1,41 +0,0 @@ -import { useEffect } from '@wordpress/element'; - -// Inject the change button next to the Shipping title -const injectShippingChangeButton = ( onChangeShippingAddressClick ) => { - const shippingTitle = document.querySelector( - '#shipping-fields h2.wc-block-components-title' - ); - - if ( - shippingTitle && - ! shippingTitle.nextElementSibling?.classList?.contains( - 'wc-block-checkout-axo-block-card__edit' - ) - ) { - const buttonElement = document.createElement( 'button' ); - buttonElement.classList.add( 'wc-block-checkout-axo-block-card__edit' ); - buttonElement.setAttribute( 'aria-label', 'Change shipping details' ); - buttonElement.textContent = 'Change'; - buttonElement.onclick = ( event ) => { - event.preventDefault(); - onChangeShippingAddressClick(); - }; - - // Ensure the button is inserted correctly after the shipping title - shippingTitle.parentNode.insertBefore( - buttonElement, - shippingTitle.nextSibling - ); - } -}; - -// ShippingChangeButton component for injecting the button -const ShippingChangeButton = ( { onChangeShippingAddressClick } ) => { - useEffect( () => { - injectShippingChangeButton( onChangeShippingAddressClick ); - }, [ onChangeShippingAddressClick ] ); - - return null; -}; - -export default ShippingChangeButton; diff --git a/modules/ppcp-axo-block/resources/js/events/fastlaneEmailManager.js b/modules/ppcp-axo-block/resources/js/events/fastlaneEmailManager.js index ba0808d88..940e817c0 100644 --- a/modules/ppcp-axo-block/resources/js/events/fastlaneEmailManager.js +++ b/modules/ppcp-axo-block/resources/js/events/fastlaneEmailManager.js @@ -1,6 +1,6 @@ -import { injectShippingChangeButton } from '../helpers/buttonHelpers'; import { populateWooFields } from '../helpers/fieldHelpers'; -import { injectCardChangeButton } from '../helpers/gatewayRadioHelpers'; +import { injectShippingChangeButton } from '../helpers/shippingChangeButtonManager'; +import { injectCardChangeButton } from '../helpers/cardChangeButtonManager'; export const onEmailSubmit = async ( email, @@ -44,7 +44,6 @@ export const onEmailSubmit = async ( setIsGuest( false ); setShippingAddress( profileData.shippingAddress ); - injectShippingChangeButton( onChangeShippingAddressClick ); setCard( profileData.card ); setShouldIncludeAdditionalInfo( false ); @@ -56,6 +55,7 @@ export const onEmailSubmit = async ( setWooBillingAddress ); + injectShippingChangeButton( onChangeShippingAddressClick ); injectCardChangeButton( onChangeButtonClick ); } else { console.warn( 'Authentication failed or did not succeed' ); diff --git a/modules/ppcp-axo-block/resources/js/helpers/gatewayRadioHelpers.js b/modules/ppcp-axo-block/resources/js/helpers/cardChangeButtonManager.js similarity index 87% rename from modules/ppcp-axo-block/resources/js/helpers/gatewayRadioHelpers.js rename to modules/ppcp-axo-block/resources/js/helpers/cardChangeButtonManager.js index ac82d6f17..382bee669 100644 --- a/modules/ppcp-axo-block/resources/js/helpers/gatewayRadioHelpers.js +++ b/modules/ppcp-axo-block/resources/js/helpers/cardChangeButtonManager.js @@ -55,4 +55,13 @@ export const injectCardChangeButton = ( onChangeButtonClick ) => { ); }; +export const removeCardChangeButton = () => { + const button = document.querySelector( + '.wc-block-checkout-axo-block-card__edit' + ); + if ( button && button.parentNode ) { + button.parentNode.remove(); + } +}; + export default CardChangeButtonManager; diff --git a/modules/ppcp-axo-block/resources/js/helpers/shippingChangeButtonManager.js b/modules/ppcp-axo-block/resources/js/helpers/shippingChangeButtonManager.js new file mode 100644 index 000000000..a10b3baa5 --- /dev/null +++ b/modules/ppcp-axo-block/resources/js/helpers/shippingChangeButtonManager.js @@ -0,0 +1,77 @@ +import { createElement, useEffect, createRoot } from '@wordpress/element'; + +const ShippingChangeButton = ( { onChangeShippingAddressClick } ) => + createElement( + 'button', + { + className: 'wc-block-checkout-axo-block-card__edit', + 'aria-label': 'Change shipping details', + type: 'button', + onClick: ( event ) => { + event.preventDefault(); + onChangeShippingAddressClick(); + }, + }, + 'Change' + ); + +const ShippingChangeButtonManager = ( { onChangeShippingAddressClick } ) => { + useEffect( () => { + const shippingTitle = document.querySelector( + '#shipping-fields h2.wc-block-components-title' + ); + + if ( shippingTitle ) { + if ( + ! shippingTitle.nextElementSibling?.classList?.contains( + 'wc-block-checkout-axo-block-card__edit' + ) + ) { + const buttonContainer = document.createElement( 'span' ); + shippingTitle.parentNode.insertBefore( + buttonContainer, + shippingTitle.nextSibling + ); + + const root = createRoot( buttonContainer ); + root.render( + createElement( ShippingChangeButton, { + onChangeShippingAddressClick, + } ) + ); + } + } + + return () => { + const button = document.querySelector( + '#shipping-fields .wc-block-checkout-axo-block-card__edit' + ); + if ( button && button.parentNode ) { + button.parentNode.remove(); + } + }; + }, [ onChangeShippingAddressClick ] ); + + return null; +}; + +export const injectShippingChangeButton = ( onChangeShippingAddressClick ) => { + const container = document.createElement( 'div' ); + document.body.appendChild( container ); + createRoot( container ).render( + createElement( ShippingChangeButtonManager, { + onChangeShippingAddressClick, + } ) + ); +}; + +export const removeShippingChangeButton = () => { + const button = document.querySelector( + '#shipping-fields .wc-block-checkout-axo-block-card__edit' + ); + if ( button && button.parentNode ) { + button.parentNode.remove(); + } +}; + +export default ShippingChangeButtonManager; diff --git a/modules/ppcp-axo-block/resources/js/helpers/watermarkHelpers.js b/modules/ppcp-axo-block/resources/js/helpers/watermarkHelpers.js index 870b93e63..aaa2ae655 100644 --- a/modules/ppcp-axo-block/resources/js/helpers/watermarkHelpers.js +++ b/modules/ppcp-axo-block/resources/js/helpers/watermarkHelpers.js @@ -1,62 +1,96 @@ -import ReactDOM from 'react-dom/client'; +import { createElement, useEffect, createRoot } from '@wordpress/element'; import { FastlaneWatermark } from '../components/FastlaneWatermark'; -export const setupWatermark = ( fastlaneSdk, shouldIncludeAdditionalInfo ) => { - const emailInput = document.getElementById( 'email' ); - let watermarkRoot = null; - let watermarkContainer = null; - - if ( emailInput ) { - const emailLabel = - emailInput.parentNode.querySelector( 'label[for="email"]' ); - watermarkContainer = document.createElement( 'div' ); - watermarkContainer.setAttribute( - 'class', - 'ppcp-axo-block-watermark-container' - ); - - if ( emailLabel ) { - emailLabel.parentNode.insertBefore( - watermarkContainer, - emailLabel.nextSibling - ); - } else { - emailInput.parentNode.appendChild( watermarkContainer ); - } - - const watermarkElement = document.createElement( 'div' ); - watermarkContainer.appendChild( watermarkElement ); - - watermarkRoot = ReactDOM.createRoot( watermarkElement ); - watermarkRoot.render( - - ); - } - - return { watermarkRoot, watermarkContainer, emailInput }; -}; - -export const cleanupWatermark = ( { - watermarkRoot, - watermarkContainer, - emailInput, +const WatermarkManager = ( { + fastlaneSdk, + shouldIncludeAdditionalInfo, onEmailSubmit, } ) => { - if ( watermarkRoot && watermarkContainer ) { - watermarkRoot.unmount(); - watermarkContainer.parentNode.removeChild( watermarkContainer ); - console.log( 'Fastlane watermark removed' ); - } - if ( emailInput ) { - emailInput.removeEventListener( 'keyup', async ( event ) => { - const email = event.target.value; - if ( email ) { - await onEmailSubmit( email ); + useEffect( () => { + const emailInput = document.getElementById( 'email' ); + let watermarkRoot = null; + let watermarkContainer = null; + + if ( emailInput ) { + const emailLabel = + emailInput.parentNode.querySelector( 'label[for="email"]' ); + watermarkContainer = document.createElement( 'div' ); + watermarkContainer.setAttribute( + 'class', + 'ppcp-axo-block-watermark-container' + ); + + if ( emailLabel ) { + emailLabel.parentNode.insertBefore( + watermarkContainer, + emailLabel.nextSibling + ); + } else { + emailInput.parentNode.appendChild( watermarkContainer ); } - } ); + + watermarkRoot = createRoot( watermarkContainer ); + watermarkRoot.render( + createElement( FastlaneWatermark, { + fastlaneSdk, + name: 'fastlane-watermark-email', + includeAdditionalInfo: shouldIncludeAdditionalInfo, + } ) + ); + + const handleEmailInput = async ( event ) => { + const email = event.target.value; + 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 ); + } + console.log( 'Fastlane watermark removed' ); + }; + } + }, [ fastlaneSdk, shouldIncludeAdditionalInfo, onEmailSubmit ] ); + + return null; +}; + +export const setupWatermark = ( + fastlaneSdk, + shouldIncludeAdditionalInfo, + onEmailSubmit +) => { + const container = document.createElement( 'div' ); + document.body.appendChild( container ); + createRoot( container ).render( + createElement( WatermarkManager, { + fastlaneSdk, + shouldIncludeAdditionalInfo, + onEmailSubmit, + } ) + ); +}; + +export const removeWatermark = () => { + const watermarkContainer = document.querySelector( + '.ppcp-axo-block-watermark-container' + ); + if ( watermarkContainer && watermarkContainer.parentNode ) { + watermarkContainer.parentNode.removeChild( watermarkContainer ); } }; + +export default WatermarkManager; diff --git a/modules/ppcp-axo-block/resources/js/index.js b/modules/ppcp-axo-block/resources/js/index.js index 6916c43de..d39bb1ded 100644 --- a/modules/ppcp-axo-block/resources/js/index.js +++ b/modules/ppcp-axo-block/resources/js/index.js @@ -11,9 +11,10 @@ import { useCustomerData } from './hooks/useCustomerData'; import { Payment } from './components/Payment'; // Helpers -import { removeShippingChangeButton } from './helpers/buttonHelpers'; import { snapshotFields, restoreOriginalFields } from './helpers/fieldHelpers'; -import { setupWatermark, cleanupWatermark } from './helpers/watermarkHelpers'; +import { setupWatermark, removeWatermark } from './helpers/watermarkHelpers'; +import { removeCardChangeButton } from './helpers/cardChangeButtonManager'; +import { removeShippingChangeButton } from './helpers/shippingChangeButtonManager'; // Event handlers import { onEmailSubmit } from './events/fastlaneEmailManager'; @@ -43,11 +44,12 @@ const Axo = () => { setBillingAddress: updateWooBillingAddress, } = useCustomerData(); - // Inject and cleanup logic for Change button + // Cleanup logic for Change buttons useEffect( () => { return () => { - // Remove the shipping Change button on unmount removeShippingChangeButton(); + removeCardChangeButton(); + removeWatermark(); // Restore WooCommerce fields restoreOriginalFields( @@ -73,56 +75,35 @@ const Axo = () => { }, [ paypalLoaded, ppcpConfig ] ); useEffect( () => { - let watermarkHandlers = {}; - const radioLabelElement = document.getElementById( - 'ppcp-axo-block-radio-label' - ); - if ( paypalLoaded && fastlaneSdk ) { console.log( 'Fastlane SDK and PayPal loaded' ); - - watermarkHandlers = setupWatermark( + setupWatermark( fastlaneSdk, - shouldIncludeAdditionalInfo + shouldIncludeAdditionalInfo, + async ( email ) => { + await onEmailSubmit( + email, + fastlaneSdk, + setIsGuest, + isGuest, + setShippingAddress, + setCard, + snapshotFields, + wooShippingAddress, + wooBillingAddress, + setWooShippingAddress, + setWooBillingAddress, + onChangeShippingAddressClick, + onChangeButtonClick, + shouldIncludeAdditionalInfo, + setShouldIncludeAdditionalInfo + ); + } ); - const { emailInput } = watermarkHandlers; - - if ( emailInput ) { - emailInput.addEventListener( 'keyup', async ( event ) => { - const email = event.target.value; - if ( email ) { - await onEmailSubmit( - email, - fastlaneSdk, - setIsGuest, - isGuest, - setShippingAddress, - setCard, - snapshotFields, - wooShippingAddress, - wooBillingAddress, - setWooShippingAddress, - setWooBillingAddress, - onChangeShippingAddressClick, - onChangeButtonClick, - shouldIncludeAdditionalInfo, - setShouldIncludeAdditionalInfo - ); - } - } ); - } } return () => { - cleanupWatermark( watermarkHandlers ); - if ( radioLabelElement ) { - const changeButton = radioLabelElement.querySelector( - '.wc-block-checkout-axo-block-card__edit' - ); - if ( changeButton ) { - changeButton.remove(); - } - } + removeWatermark(); }; }, [ paypalLoaded, fastlaneSdk, shouldIncludeAdditionalInfo ] );