Merge pull request #2672 from woocommerce/PCP-3767-axo-block-fix-the-handling-of-the-missing-card-profile

Axo Block: Display card fields for authenticated cardless profiles (3767)
This commit is contained in:
Emili Castells 2024-10-11 14:58:54 +02:00 committed by GitHub
commit c405a98382
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 74 additions and 29 deletions

View file

@ -1,6 +1,7 @@
import { useEffect, useCallback, useState } from '@wordpress/element'; import { useEffect, useCallback, useState } from '@wordpress/element';
import { useSelect } from '@wordpress/data'; import { useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n'; import { __ } from '@wordpress/i18n';
import { log } from '../../../../../ppcp-axo/resources/js/Helper/Debug';
import { Card } from '../Card'; import { Card } from '../Card';
import { STORE_NAME } from '../../stores/axoStore'; import { STORE_NAME } from '../../stores/axoStore';
@ -16,27 +17,48 @@ export const Payment = ( { fastlaneSdk, onPaymentLoad } ) => {
const [ isCardElementReady, setIsCardElementReady ] = useState( false ); const [ isCardElementReady, setIsCardElementReady ] = useState( false );
// Select relevant states from the AXO store // Select relevant states from the AXO store
const { isGuest, isEmailLookupCompleted } = useSelect( const { isGuest, isEmailLookupCompleted, cardDetails } = useSelect(
( select ) => ( { ( select ) => ( {
isGuest: select( STORE_NAME ).getIsGuest(), isGuest: select( STORE_NAME ).getIsGuest(),
isEmailLookupCompleted: isEmailLookupCompleted:
select( STORE_NAME ).getIsEmailLookupCompleted(), 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 () => { const loadPaymentComponent = useCallback( async () => {
if ( isGuest && isEmailLookupCompleted && isCardElementReady ) { if (
const paymentComponent = await fastlaneSdk.FastlaneCardComponent( ( isGuest && isEmailLookupCompleted && isCardElementReady ) ||
{} ( ! isGuest && ! cardDetails )
); ) {
paymentComponent.render( `#fastlane-card` ); 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 ); onPaymentLoad( paymentComponent );
} }
} catch ( error ) {
log( `Error loading payment component: ${ error }`, 'error' );
}
}
}, [ }, [
isGuest, isGuest,
isEmailLookupCompleted, isEmailLookupCompleted,
isCardElementReady, isCardElementReady,
cardDetails,
fastlaneSdk, fastlaneSdk,
onPaymentLoad, onPaymentLoad,
] ); ] );
@ -48,19 +70,27 @@ export const Payment = ( { fastlaneSdk, onPaymentLoad } ) => {
} }
}, [ isGuest, isEmailLookupCompleted ] ); }, [ isGuest, isEmailLookupCompleted ] );
// Load payment component when dependencies change // Load payment component when card element is ready
useEffect( () => { useEffect( () => {
if ( isCardElementReady ) {
loadPaymentComponent(); 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 <div id="fastlane-card" key="fastlane-card" />;
} }
}, [ 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 ( return (
<div id="ppcp-axo-block-radio-content"> <div id="ppcp-axo-block-radio-content">
{ __( { __(
@ -70,5 +100,18 @@ export const Payment = ( { fastlaneSdk, onPaymentLoad } ) => {
</div> </div>
); );
} }
// Case 2 & 3: Guest with completed email lookup or authenticated user without card details
if (
( isGuest && isEmailLookupCompleted ) ||
( ! isGuest && ! cardDetails )
) {
return <div id="fastlane-card" />;
}
// Case 4: Authenticated user with card details
return <Card fastlaneSdk={ fastlaneSdk } showWatermark={ ! isGuest } />; return <Card fastlaneSdk={ fastlaneSdk } showWatermark={ ! isGuest } />;
}; };
return renderPaymentComponent();
};

View file

@ -18,7 +18,8 @@ import useCustomerData from './useCustomerData';
*/ */
const useAxoCleanup = () => { const useAxoCleanup = () => {
// Get dispatch functions from the AXO store // 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 // Get functions to update WooCommerce shipping and billing addresses
const { const {
@ -45,6 +46,7 @@ const useAxoCleanup = () => {
// Reset AXO state // Reset AXO state
setIsAxoActive( false ); setIsAxoActive( false );
setIsGuest( true ); setIsGuest( true );
setIsEmailLookupCompleted( false );
// Remove AXO UI elements // Remove AXO UI elements
removeShippingChangeButton(); removeShippingChangeButton();