2020-01-06 22:28:09 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
import {
|
|
|
|
usePaymentMethods,
|
2020-03-11 10:50:12 +00:00
|
|
|
usePaymentMethodInterface,
|
2020-01-06 22:28:09 +00:00
|
|
|
} from '@woocommerce/base-hooks';
|
2020-03-10 16:35:30 +00:00
|
|
|
import {
|
|
|
|
useCallback,
|
|
|
|
cloneElement,
|
|
|
|
useRef,
|
|
|
|
useEffect,
|
2020-03-26 11:11:46 +00:00
|
|
|
useState,
|
2020-03-10 16:35:30 +00:00
|
|
|
} from '@wordpress/element';
|
2020-01-06 22:28:09 +00:00
|
|
|
import { __ } from '@wordpress/i18n';
|
2020-03-26 11:11:46 +00:00
|
|
|
import {
|
2020-04-01 09:27:53 +00:00
|
|
|
useEditorContext,
|
2020-03-26 11:11:46 +00:00
|
|
|
usePaymentMethodDataContext,
|
|
|
|
} from '@woocommerce/base-context';
|
2020-01-06 22:28:09 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import Tabs from '../tabs';
|
2020-03-26 11:11:46 +00:00
|
|
|
import NoPaymentMethods from './no-payment-methods';
|
|
|
|
import SavedPaymentMethodOptions from './saved-payment-method-options';
|
2020-01-06 22:28:09 +00:00
|
|
|
|
2020-03-10 16:35:30 +00:00
|
|
|
/**
|
|
|
|
* Returns a payment method for the given context.
|
|
|
|
*
|
|
|
|
* @param {string} id The payment method slug to return.
|
|
|
|
* @param {Object} paymentMethods The current registered payment methods
|
|
|
|
* @param {boolean} isEditor Whether in the editor context (true) or not (false).
|
|
|
|
*
|
|
|
|
* @return {Object} The payment method matching the id for the given context.
|
|
|
|
*/
|
|
|
|
const getPaymentMethod = ( id, paymentMethods, isEditor ) => {
|
|
|
|
let paymentMethod = paymentMethods[ id ] || null;
|
|
|
|
if ( paymentMethod ) {
|
2020-03-30 12:07:49 +00:00
|
|
|
paymentMethod = isEditor ? paymentMethod.edit : paymentMethod.content;
|
2020-03-10 16:35:30 +00:00
|
|
|
}
|
|
|
|
return paymentMethod;
|
|
|
|
};
|
|
|
|
|
2020-03-20 16:48:11 +00:00
|
|
|
/**
|
|
|
|
* PaymentMethods component.
|
|
|
|
*
|
|
|
|
* @return {*} The rendered component.
|
|
|
|
*/
|
2020-01-06 22:28:09 +00:00
|
|
|
const PaymentMethods = () => {
|
2020-04-01 09:27:53 +00:00
|
|
|
const { isEditor } = useEditorContext();
|
2020-03-26 11:11:46 +00:00
|
|
|
const { customerPaymentMethods = {} } = usePaymentMethodDataContext();
|
2020-01-06 22:28:09 +00:00
|
|
|
const { isInitialized, paymentMethods } = usePaymentMethods();
|
2020-03-10 16:35:30 +00:00
|
|
|
const currentPaymentMethods = useRef( paymentMethods );
|
2020-03-11 10:50:12 +00:00
|
|
|
const {
|
|
|
|
activePaymentMethod,
|
|
|
|
setActivePaymentMethod,
|
|
|
|
...paymentMethodInterface
|
|
|
|
} = usePaymentMethodInterface();
|
|
|
|
const currentPaymentMethodInterface = useRef( paymentMethodInterface );
|
2020-03-26 11:11:46 +00:00
|
|
|
const [ selectedToken, setSelectedToken ] = useState( 0 );
|
2020-03-10 16:35:30 +00:00
|
|
|
|
2020-03-20 16:48:11 +00:00
|
|
|
// update ref on change.
|
2020-03-10 16:35:30 +00:00
|
|
|
useEffect( () => {
|
|
|
|
currentPaymentMethods.current = paymentMethods;
|
2020-03-11 10:50:12 +00:00
|
|
|
currentPaymentMethodInterface.current = paymentMethodInterface;
|
|
|
|
}, [ paymentMethods, paymentMethodInterface, activePaymentMethod ] );
|
2020-03-20 16:48:11 +00:00
|
|
|
|
2020-01-06 22:28:09 +00:00
|
|
|
const getRenderedTab = useCallback(
|
|
|
|
() => ( selectedTab ) => {
|
2020-03-10 16:35:30 +00:00
|
|
|
const paymentMethod = getPaymentMethod(
|
|
|
|
selectedTab,
|
|
|
|
currentPaymentMethods.current,
|
|
|
|
isEditor
|
|
|
|
);
|
2020-01-06 22:28:09 +00:00
|
|
|
return paymentMethod
|
|
|
|
? cloneElement( paymentMethod, {
|
2020-03-30 12:07:49 +00:00
|
|
|
activePaymentMethod,
|
2020-03-11 10:50:12 +00:00
|
|
|
...currentPaymentMethodInterface.current,
|
2020-01-06 22:28:09 +00:00
|
|
|
} )
|
|
|
|
: null;
|
|
|
|
},
|
2020-03-11 10:50:12 +00:00
|
|
|
[ isEditor, activePaymentMethod ]
|
2020-01-06 22:28:09 +00:00
|
|
|
);
|
2020-03-20 16:48:11 +00:00
|
|
|
|
2020-03-26 11:11:46 +00:00
|
|
|
if (
|
|
|
|
! isInitialized ||
|
|
|
|
Object.keys( currentPaymentMethods.current ).length === 0
|
|
|
|
) {
|
2020-03-20 16:48:11 +00:00
|
|
|
return <NoPaymentMethods />;
|
2020-01-06 22:28:09 +00:00
|
|
|
}
|
2020-03-26 11:11:46 +00:00
|
|
|
const renderedTabs = (
|
2020-01-06 22:28:09 +00:00
|
|
|
<Tabs
|
2020-03-20 16:48:11 +00:00
|
|
|
className="wc-block-components-checkout-payment-methods"
|
2020-01-06 22:28:09 +00:00
|
|
|
onSelect={ ( tabName ) => setActivePaymentMethod( tabName ) }
|
2020-03-26 11:11:46 +00:00
|
|
|
tabs={ Object.keys( currentPaymentMethods.current ).map( ( id ) => {
|
|
|
|
const { label, ariaLabel } = currentPaymentMethods.current[
|
|
|
|
id
|
|
|
|
];
|
2020-03-20 16:48:11 +00:00
|
|
|
return {
|
|
|
|
name: id,
|
|
|
|
title: () => label,
|
|
|
|
ariaLabel,
|
|
|
|
};
|
|
|
|
} ) }
|
2020-01-06 22:28:09 +00:00
|
|
|
initialTabName={ activePaymentMethod }
|
|
|
|
ariaLabel={ __(
|
|
|
|
'Payment Methods',
|
|
|
|
'woo-gutenberg-products-block'
|
|
|
|
) }
|
2020-03-30 12:07:49 +00:00
|
|
|
id="wc-block-payment-methods"
|
2020-01-06 22:28:09 +00:00
|
|
|
>
|
|
|
|
{ getRenderedTab() }
|
|
|
|
</Tabs>
|
|
|
|
);
|
2020-03-26 11:11:46 +00:00
|
|
|
|
|
|
|
const renderedSavedPaymentOptions = (
|
|
|
|
<SavedPaymentMethodOptions onSelect={ setSelectedToken } />
|
|
|
|
);
|
|
|
|
|
|
|
|
const renderedTabsAndSavedPaymentOptions = (
|
|
|
|
<>
|
|
|
|
{ renderedSavedPaymentOptions }
|
|
|
|
{ renderedTabs }
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
|
|
|
|
return Object.keys( customerPaymentMethods ).length > 0 &&
|
|
|
|
selectedToken !== 0
|
|
|
|
? renderedSavedPaymentOptions
|
|
|
|
: renderedTabsAndSavedPaymentOptions;
|
2020-01-06 22:28:09 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
export default PaymentMethods;
|