From 5acd0f155183ed957ed5c275530dfdd9034a5058 Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Sun, 8 Dec 2019 18:04:38 -0500 Subject: [PATCH] add checkout and payment method hooks --- assets/js/base/hooks/checkout/index.js | 5 +++ .../hooks/checkout/use-checkout-events.js | 41 +++++++++++++++++++ .../hooks/checkout/use-checkout-notices.js | 24 +++++++++++ .../checkout/use-checkout-redirect-urls.js | 22 ++++++++++ assets/js/base/hooks/index.js | 2 + .../base/hooks/payment-methods/constants.js | 8 ++++ assets/js/base/hooks/payment-methods/index.js | 2 + .../use-active-payment-method.js | 25 +++++++++++ .../hooks/payment-methods/use-payment-data.js | 29 +++++++++++++ .../payment-methods/use-payment-events.js | 38 +++++++++++++++++ 10 files changed, 196 insertions(+) create mode 100644 assets/js/base/hooks/checkout/index.js create mode 100644 assets/js/base/hooks/checkout/use-checkout-events.js create mode 100644 assets/js/base/hooks/checkout/use-checkout-notices.js create mode 100644 assets/js/base/hooks/checkout/use-checkout-redirect-urls.js create mode 100644 assets/js/base/hooks/payment-methods/constants.js create mode 100644 assets/js/base/hooks/payment-methods/index.js create mode 100644 assets/js/base/hooks/payment-methods/use-active-payment-method.js create mode 100644 assets/js/base/hooks/payment-methods/use-payment-data.js create mode 100644 assets/js/base/hooks/payment-methods/use-payment-events.js diff --git a/assets/js/base/hooks/checkout/index.js b/assets/js/base/hooks/checkout/index.js new file mode 100644 index 00000000000..f1e3aaceb3d --- /dev/null +++ b/assets/js/base/hooks/checkout/index.js @@ -0,0 +1,5 @@ +export { default as useCheckoutEvents } from './use-checkout-events'; +export { default as useCheckoutNotices } from './use-checkout-notcies'; +export { + default as useCheckoutRedirectUrls, +} from './use-checkout-redirect-urls'; diff --git a/assets/js/base/hooks/checkout/use-checkout-events.js b/assets/js/base/hooks/checkout/use-checkout-events.js new file mode 100644 index 00000000000..3298c7b3d7f --- /dev/null +++ b/assets/js/base/hooks/checkout/use-checkout-events.js @@ -0,0 +1,41 @@ +/** + * External dependencies + */ +import useCheckoutContext from '@woocommerce/base-context/checkout-context'; + +export const useCheckoutEvents = () => { + const { + checkoutComplete, + setCheckoutComplete, + checkoutHasError, + setCheckoutHasError, + isCalculating, + setIsCalculating, + } = useCheckoutContext(); + const setHasError = () => { + setCheckoutHasError( true ); + }; + const cancelCheckoutError = () => { + setCheckoutHasError( false ); + }; + const setComplete = () => { + cancelCheckoutError(); + setCheckoutComplete( true ); + }; + const setCalculating = () => { + setIsCalculating( true ); + }; + const cancelCalculating = () => { + setIsCalculating( false ); + }; + return { + setCheckoutComplete: setComplete, + setCheckoutHasError: setHasError, + cancelCheckoutError, + setIsCalculating: setCalculating, + cancelCalculating, + isCalculating, + checkoutComplete, + checkoutHasError, + }; +}; diff --git a/assets/js/base/hooks/checkout/use-checkout-notices.js b/assets/js/base/hooks/checkout/use-checkout-notices.js new file mode 100644 index 00000000000..5eceda49886 --- /dev/null +++ b/assets/js/base/hooks/checkout/use-checkout-notices.js @@ -0,0 +1,24 @@ +/** + * External dependencies + */ +import useCheckoutContext from '@woocommerce/base-context/checkout-context'; + +const useCheckoutNotices = () => { + const { notices, updateNotices } = useCheckoutContext(); + const addNotice = ( notice ) => { + updateNotices( ( originalNotices ) => [ ...originalNotices, notice ] ); + }; + const removeNotice = ( notice ) => { + // @todo...figure out how notices are saved - might need unique ids? + // Do we have a special notice creator that takes care of that? + // Use wp notice api? + return notice; + }; + return { + notices, + addNotice, + removeNotice, + }; +}; + +export default useCheckoutNotices; diff --git a/assets/js/base/hooks/checkout/use-checkout-redirect-urls.js b/assets/js/base/hooks/checkout/use-checkout-redirect-urls.js new file mode 100644 index 00000000000..264a1f3a507 --- /dev/null +++ b/assets/js/base/hooks/checkout/use-checkout-redirect-urls.js @@ -0,0 +1,22 @@ +/** + * External dependencies + */ +import useCheckoutContext from '@woocommerce/base-context/checkout-context'; + +const useCheckoutRedirectUrls = () => { + const { + successRedirectUrl, + setSuccessRedirectUrl, + failureRedirectUrl, + setFailureRedirectUrl, + } = useCheckoutContext(); + + return { + successRedirectUrl, + setSuccessRedirectUrl, + failureRedirectUrl, + setFailureRedirectUrl, + }; +}; + +export default useCheckoutRedirectUrls; diff --git a/assets/js/base/hooks/index.js b/assets/js/base/hooks/index.js index 13c0ae28153..3cd18b51450 100644 --- a/assets/js/base/hooks/index.js +++ b/assets/js/base/hooks/index.js @@ -5,3 +5,5 @@ export * from './use-collection'; export * from './use-collection-header'; export * from './use-collection-data'; export * from './use-previous'; +export * from './checkout'; +export * from './payment-methods'; diff --git a/assets/js/base/hooks/payment-methods/constants.js b/assets/js/base/hooks/payment-methods/constants.js new file mode 100644 index 00000000000..f943f737332 --- /dev/null +++ b/assets/js/base/hooks/payment-methods/constants.js @@ -0,0 +1,8 @@ +export const STATUS = { + PRISTINE: 'pristine', + STARTED: 'started', + FINISHED: 'finished', + ERROR: 'has_error', + FAILED: 'failed', + SUCCESS: 'success', +}; diff --git a/assets/js/base/hooks/payment-methods/index.js b/assets/js/base/hooks/payment-methods/index.js new file mode 100644 index 00000000000..48e39068860 --- /dev/null +++ b/assets/js/base/hooks/payment-methods/index.js @@ -0,0 +1,2 @@ +export { default as useActivePaymentMethod } from './use-active-payment-method'; +export { default as usePaymentEvents } from './use-payment-events'; diff --git a/assets/js/base/hooks/payment-methods/use-active-payment-method.js b/assets/js/base/hooks/payment-methods/use-active-payment-method.js new file mode 100644 index 00000000000..46d9911faf0 --- /dev/null +++ b/assets/js/base/hooks/payment-methods/use-active-payment-method.js @@ -0,0 +1,25 @@ +/** + * External dependencies + */ +import useCheckoutContext from '@woocommerce/base-context/checkout-context'; +import { useEffect } from '@wordpress/element'; +import { getPaymentMethods } from '@woocommerce/block-settings'; + +const useActivePaymentMethod = () => { + const { + activePaymentMethod, + setActivePaymentMethod, + } = useCheckoutContext(); + // if payment method has not been set yet, let's set it. + useEffect( () => { + if ( ! activePaymentMethod && activePaymentMethod !== null ) { + const paymentMethods = getPaymentMethods(); + setActivePaymentMethod( + paymentMethods.length > 0 ? paymentMethods[ 0 ].name : null + ); + } + }, [ activePaymentMethod, setActivePaymentMethod ] ); + return { activePaymentMethod, setActivePaymentMethod }; +}; + +export default useActivePaymentMethod; diff --git a/assets/js/base/hooks/payment-methods/use-payment-data.js b/assets/js/base/hooks/payment-methods/use-payment-data.js new file mode 100644 index 00000000000..d72b97a3d5a --- /dev/null +++ b/assets/js/base/hooks/payment-methods/use-payment-data.js @@ -0,0 +1,29 @@ +// @todo this should be a value object. Provided via wc-settings? +const currencyObject = { + code: 'USD', + precision: 2, + symbol: '$', + symbolPosition: 'left', + decimalSeparator: '.', + priceFormat: '%1$s%2$s', + thousandSeparator: ',', +}; + +const usePaymentData = () => { + // @todo this will likely be a global wp.data store state so that things + // like shipping selection, quantity changes, etc that affect totals etc + // will automatically update the payment data. For POC this is hardcoded + const paymentData = { + // this likely should be a float. + total: 10.123, + currency: currencyObject, + // @todo, should this be a standard format of items in the checkout/cart + // provided to ALL payment methods? Line items includes taxes/shipping + // costs? Coupons? + lineItems: [], + }; + const updatePaymentData = () => {}; + return [ paymentData, updatePaymentData ]; +}; + +export default usePaymentData; diff --git a/assets/js/base/hooks/payment-methods/use-payment-events.js b/assets/js/base/hooks/payment-methods/use-payment-events.js new file mode 100644 index 00000000000..ef5b7201434 --- /dev/null +++ b/assets/js/base/hooks/payment-methods/use-payment-events.js @@ -0,0 +1,38 @@ +/** + * External dependencies + */ +import { useState, useMemo } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { STATUS } from './constants'; + +const usePaymentEvents = () => { + const { paymentStatus, setPaymentStatus } = useState( STATUS.PRISTINE ); + const dispatch = useMemo( + () => ( { + pristine: () => setPaymentStatus( STATUS.PRISTINE ), + started: () => setPaymentStatus( STATUS.STARTED ), + finished: () => setPaymentStatus( STATUS.FINISHED ), + error: () => setPaymentStatus( STATUS.ERROR ), + failed: () => setPaymentStatus( STATUS.FAILED ), + success: () => setPaymentStatus( STATUS.SUCCESS ), + } ), + [ setPaymentStatus ] + ); + const select = useMemo( + () => ( { + isPristine: () => paymentStatus === STATUS.PRISTINE, + isStarted: () => paymentStatus === STATUS.STARTED, + isFinished: () => paymentStatus === STATUS.FINISHED, + hasError: () => paymentStatus === STATUS.ERROR, + hasFailed: () => paymentStatus === STATUS.FAILED, + isSuccessful: () => paymentStatus === STATUS.SUCCESS, + } ), + [ paymentStatus ] + ); + return { dispatch, select }; +}; + +export default usePaymentEvents;