/** * External dependencies */ import PropTypes from 'prop-types'; import { __ } from '@wordpress/i18n'; import { useState, useEffect } from '@wordpress/element'; import { TotalsCouponCodeInput, TotalsItem, } from '@woocommerce/base-components/totals'; import ShippingRatesControl, { Packages, } from '@woocommerce/base-components/shipping-rates-control'; import ShippingCalculator from '@woocommerce/base-components/shipping-calculator'; import ShippingLocation from '@woocommerce/base-components/shipping-location'; import LoadingMask from '@woocommerce/base-components/loading-mask'; import { COUPONS_ENABLED, SHIPPING_ENABLED, DISPLAY_PRICES_INCLUDING_TAXES, } from '@woocommerce/block-settings'; import { getCurrencyFromPriceResponse } from '@woocommerce/base-utils'; import { Card, CardBody } from 'wordpress-components'; import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-monetary-amount'; import { decodeEntities } from '@wordpress/html-entities'; import { useStoreCartCoupons } from '@woocommerce/base-hooks'; import classnames from 'classnames'; /** * Internal dependencies */ import CheckoutButton from './checkout-button'; import CartLineItemsTitle from './cart-line-items-title'; import CartLineItemsTable from './cart-line-items-table'; import './style.scss'; import './editor.scss'; const renderShippingRatesControlOption = ( option ) => ( { label: decodeEntities( option.name ), value: option.rate_id, description: ( <> { option.price && ( ) } { option.price && option.delivery_time ? ' — ' : null } { decodeEntities( option.delivery_time ) } ), } ); /** * Component that renders the Cart block when user has something in cart aka "full". */ const Cart = ( { cartItems = [], cartTotals = {}, cartCoupons = [], isShippingCalculatorEnabled, isShippingCostHidden, shippingRates, isLoading = false, } ) => { const [ selectedShippingRate, setSelectedShippingRate ] = useState(); const [ shippingCalculatorAddress, setShippingCalculatorAddress, ] = useState( { city: '', state: '', postcode: '', country: '', } ); const [ showShippingCosts, setShowShippingCosts ] = useState( ! isShippingCostHidden ); const { applyCoupon, removeCoupon, isApplyingCoupon, isRemovingCoupon, } = useStoreCartCoupons(); useEffect( () => { if ( ! SHIPPING_ENABLED ) { return setShowShippingCosts( false ); } if ( isShippingCalculatorEnabled ) { if ( isShippingCostHidden ) { if ( shippingCalculatorAddress.country ) { return setShowShippingCosts( true ); } } else { return setShowShippingCosts( true ); } } return setShowShippingCosts( false ); }, [ isShippingCalculatorEnabled, isShippingCostHidden, shippingCalculatorAddress, ] ); /** * Given an API response with cart totals, generates an array of rows to display in the Cart block. * * @return {Object[]} Values to display in the cart block. */ const getTotalRowsConfig = () => { const totalItems = parseInt( cartTotals.total_items, 10 ); const totalItemsTax = parseInt( cartTotals.total_items_tax, 10 ); const totalRowsConfig = [ { label: __( 'Subtotal:', 'woo-gutenberg-products-block' ), value: DISPLAY_PRICES_INCLUDING_TAXES ? totalItems + totalItemsTax : totalItems, }, ]; const totalFees = parseInt( cartTotals.total_fees, 10 ); if ( totalFees > 0 ) { const totalFeesTax = parseInt( cartTotals.total_fees_tax, 10 ); totalRowsConfig.push( { label: __( 'Fees:', 'woo-gutenberg-products-block' ), value: DISPLAY_PRICES_INCLUDING_TAXES ? totalFees + totalFeesTax : totalFees, } ); } const totalDiscount = parseInt( cartTotals.total_discount, 10 ); if ( totalDiscount > 0 || cartCoupons.length !== 0 ) { const totalDiscountTax = parseInt( cartTotals.total_discount_tax, 10 ); // @todo The remove coupon button is a placeholder - replace with new // chip component. totalRowsConfig.push( { label: __( 'Discount:', 'woo-gutenberg-products-block' ), value: ( DISPLAY_PRICES_INCLUDING_TAXES ? totalDiscount + totalDiscountTax : totalDiscount ) * -1, description: ( { cartCoupons.map( ( cartCoupon ) => ( ) ) } ), } ); } if ( ! DISPLAY_PRICES_INCLUDING_TAXES ) { const totalTax = parseInt( cartTotals.total_tax, 10 ); totalRowsConfig.push( { label: __( 'Taxes:', 'woo-gutenberg-products-block' ), value: totalTax, } ); } if ( SHIPPING_ENABLED && isShippingCalculatorEnabled ) { const totalShipping = parseInt( cartTotals.total_shipping, 10 ); const totalShippingTax = parseInt( cartTotals.total_shipping_tax, 10 ); totalRowsConfig.push( { label: __( 'Shipping:', 'woo-gutenberg-products-block' ), value: DISPLAY_PRICES_INCLUDING_TAXES ? totalShipping + totalShippingTax : totalShipping, description: ( <> ), } ); } return totalRowsConfig; }; const totalsCurrency = getCurrencyFromPriceResponse( cartTotals ); const totalRowsConfig = getTotalRowsConfig(); const ShippingCalculatorOptions = () => (
{ __( 'Choose the shipping method.', 'woo-gutenberg-products-block' ) } { shippingRates ? ( ) : ( setSelectedShippingRate( newSelectedShippingOption ) } /> ) }
); const cartClassName = classnames( 'wc-block-cart', { 'wc-block-cart--is-loading': isLoading, } ); return (

{ __( 'Cart totals', 'woo-gutenberg-products-block' ) }

{ totalRowsConfig.map( ( { label, value, description } ) => ( ) ) } { showShippingCosts && } { COUPONS_ENABLED && ( ) }
); }; Cart.propTypes = { cartItems: PropTypes.array, cartTotals: PropTypes.shape( { total_items: PropTypes.string, total_items_tax: PropTypes.string, total_fees: PropTypes.string, total_fees_tax: PropTypes.string, total_discount: PropTypes.string, total_discount_tax: PropTypes.string, total_shipping: PropTypes.string, total_shipping_tax: PropTypes.string, total_tax: PropTypes.string, total_price: PropTypes.string, } ), isShippingCalculatorEnabled: PropTypes.bool, isShippingCostHidden: PropTypes.bool, isLoading: PropTypes.bool, /** * List of shipping rates to display. If defined, shipping rates will not be fetched from the API (used for the block preview). */ shippingRates: PropTypes.array, }; export default Cart;