diff --git a/modules/ppcp-axo-block/resources/js/components/Payment/Payment.js b/modules/ppcp-axo-block/resources/js/components/Payment/Payment.js index e1191c8ce..0043db639 100644 --- a/modules/ppcp-axo-block/resources/js/components/Payment/Payment.js +++ b/modules/ppcp-axo-block/resources/js/components/Payment/Payment.js @@ -1,6 +1,7 @@ import { useEffect, useCallback, useState } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; +import { log } from '../../../../../ppcp-axo/resources/js/Helper/Debug'; import { Card } from '../Card'; import { STORE_NAME } from '../../stores/axoStore'; @@ -16,27 +17,48 @@ export const Payment = ( { fastlaneSdk, onPaymentLoad } ) => { const [ isCardElementReady, setIsCardElementReady ] = useState( false ); // Select relevant states from the AXO store - const { isGuest, isEmailLookupCompleted } = useSelect( + const { isGuest, isEmailLookupCompleted, cardDetails } = useSelect( ( select ) => ( { isGuest: select( STORE_NAME ).getIsGuest(), isEmailLookupCompleted: select( STORE_NAME ).getIsEmailLookupCompleted(), + cardDetails: select( STORE_NAME ).getCardDetails(), } ), [] ); + /** + * Loads and renders the Fastlane card fields component when necessary. + * This function is called for: + * 1. Guest users who have completed email lookup + * 2. Authenticated users who are missing card details + * + * The component allows users to enter new card details for payment. + */ const loadPaymentComponent = useCallback( async () => { - if ( isGuest && isEmailLookupCompleted && isCardElementReady ) { - const paymentComponent = await fastlaneSdk.FastlaneCardComponent( - {} - ); - paymentComponent.render( `#fastlane-card` ); - onPaymentLoad( paymentComponent ); + if ( + ( isGuest && isEmailLookupCompleted && isCardElementReady ) || + ( ! isGuest && ! cardDetails ) + ) { + try { + const paymentComponent = + await fastlaneSdk.FastlaneCardComponent( {} ); + // Check if the container exists before rendering + const cardContainer = + document.querySelector( '#fastlane-card' ); + if ( cardContainer ) { + paymentComponent.render( '#fastlane-card' ); + onPaymentLoad( paymentComponent ); + } + } catch ( error ) { + log( `Error loading payment component: ${ error }`, 'error' ); + } } }, [ isGuest, isEmailLookupCompleted, isCardElementReady, + cardDetails, fastlaneSdk, onPaymentLoad, ] ); @@ -48,27 +70,48 @@ export const Payment = ( { fastlaneSdk, onPaymentLoad } ) => { } }, [ isGuest, isEmailLookupCompleted ] ); - // Load payment component when dependencies change + // Load payment component when card element is ready useEffect( () => { - loadPaymentComponent(); - }, [ loadPaymentComponent ] ); - - // Conditional rendering based on user state: - // 1. If authenticated: Render the Card component - // 2. If guest with completed email lookup: Render the card fields - // 3. If guest without completed email lookup: Render a message to enter email - if ( isGuest ) { - if ( isEmailLookupCompleted ) { - return
; + if ( isCardElementReady ) { + loadPaymentComponent(); } - return ( -
- { __( - 'Enter your email address above to continue.', - 'woocommerce-paypal-payments' - ) } -
- ); - } - return ; + }, [ isCardElementReady, loadPaymentComponent ] ); + + /** + * Determines which component to render based on the current state. + * + * Rendering logic: + * 1. For guests without completed email lookup: Show message to enter email + * 2. For guests with completed email lookup: Render Fastlane card fields + * 3. For authenticated users without card details: Render Fastlane card fields + * 4. For authenticated users with card details: Render Card component + * + * @return {JSX.Element} The appropriate component based on the current state + */ + const renderPaymentComponent = () => { + // Case 1: Guest user without completed email lookup + if ( isGuest && ! isEmailLookupCompleted ) { + return ( +
+ { __( + 'Enter your email address above to continue.', + 'woocommerce-paypal-payments' + ) } +
+ ); + } + + // Case 2 & 3: Guest with completed email lookup or authenticated user without card details + if ( + ( isGuest && isEmailLookupCompleted ) || + ( ! isGuest && ! cardDetails ) + ) { + return
; + } + + // Case 4: Authenticated user with card details + return ; + }; + + return renderPaymentComponent(); }; diff --git a/modules/ppcp-axo-block/resources/js/hooks/useAxoCleanup.js b/modules/ppcp-axo-block/resources/js/hooks/useAxoCleanup.js index 871197722..1da3cca85 100644 --- a/modules/ppcp-axo-block/resources/js/hooks/useAxoCleanup.js +++ b/modules/ppcp-axo-block/resources/js/hooks/useAxoCleanup.js @@ -18,7 +18,8 @@ import useCustomerData from './useCustomerData'; */ const useAxoCleanup = () => { // Get dispatch functions from the AXO store - const { setIsAxoActive, setIsGuest } = useDispatch( STORE_NAME ); + const { setIsAxoActive, setIsGuest, setIsEmailLookupCompleted } = + useDispatch( STORE_NAME ); // Get functions to update WooCommerce shipping and billing addresses const { @@ -45,6 +46,7 @@ const useAxoCleanup = () => { // Reset AXO state setIsAxoActive( false ); setIsGuest( true ); + setIsEmailLookupCompleted( false ); // Remove AXO UI elements removeShippingChangeButton();