Add checkout sidebar (https://github.com/woocommerce/woocommerce-blocks/pull/1921)
This commit is contained in:
parent
87b87cee8a
commit
2147e8a22a
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import './style.scss';
|
||||
|
||||
export { default as Sidebar } from './sidebar';
|
||||
export { default as Main } from './main';
|
||||
export { default as SidebarLayout } from './sidebar-layout';
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import classNames from 'classnames';
|
||||
|
||||
const Main = ( { children, className } ) => {
|
||||
return (
|
||||
<div className={ classNames( 'wc-block-main', className ) }>
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Main;
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import classNames from 'classnames';
|
||||
|
||||
const SidebarLayout = ( { children, className } ) => {
|
||||
return (
|
||||
<div className={ classNames( 'wc-block-sidebar-layout', className ) }>
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SidebarLayout;
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import classNames from 'classnames';
|
||||
|
||||
const Sidebar = ( { children, className } ) => {
|
||||
return (
|
||||
<div className={ classNames( 'wc-block-sidebar', className ) }>
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Sidebar;
|
|
@ -0,0 +1,86 @@
|
|||
.wc-block-sidebar-layout {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 (-$gap) $gap;
|
||||
|
||||
.wc-block-main {
|
||||
flex: 1 0 65%;
|
||||
margin: 0;
|
||||
padding: 0 $gap;
|
||||
min-width: 500px;
|
||||
}
|
||||
|
||||
.wc-block-sidebar {
|
||||
flex: 1 1 35%;
|
||||
margin: 0;
|
||||
max-width: 35%;
|
||||
padding: 0 $gap;
|
||||
|
||||
// Reset Gutenberg <Panel> styles when used in the sidebar.
|
||||
.components-panel__body {
|
||||
border-top: 1px solid $core-grey-light-600;
|
||||
border-bottom: 1px solid $core-grey-light-600;
|
||||
|
||||
&.is-opened {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
|
||||
> .components-panel__body-title {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> .components-panel__body-title,
|
||||
.components-panel__body-toggle {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.components-panel__body-toggle {
|
||||
font-weight: normal;
|
||||
font-size: inherit;
|
||||
padding-left: 0;
|
||||
padding-right: 36px;
|
||||
|
||||
&.components-button,
|
||||
&.components-button:focus:not(:disabled):not([aria-disabled="true"]) {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint( "<782px" ) {
|
||||
.wc-block-sidebar-layout {
|
||||
display: block;
|
||||
margin: 0 0 $gap;
|
||||
|
||||
.wc-block-main {
|
||||
padding: 0;
|
||||
flex: none;
|
||||
min-width: 200px;
|
||||
}
|
||||
.wc-block-sidebar {
|
||||
padding: 0;
|
||||
flex: none;
|
||||
max-width: 100%;
|
||||
|
||||
// Reset (remove) totals "card" styling on mobile.
|
||||
.components-card {
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
}
|
||||
.components-card__body {
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ import LoadingMask from '../../loading-mask';
|
|||
const TotalsCouponCodeInput = ( {
|
||||
instanceId,
|
||||
isLoading = false,
|
||||
initialOpen,
|
||||
onSubmit = () => {},
|
||||
} ) => {
|
||||
const [ couponValue, setCouponValue ] = useState( '' );
|
||||
|
@ -49,7 +50,7 @@ const TotalsCouponCodeInput = ( {
|
|||
htmlFor={ `wc-block-coupon-code__input-${ instanceId }` }
|
||||
/>
|
||||
}
|
||||
initialOpen={ true }
|
||||
initialOpen={ initialOpen }
|
||||
>
|
||||
<LoadingMask
|
||||
screenReaderLabel={ __(
|
||||
|
|
|
@ -36,11 +36,15 @@ const TotalsShippingItem = ( {
|
|||
currency={ currency }
|
||||
description={
|
||||
<>
|
||||
<ShippingLocation address={ shippingAddress } />
|
||||
<ShippingCalculator
|
||||
address={ shippingAddress }
|
||||
setAddress={ updateShippingAddress }
|
||||
/>
|
||||
{ shippingAddress && (
|
||||
<ShippingLocation address={ shippingAddress } />
|
||||
) }
|
||||
{ updateShippingAddress && shippingAddress && (
|
||||
<ShippingCalculator
|
||||
address={ shippingAddress }
|
||||
setAddress={ updateShippingAddress }
|
||||
/>
|
||||
) }
|
||||
</>
|
||||
}
|
||||
label={ __( 'Shipping', 'woo-gutenberg-products-block' ) }
|
||||
|
|
|
@ -25,6 +25,11 @@ import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-mone
|
|||
import { decodeEntities } from '@wordpress/html-entities';
|
||||
import { useStoreCartCoupons, useShippingRates } from '@woocommerce/base-hooks';
|
||||
import classnames from 'classnames';
|
||||
import {
|
||||
Sidebar,
|
||||
SidebarLayout,
|
||||
Main,
|
||||
} from '@woocommerce/base-components/sidebar-layout';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -118,15 +123,15 @@ const Cart = ( {
|
|||
} );
|
||||
|
||||
return (
|
||||
<div className={ cartClassName }>
|
||||
<div className="wc-block-cart__main">
|
||||
<SidebarLayout className={ cartClassName }>
|
||||
<Main className="wc-block-cart__main">
|
||||
<CartLineItemsTitle itemCount={ cartItems.length } />
|
||||
<CartLineItemsTable
|
||||
lineItems={ cartItems }
|
||||
isLoading={ isLoading }
|
||||
/>
|
||||
</div>
|
||||
<div className="wc-block-cart__sidebar">
|
||||
</Main>
|
||||
<Sidebar className="wc-block-cart__sidebar">
|
||||
<Card isElevated={ true }>
|
||||
<CardBody>
|
||||
<h2 className="wc-block-cart__totals-title">
|
||||
|
@ -183,6 +188,7 @@ const Cart = ( {
|
|||
{ COUPONS_ENABLED && (
|
||||
<TotalsCouponCodeInput
|
||||
onSubmit={ applyCoupon }
|
||||
initialOpen={ true }
|
||||
isLoading={ isApplyingCoupon }
|
||||
/>
|
||||
) }
|
||||
|
@ -193,8 +199,8 @@ const Cart = ( {
|
|||
<CheckoutButton />
|
||||
</CardBody>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</Sidebar>
|
||||
</SidebarLayout>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,21 +1,6 @@
|
|||
.wc-block-cart {
|
||||
color: $core-grey-dark-600;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 (-$gap) $gap;
|
||||
|
||||
.wc-block-cart__main {
|
||||
flex: 1 0 65%;
|
||||
margin: 0;
|
||||
padding: 0 $gap;
|
||||
min-width: 500px;
|
||||
}
|
||||
.wc-block-cart__sidebar {
|
||||
flex: 1 1 35%;
|
||||
margin: 0;
|
||||
max-width: 35%;
|
||||
padding: 0 $gap;
|
||||
}
|
||||
.wc-block-cart__item-count {
|
||||
float: right;
|
||||
}
|
||||
|
@ -275,75 +260,13 @@ table.wc-block-cart-items {
|
|||
display: flex;
|
||||
}
|
||||
|
||||
// Reset Gutenberg <Panel> styles when used in the sidebar.
|
||||
.wc-block-cart__sidebar {
|
||||
.components-panel__body {
|
||||
border-top: 1px solid $core-grey-light-600;
|
||||
border-bottom: 1px solid $core-grey-light-600;
|
||||
|
||||
&.is-opened {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
|
||||
> .components-panel__body-title {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> .components-panel__body-title,
|
||||
.components-panel__body-toggle {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.components-panel__body-toggle {
|
||||
font-weight: normal;
|
||||
font-size: inherit;
|
||||
padding-left: 0;
|
||||
padding-right: 36px;
|
||||
|
||||
&.components-button,
|
||||
&.components-button:focus:not(:disabled):not([aria-disabled="true"]) {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mobile styles.
|
||||
@include breakpoint( "<782px" ) {
|
||||
.wc-block-cart:not(.wc-block-cart--is-loading):not(.wc-block-cart--skeleton) {
|
||||
display: block;
|
||||
margin: 0 0 $gap;
|
||||
.wc-block-cart__main {
|
||||
padding: 0;
|
||||
flex: none;
|
||||
min-width: 200px;
|
||||
}
|
||||
.wc-block-cart__sidebar {
|
||||
padding: 0;
|
||||
flex: none;
|
||||
max-width: 100%;
|
||||
|
||||
.wc-block-cart {
|
||||
.wc-block-sidebar {
|
||||
.wc-block-cart__totals-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Reset (remove) totals "card" styling on mobile.
|
||||
.components-card {
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
}
|
||||
.components-card__body {
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
table.wc-block-cart-items {
|
||||
|
|
|
@ -24,14 +24,26 @@ import {
|
|||
import { SHIPPING_ENABLED } from '@woocommerce/block-settings';
|
||||
import { decodeEntities } from '@wordpress/html-entities';
|
||||
import { useShippingRates } from '@woocommerce/base-hooks';
|
||||
import {
|
||||
Sidebar,
|
||||
SidebarLayout,
|
||||
Main,
|
||||
} from '@woocommerce/base-components/sidebar-layout'; // @todo
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import CheckoutSidebar from './sidebar.js';
|
||||
import './style.scss';
|
||||
import '../../../payment-methods-demo';
|
||||
|
||||
const Block = ( { attributes, isEditor = false, shippingRates = [] } ) => {
|
||||
const Block = ( {
|
||||
attributes,
|
||||
cartCoupons = [],
|
||||
cartTotals = {},
|
||||
isEditor = false,
|
||||
shippingRates = [],
|
||||
} ) => {
|
||||
const [ selectedShippingRate, setSelectedShippingRate ] = useState( {} );
|
||||
const [ contactFields, setContactFields ] = useState( {} );
|
||||
const [ shouldSavePayment, setShouldSavePayment ] = useState( true );
|
||||
|
@ -80,228 +92,248 @@ const Block = ( { attributes, isEditor = false, shippingRates = [] } ) => {
|
|||
|
||||
return (
|
||||
<CheckoutProvider isEditor={ isEditor }>
|
||||
<ExpressCheckoutFormControl />
|
||||
<CheckoutForm>
|
||||
<FormStep
|
||||
id="contact-fields"
|
||||
className="wc-block-checkout__contact-fields"
|
||||
title={ __(
|
||||
'Contact information',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
description={ __(
|
||||
"We'll use this email to send you details and updates about your order.",
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
stepHeadingContent={ () => (
|
||||
<Fragment>
|
||||
{ __(
|
||||
'Already have an account? ',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
<a href="/wp-login.php">
|
||||
{ __(
|
||||
'Log in.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</a>
|
||||
</Fragment>
|
||||
) }
|
||||
>
|
||||
<TextInput
|
||||
type="email"
|
||||
label={ __(
|
||||
'Email address',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
value={ contactFields.email }
|
||||
autoComplete="email"
|
||||
onChange={ ( newValue ) =>
|
||||
setContactFields( {
|
||||
...contactFields,
|
||||
email: newValue,
|
||||
} )
|
||||
}
|
||||
required={ true }
|
||||
/>
|
||||
<CheckboxControl
|
||||
className="wc-block-checkout__keep-updated"
|
||||
label={ __(
|
||||
'Keep me up to date on news and exclusive offers',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ contactFields.keepUpdated }
|
||||
onChange={ () =>
|
||||
setContactFields( {
|
||||
...contactFields,
|
||||
keepUpdated: ! contactFields.keepUpdated,
|
||||
} )
|
||||
}
|
||||
/>
|
||||
</FormStep>
|
||||
{ SHIPPING_ENABLED && (
|
||||
<FormStep
|
||||
id="shipping-fields"
|
||||
className="wc-block-checkout__shipping-fields"
|
||||
title={ __(
|
||||
'Shipping address',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
description={ __(
|
||||
'Enter the physical address where you want us to deliver your order.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
>
|
||||
<AddressForm
|
||||
onChange={ setShippingFields }
|
||||
values={ shippingFields }
|
||||
fields={ Object.keys( addressFields ) }
|
||||
fieldConfig={ addressFields }
|
||||
/>
|
||||
{ attributes.showPhoneField && (
|
||||
<TextInput
|
||||
type="tel"
|
||||
label={
|
||||
attributes.requirePhoneField
|
||||
? __(
|
||||
'Phone',
|
||||
'woo-gutenberg-products-block'
|
||||
)
|
||||
: __(
|
||||
'Phone (optional)',
|
||||
'woo-gutenberg-products-block'
|
||||
)
|
||||
}
|
||||
value={ shippingFields.phone }
|
||||
autoComplete="tel"
|
||||
onChange={ ( newValue ) =>
|
||||
setShippingFields( {
|
||||
...shippingFields,
|
||||
phone: newValue,
|
||||
} )
|
||||
}
|
||||
required={ attributes.requirePhoneField }
|
||||
/>
|
||||
) }
|
||||
<CheckboxControl
|
||||
className="wc-block-checkout__use-address-for-billing"
|
||||
label={ __(
|
||||
'Use same address for billing',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ useShippingAddressAsBilling }
|
||||
onChange={ ( isChecked ) =>
|
||||
setUseShippingAsBilling( isChecked )
|
||||
}
|
||||
/>
|
||||
</FormStep>
|
||||
) }
|
||||
{ showBillingFields && (
|
||||
<FormStep
|
||||
id="billing-fields"
|
||||
className="wc-block-checkout__billing-fields"
|
||||
title={ __(
|
||||
'Billing address',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
description={ __(
|
||||
'Enter the address that matches your card or payment method.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
>
|
||||
<AddressForm
|
||||
onChange={ setBillingFields }
|
||||
type="billing"
|
||||
values={ billingFields }
|
||||
fields={ Object.keys( addressFields ) }
|
||||
fieldConfig={ addressFields }
|
||||
/>
|
||||
</FormStep>
|
||||
) }
|
||||
{ SHIPPING_ENABLED &&
|
||||
( shippingRates.length === 0 && isEditor ? (
|
||||
<NoShipping />
|
||||
) : (
|
||||
<SidebarLayout>
|
||||
<Main>
|
||||
<ExpressCheckoutFormControl />
|
||||
<CheckoutForm>
|
||||
<FormStep
|
||||
id="shipping-option"
|
||||
className="wc-block-checkout__shipping-option"
|
||||
id="contact-fields"
|
||||
className="wc-block-checkout__contact-fields"
|
||||
title={ __(
|
||||
'Shipping options',
|
||||
'Contact information',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
description={ __(
|
||||
'Select your shipping method below.',
|
||||
"We'll use this email to send you details and updates about your order.",
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
stepHeadingContent={ () => (
|
||||
<Fragment>
|
||||
{ __(
|
||||
'Already have an account? ',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
<a href="/wp-login.php">
|
||||
{ __(
|
||||
'Log in.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</a>
|
||||
</Fragment>
|
||||
) }
|
||||
>
|
||||
<ShippingRatesControl
|
||||
address={
|
||||
shippingFields.country
|
||||
? {
|
||||
address_1:
|
||||
shippingFields.address_1,
|
||||
address_2:
|
||||
shippingFields.apartment,
|
||||
city: shippingFields.city,
|
||||
state: shippingFields.state,
|
||||
postcode:
|
||||
shippingFields.postcode,
|
||||
country: shippingFields.country,
|
||||
}
|
||||
: null
|
||||
}
|
||||
noResultsMessage={ __(
|
||||
'There are no shipping options available. Please ensure that your address has been entered correctly, or contact us if you need any help.',
|
||||
<TextInput
|
||||
type="email"
|
||||
label={ __(
|
||||
'Email address',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
renderOption={
|
||||
renderShippingRatesControlOption
|
||||
value={ contactFields.email }
|
||||
autoComplete="email"
|
||||
onChange={ ( newValue ) =>
|
||||
setContactFields( {
|
||||
...contactFields,
|
||||
email: newValue,
|
||||
} )
|
||||
}
|
||||
shippingRates={ shippingRates }
|
||||
shippingRatesLoading={ shippingRatesLoading }
|
||||
required={ true }
|
||||
/>
|
||||
|
||||
<CheckboxControl
|
||||
className="wc-block-checkout__add-note"
|
||||
label="Add order notes?"
|
||||
checked={ selectedShippingRate.orderNote }
|
||||
className="wc-block-checkout__keep-updated"
|
||||
label={ __(
|
||||
'Keep me up to date on news and exclusive offers',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ contactFields.keepUpdated }
|
||||
onChange={ () =>
|
||||
setSelectedShippingRate( {
|
||||
...selectedShippingRate,
|
||||
orderNote: ! selectedShippingRate.orderNote,
|
||||
setContactFields( {
|
||||
...contactFields,
|
||||
keepUpdated: ! contactFields.keepUpdated,
|
||||
} )
|
||||
}
|
||||
/>
|
||||
</FormStep>
|
||||
) ) }
|
||||
<FormStep
|
||||
id="payment-method"
|
||||
className="wc-block-checkout__payment-method"
|
||||
title={ __(
|
||||
'Payment method',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
description={ __(
|
||||
'Select a payment method below.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
>
|
||||
<PaymentMethods />
|
||||
{ /*@todo this should be something the payment method controls*/ }
|
||||
<CheckboxControl
|
||||
className="wc-block-checkout__save-card-info"
|
||||
label={ __(
|
||||
'Save payment information to my account for future purchases.',
|
||||
'woo-gutenberg-products-block'
|
||||
{ SHIPPING_ENABLED && (
|
||||
<FormStep
|
||||
id="shipping-fields"
|
||||
className="wc-block-checkout__shipping-fields"
|
||||
title={ __(
|
||||
'Shipping address',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
description={ __(
|
||||
'Enter the physical address where you want us to deliver your order.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
>
|
||||
<AddressForm
|
||||
onChange={ setShippingFields }
|
||||
values={ shippingFields }
|
||||
fields={ Object.keys( addressFields ) }
|
||||
fieldConfig={ addressFields }
|
||||
/>
|
||||
{ attributes.showPhoneField && (
|
||||
<TextInput
|
||||
type="tel"
|
||||
label={
|
||||
attributes.requirePhoneField
|
||||
? __(
|
||||
'Phone',
|
||||
'woo-gutenberg-products-block'
|
||||
)
|
||||
: __(
|
||||
'Phone (optional)',
|
||||
'woo-gutenberg-products-block'
|
||||
)
|
||||
}
|
||||
value={ shippingFields.phone }
|
||||
autoComplete="tel"
|
||||
onChange={ ( newValue ) =>
|
||||
setShippingFields( {
|
||||
...shippingFields,
|
||||
phone: newValue,
|
||||
} )
|
||||
}
|
||||
required={
|
||||
attributes.requirePhoneField
|
||||
}
|
||||
/>
|
||||
) }
|
||||
<CheckboxControl
|
||||
className="wc-block-checkout__use-address-for-billing"
|
||||
label={ __(
|
||||
'Use same address for billing',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ useShippingAddressAsBilling }
|
||||
onChange={ ( isChecked ) =>
|
||||
setUseShippingAsBilling( isChecked )
|
||||
}
|
||||
/>
|
||||
</FormStep>
|
||||
) }
|
||||
checked={ shouldSavePayment }
|
||||
onChange={ () =>
|
||||
setShouldSavePayment( ! shouldSavePayment )
|
||||
}
|
||||
{ showBillingFields && (
|
||||
<FormStep
|
||||
id="billing-fields"
|
||||
className="wc-block-checkout__billing-fields"
|
||||
title={ __(
|
||||
'Billing address',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
description={ __(
|
||||
'Enter the address that matches your card or payment method.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
>
|
||||
<AddressForm
|
||||
onChange={ setBillingFields }
|
||||
type="billing"
|
||||
values={ billingFields }
|
||||
fields={ Object.keys( addressFields ) }
|
||||
fieldConfig={ addressFields }
|
||||
/>
|
||||
</FormStep>
|
||||
) }
|
||||
{ SHIPPING_ENABLED &&
|
||||
( shippingRates.length === 0 && isEditor ? (
|
||||
<NoShipping />
|
||||
) : (
|
||||
<FormStep
|
||||
id="shipping-option"
|
||||
className="wc-block-checkout__shipping-option"
|
||||
title={ __(
|
||||
'Shipping options',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
description={ __(
|
||||
'Select your shipping method below.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
>
|
||||
<ShippingRatesControl
|
||||
address={
|
||||
shippingFields.country
|
||||
? {
|
||||
address_1:
|
||||
shippingFields.address_1,
|
||||
address_2:
|
||||
shippingFields.apartment,
|
||||
city:
|
||||
shippingFields.city,
|
||||
state:
|
||||
shippingFields.state,
|
||||
postcode:
|
||||
shippingFields.postcode,
|
||||
country:
|
||||
shippingFields.country,
|
||||
}
|
||||
: null
|
||||
}
|
||||
noResultsMessage={ __(
|
||||
'There are no shipping options available. Please ensure that your address has been entered correctly, or contact us if you need any help.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
renderOption={
|
||||
renderShippingRatesControlOption
|
||||
}
|
||||
shippingRates={ shippingRates }
|
||||
shippingRatesLoading={
|
||||
shippingRatesLoading
|
||||
}
|
||||
/>
|
||||
|
||||
<CheckboxControl
|
||||
className="wc-block-checkout__add-note"
|
||||
label="Add order notes?"
|
||||
checked={
|
||||
selectedShippingRate.orderNote
|
||||
}
|
||||
onChange={ () =>
|
||||
setSelectedShippingRate( {
|
||||
...selectedShippingRate,
|
||||
orderNote: ! selectedShippingRate.orderNote,
|
||||
} )
|
||||
}
|
||||
/>
|
||||
</FormStep>
|
||||
) ) }
|
||||
<FormStep
|
||||
id="payment-method"
|
||||
className="wc-block-checkout__payment-method"
|
||||
title={ __(
|
||||
'Payment method',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
description={ __(
|
||||
'Select a payment method below.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
>
|
||||
<PaymentMethods />
|
||||
{ /*@todo this should be something the payment method controls*/ }
|
||||
<CheckboxControl
|
||||
className="wc-block-checkout__save-card-info"
|
||||
label={ __(
|
||||
'Save payment information to my account for future purchases.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ shouldSavePayment }
|
||||
onChange={ () =>
|
||||
setShouldSavePayment( ! shouldSavePayment )
|
||||
}
|
||||
/>
|
||||
</FormStep>
|
||||
{ attributes.showPolicyLinks && <Policies /> }
|
||||
</CheckoutForm>
|
||||
</Main>
|
||||
<Sidebar>
|
||||
<CheckoutSidebar
|
||||
cartCoupons={ cartCoupons }
|
||||
cartTotals={ cartTotals }
|
||||
shippingRates={ shippingRates }
|
||||
/>
|
||||
</FormStep>
|
||||
{ attributes.showPolicyLinks && <Policies /> }
|
||||
</CheckoutForm>
|
||||
</Sidebar>
|
||||
</SidebarLayout>
|
||||
</CheckoutProvider>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { withFeedbackPrompt } from '@woocommerce/block-hocs';
|
||||
import { previewShippingRates } from '@woocommerce/resource-previews';
|
||||
import {
|
||||
previewCart,
|
||||
previewShippingRates,
|
||||
} from '@woocommerce/resource-previews';
|
||||
import { InspectorControls } from '@wordpress/block-editor';
|
||||
import {
|
||||
PanelBody,
|
||||
|
@ -216,6 +219,7 @@ const CheckoutEditor = ( { attributes, setAttributes } ) => {
|
|||
>
|
||||
<Block
|
||||
attributes={ attributes }
|
||||
cartTotals={ previewCart.totals }
|
||||
isEditor={ true }
|
||||
shippingRates={
|
||||
SHIPPING_METHODS_EXIST ? previewShippingRates : []
|
||||
|
|
|
@ -24,7 +24,12 @@ import renderFrontend from '../../../utils/render-frontend.js';
|
|||
* @param {Object} props Props for the block.
|
||||
*/
|
||||
const CheckoutFrontend = ( props ) => {
|
||||
const { cartErrors, shippingRates } = useStoreCart();
|
||||
const {
|
||||
cartCoupons,
|
||||
cartErrors,
|
||||
cartTotals,
|
||||
shippingRates,
|
||||
} = useStoreCart();
|
||||
|
||||
if ( cartErrors && cartErrors.length > 0 ) {
|
||||
throw new Error( cartErrors[ 0 ].message );
|
||||
|
@ -50,7 +55,12 @@ const CheckoutFrontend = ( props ) => {
|
|||
) }
|
||||
showErrorMessage={ CURRENT_USER_IS_ADMIN }
|
||||
>
|
||||
<Block { ...props } shippingRates={ shippingRates } />
|
||||
<Block
|
||||
{ ...props }
|
||||
cartCoupons={ cartCoupons }
|
||||
cartTotals={ cartTotals }
|
||||
shippingRates={ shippingRates }
|
||||
/>
|
||||
</BlockErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import {
|
||||
SubtotalsItem,
|
||||
TotalsFeesItem,
|
||||
TotalsCouponCodeInput,
|
||||
TotalsDiscountItem,
|
||||
TotalsFooterItem,
|
||||
TotalsShippingItem,
|
||||
TotalsTaxesItem,
|
||||
} from '@woocommerce/base-components/totals';
|
||||
import { getCurrencyFromPriceResponse } from '@woocommerce/base-utils';
|
||||
import {
|
||||
COUPONS_ENABLED,
|
||||
DISPLAY_CART_PRICES_INCLUDING_TAX,
|
||||
} from '@woocommerce/block-settings';
|
||||
import { useStoreCartCoupons } from '@woocommerce/base-hooks';
|
||||
|
||||
const CheckoutSidebar = ( {
|
||||
cartCoupons = [],
|
||||
cartTotals = {},
|
||||
shippingRates,
|
||||
} ) => {
|
||||
const {
|
||||
applyCoupon,
|
||||
removeCoupon,
|
||||
isApplyingCoupon,
|
||||
isRemovingCoupon,
|
||||
} = useStoreCartCoupons();
|
||||
const shippingAddress = shippingRates[ 0 ]?.destination;
|
||||
const totalsCurrency = getCurrencyFromPriceResponse( cartTotals );
|
||||
|
||||
return (
|
||||
<>
|
||||
<SubtotalsItem currency={ totalsCurrency } values={ cartTotals } />
|
||||
<TotalsFeesItem currency={ totalsCurrency } values={ cartTotals } />
|
||||
<TotalsDiscountItem
|
||||
cartCoupons={ cartCoupons }
|
||||
currency={ totalsCurrency }
|
||||
isRemovingCoupon={ isRemovingCoupon }
|
||||
removeCoupon={ removeCoupon }
|
||||
values={ cartTotals }
|
||||
/>
|
||||
<TotalsShippingItem
|
||||
currency={ totalsCurrency }
|
||||
shippingAddress={ shippingAddress }
|
||||
values={ cartTotals }
|
||||
/>
|
||||
{ ! DISPLAY_CART_PRICES_INCLUDING_TAX && (
|
||||
<TotalsTaxesItem
|
||||
currency={ totalsCurrency }
|
||||
values={ cartTotals }
|
||||
/>
|
||||
) }
|
||||
{ COUPONS_ENABLED && (
|
||||
<TotalsCouponCodeInput
|
||||
onSubmit={ applyCoupon }
|
||||
initialOpen={ false }
|
||||
isLoading={ isApplyingCoupon }
|
||||
/>
|
||||
) }
|
||||
<TotalsFooterItem
|
||||
currency={ totalsCurrency }
|
||||
values={ cartTotals }
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default CheckoutSidebar;
|
|
@ -59,16 +59,16 @@ const reducer = (
|
|||
currency_thousand_separator: ',',
|
||||
currency_prefix: '',
|
||||
currency_suffix: '',
|
||||
total_items: 0,
|
||||
total_items_tax: 0,
|
||||
total_fees: 0,
|
||||
total_fees_tax: 0,
|
||||
total_discount: 0,
|
||||
total_discount_tax: 0,
|
||||
total_shipping: 0,
|
||||
total_shipping_tax: 0,
|
||||
total_price: 0,
|
||||
total_tax: 0,
|
||||
total_items: '0',
|
||||
total_items_tax: '0',
|
||||
total_fees: '0',
|
||||
total_fees_tax: '0',
|
||||
total_discount: '0',
|
||||
total_discount_tax: '0',
|
||||
total_shipping: '0',
|
||||
total_shipping_tax: '0',
|
||||
total_price: '0',
|
||||
total_tax: '0',
|
||||
tax_lines: [],
|
||||
},
|
||||
},
|
||||
|
|
|
@ -37,16 +37,16 @@ export const getCartTotals = ( state ) => {
|
|||
currency_thousand_separator: ',',
|
||||
currency_prefix: '',
|
||||
currency_suffix: '',
|
||||
total_items: 0,
|
||||
total_items_tax: 0,
|
||||
total_fees: 0,
|
||||
total_fees_tax: 0,
|
||||
total_discount: 0,
|
||||
total_discount_tax: 0,
|
||||
total_shipping: 0,
|
||||
total_shipping_tax: 0,
|
||||
total_price: 0,
|
||||
total_tax: 0,
|
||||
total_items: '0',
|
||||
total_items_tax: '0',
|
||||
total_fees: '0',
|
||||
total_fees_tax: '0',
|
||||
total_discount: '0',
|
||||
total_discount_tax: '0',
|
||||
total_shipping: '0',
|
||||
total_shipping_tax: '0',
|
||||
total_price: '0',
|
||||
total_tax: '0',
|
||||
tax_lines: [],
|
||||
}
|
||||
);
|
||||
|
|
|
@ -80,8 +80,8 @@ class Cart extends AbstractBlock {
|
|||
*/
|
||||
protected function get_skeleton() {
|
||||
return '
|
||||
<div class="wc-block-cart wc-block-cart--is-loading wc-block-cart--skeleton" aria-hidden="true">
|
||||
<div class="wc-block-cart__main">
|
||||
<div class="wc-block-sidebar-layout wc-block-cart wc-block-cart--is-loading wc-block-cart--skeleton" aria-hidden="true">
|
||||
<div class="wc-block-main wc-block-cart__main">
|
||||
<h2><span></span></h2>
|
||||
<table class="wc-block-cart-items">
|
||||
<thead>
|
||||
|
@ -153,7 +153,7 @@ class Cart extends AbstractBlock {
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="wc-block-cart__sidebar">
|
||||
<div class="wc-block-sidebar wc-block-cart__sidebar">
|
||||
<div class="components-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue