2020-02-25 11:36:53 +00:00
|
|
|
/** @typedef { import('@woocommerce/type-defs/hooks').StoreCart } StoreCart */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
import { CART_STORE_KEY as storeKey } from '@woocommerce/block-data';
|
|
|
|
import { useSelect } from '@wordpress/data';
|
2020-03-13 13:41:59 +00:00
|
|
|
import { useEditorContext } from '@woocommerce/base-context';
|
2020-04-21 13:43:49 +00:00
|
|
|
import { decodeEntities } from '@wordpress/html-entities';
|
2021-03-10 15:03:26 +00:00
|
|
|
import type {
|
|
|
|
StoreCart,
|
|
|
|
CartResponseTotals,
|
|
|
|
CartResponseFeeItem,
|
|
|
|
CartResponseBillingAddress,
|
|
|
|
CartResponseShippingAddress,
|
|
|
|
} from '@woocommerce/types';
|
|
|
|
import { fromEntriesPolyfill } from '@woocommerce/base-utils';
|
2020-02-25 11:36:53 +00:00
|
|
|
|
2021-03-10 15:03:26 +00:00
|
|
|
declare module '@wordpress/html-entities' {
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
|
|
export function decodeEntities< T >( coupon: T ): T;
|
|
|
|
}
|
|
|
|
const defaultShippingAddress: CartResponseShippingAddress = {
|
2020-11-20 15:13:35 +00:00
|
|
|
first_name: '',
|
|
|
|
last_name: '',
|
|
|
|
company: '',
|
|
|
|
address_1: '',
|
|
|
|
address_2: '',
|
|
|
|
city: '',
|
|
|
|
state: '',
|
|
|
|
postcode: '',
|
|
|
|
country: '',
|
|
|
|
};
|
|
|
|
|
2021-03-10 15:03:26 +00:00
|
|
|
const defaultBillingAddress: CartResponseBillingAddress = {
|
2020-11-20 15:13:35 +00:00
|
|
|
...defaultShippingAddress,
|
|
|
|
email: '',
|
|
|
|
phone: '',
|
|
|
|
};
|
|
|
|
|
2021-03-10 15:03:26 +00:00
|
|
|
const defaultCartTotals: CartResponseTotals = {
|
|
|
|
total_items: '',
|
|
|
|
total_items_tax: '',
|
|
|
|
total_fees: '',
|
|
|
|
total_fees_tax: '',
|
|
|
|
total_discount: '',
|
|
|
|
total_discount_tax: '',
|
|
|
|
total_shipping: '',
|
|
|
|
total_shipping_tax: '',
|
|
|
|
total_price: '',
|
|
|
|
total_tax: '',
|
|
|
|
tax_lines: [],
|
|
|
|
currency_code: '',
|
|
|
|
currency_symbol: '',
|
|
|
|
currency_minor_unit: 2,
|
|
|
|
currency_decimal_separator: '',
|
|
|
|
currency_thousand_separator: '',
|
|
|
|
currency_prefix: '',
|
|
|
|
currency_suffix: '',
|
|
|
|
};
|
|
|
|
|
|
|
|
const decodeValues = (
|
|
|
|
object: Record< string, unknown >
|
|
|
|
): Record< string, unknown > =>
|
|
|
|
fromEntriesPolyfill(
|
|
|
|
Object.entries( object ).map( ( [ key, value ] ) => [
|
|
|
|
key,
|
|
|
|
decodeEntities( value ),
|
|
|
|
] )
|
|
|
|
);
|
2020-11-20 15:13:35 +00:00
|
|
|
|
2020-02-18 23:06:37 +00:00
|
|
|
/**
|
2020-02-25 11:36:53 +00:00
|
|
|
* @constant
|
|
|
|
* @type {StoreCart} Object containing cart data.
|
2020-02-18 23:06:37 +00:00
|
|
|
*/
|
2021-03-10 15:03:26 +00:00
|
|
|
export const defaultCartData: StoreCart = {
|
2020-02-25 11:36:53 +00:00
|
|
|
cartCoupons: [],
|
|
|
|
cartItems: [],
|
2021-01-13 16:57:42 +00:00
|
|
|
cartFees: [],
|
2020-02-25 11:36:53 +00:00
|
|
|
cartItemsCount: 0,
|
|
|
|
cartItemsWeight: 0,
|
2020-04-09 14:01:11 +00:00
|
|
|
cartNeedsPayment: true,
|
2020-02-25 11:36:53 +00:00
|
|
|
cartNeedsShipping: true,
|
2020-04-02 14:04:43 +00:00
|
|
|
cartItemErrors: [],
|
2021-03-10 15:03:26 +00:00
|
|
|
cartTotals: defaultCartTotals,
|
2020-02-25 11:36:53 +00:00
|
|
|
cartIsLoading: true,
|
|
|
|
cartErrors: [],
|
2020-11-20 15:13:35 +00:00
|
|
|
billingAddress: defaultBillingAddress,
|
|
|
|
shippingAddress: defaultShippingAddress,
|
2020-03-13 19:04:03 +00:00
|
|
|
shippingRates: [],
|
2020-04-08 11:20:41 +00:00
|
|
|
shippingRatesLoading: false,
|
2020-11-17 11:58:38 +00:00
|
|
|
cartHasCalculatedShipping: false,
|
2021-01-29 06:28:44 +00:00
|
|
|
paymentRequirements: [],
|
2021-03-10 15:03:26 +00:00
|
|
|
receiveCart: () => undefined,
|
2021-02-04 17:05:47 +00:00
|
|
|
extensions: {},
|
2020-02-25 11:36:53 +00:00
|
|
|
};
|
2020-02-18 23:06:37 +00:00
|
|
|
|
|
|
|
/**
|
2020-02-25 11:36:53 +00:00
|
|
|
* This is a custom hook that is wired up to the `wc/store/cart` data
|
|
|
|
* store.
|
|
|
|
*
|
|
|
|
* @param {Object} options An object declaring the various
|
|
|
|
* collection arguments.
|
|
|
|
* @param {boolean} options.shouldSelect If false, the previous results will be
|
|
|
|
* returned and internal selects will not
|
|
|
|
* fire.
|
2020-02-18 23:06:37 +00:00
|
|
|
*
|
2020-02-25 11:36:53 +00:00
|
|
|
* @return {StoreCart} Object containing cart data.
|
2020-02-18 23:06:37 +00:00
|
|
|
*/
|
2021-03-10 15:03:26 +00:00
|
|
|
export const useStoreCart = (
|
|
|
|
options: { shouldSelect: boolean } = { shouldSelect: true }
|
|
|
|
): StoreCart => {
|
2020-04-15 00:05:01 +00:00
|
|
|
const { isEditor, previewData } = useEditorContext();
|
|
|
|
const previewCart = previewData?.previewCart || {};
|
2020-02-25 11:36:53 +00:00
|
|
|
const { shouldSelect } = options;
|
|
|
|
|
2021-03-10 15:03:26 +00:00
|
|
|
const results: StoreCart = useSelect(
|
2020-04-17 20:18:54 +00:00
|
|
|
( select, { dispatch } ) => {
|
2020-02-25 11:36:53 +00:00
|
|
|
if ( ! shouldSelect ) {
|
2020-03-13 19:04:03 +00:00
|
|
|
return defaultCartData;
|
2020-02-25 11:36:53 +00:00
|
|
|
}
|
2020-03-13 13:41:59 +00:00
|
|
|
|
|
|
|
if ( isEditor ) {
|
|
|
|
return {
|
|
|
|
cartCoupons: previewCart.coupons,
|
|
|
|
cartItems: previewCart.items,
|
2021-01-13 16:57:42 +00:00
|
|
|
cartFees: previewCart.fees,
|
2020-03-13 13:41:59 +00:00
|
|
|
cartItemsCount: previewCart.items_count,
|
|
|
|
cartItemsWeight: previewCart.items_weight,
|
2020-04-09 14:01:11 +00:00
|
|
|
cartNeedsPayment: previewCart.needs_payment,
|
2020-03-13 13:41:59 +00:00
|
|
|
cartNeedsShipping: previewCart.needs_shipping,
|
2020-04-02 14:04:43 +00:00
|
|
|
cartItemErrors: [],
|
2020-03-13 13:41:59 +00:00
|
|
|
cartTotals: previewCart.totals,
|
|
|
|
cartIsLoading: false,
|
|
|
|
cartErrors: [],
|
2020-11-20 15:13:35 +00:00
|
|
|
billingAddress: defaultBillingAddress,
|
|
|
|
shippingAddress: defaultShippingAddress,
|
2021-01-20 20:35:53 +00:00
|
|
|
extensions: {},
|
2020-04-08 11:20:41 +00:00
|
|
|
shippingRates: previewCart.shipping_rates,
|
|
|
|
shippingRatesLoading: false,
|
2020-11-17 11:58:38 +00:00
|
|
|
cartHasCalculatedShipping:
|
|
|
|
previewCart.has_calculated_shipping,
|
2021-01-29 06:28:44 +00:00
|
|
|
paymentRequirements: previewCart.paymentRequirements,
|
2020-04-17 20:18:54 +00:00
|
|
|
receiveCart:
|
|
|
|
typeof previewCart?.receiveCart === 'function'
|
|
|
|
? previewCart.receiveCart
|
2021-03-10 15:03:26 +00:00
|
|
|
: () => undefined,
|
2020-03-13 13:41:59 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-02-25 11:36:53 +00:00
|
|
|
const store = select( storeKey );
|
|
|
|
const cartData = store.getCartData();
|
|
|
|
const cartErrors = store.getCartErrors();
|
|
|
|
const cartTotals = store.getCartTotals();
|
|
|
|
const cartIsLoading = ! store.hasFinishedResolution(
|
|
|
|
'getCartData'
|
|
|
|
);
|
2020-11-20 15:13:35 +00:00
|
|
|
const shippingRatesLoading = store.isCustomerDataUpdating();
|
2020-04-17 20:18:54 +00:00
|
|
|
const { receiveCart } = dispatch( storeKey );
|
2021-02-04 17:05:47 +00:00
|
|
|
const billingAddress = decodeValues( cartData.billingAddress );
|
2020-11-20 15:13:35 +00:00
|
|
|
const shippingAddress = cartData.needsShipping
|
2021-02-04 17:05:47 +00:00
|
|
|
? decodeValues( cartData.shippingAddress )
|
2020-12-23 15:10:13 +00:00
|
|
|
: billingAddress;
|
2021-03-10 15:03:26 +00:00
|
|
|
const cartFees = cartData.fees.map( ( fee: CartResponseFeeItem ) =>
|
2021-02-04 17:05:47 +00:00
|
|
|
decodeValues( fee )
|
|
|
|
);
|
2020-02-25 11:36:53 +00:00
|
|
|
return {
|
|
|
|
cartCoupons: cartData.coupons,
|
2020-06-10 18:21:34 +00:00
|
|
|
cartItems: cartData.items || [],
|
2021-02-04 17:05:47 +00:00
|
|
|
cartFees,
|
2020-02-25 11:36:53 +00:00
|
|
|
cartItemsCount: cartData.itemsCount,
|
|
|
|
cartItemsWeight: cartData.itemsWeight,
|
2020-04-09 14:01:11 +00:00
|
|
|
cartNeedsPayment: cartData.needsPayment,
|
2020-02-25 11:36:53 +00:00
|
|
|
cartNeedsShipping: cartData.needsShipping,
|
2020-06-10 18:21:34 +00:00
|
|
|
cartItemErrors: cartData.errors || [],
|
2020-02-25 11:36:53 +00:00
|
|
|
cartTotals,
|
|
|
|
cartIsLoading,
|
|
|
|
cartErrors,
|
2020-11-20 15:13:35 +00:00
|
|
|
billingAddress,
|
2020-04-21 13:43:49 +00:00
|
|
|
shippingAddress,
|
2021-01-20 20:35:53 +00:00
|
|
|
extensions: cartData.extensions || {},
|
2020-06-10 18:21:34 +00:00
|
|
|
shippingRates: cartData.shippingRates || [],
|
2020-04-08 11:20:41 +00:00
|
|
|
shippingRatesLoading,
|
2020-11-17 11:58:38 +00:00
|
|
|
cartHasCalculatedShipping: cartData.hasCalculatedShipping,
|
2021-01-29 06:28:44 +00:00
|
|
|
paymentRequirements: cartData.paymentRequirements || [],
|
2020-04-17 20:18:54 +00:00
|
|
|
receiveCart,
|
2020-02-25 11:36:53 +00:00
|
|
|
};
|
|
|
|
},
|
|
|
|
[ shouldSelect ]
|
|
|
|
);
|
|
|
|
return results;
|
2020-02-18 23:06:37 +00:00
|
|
|
};
|