Implement "return to cart" and "place order" buttons on checkout (https://github.com/woocommerce/woocommerce-blocks/pull/1926)
* Add back icon * Add cart URL constant * Add button components * Implement button components into checkout * Update checkout styles to match mockup incl updates to margins and padding * Add options to control return to cart link * Use checkout context * Update snapshot * Update context * href * Color/arrow styling * Implement select instead of open URL field * Add notice and updated settings control * Show notice conditonally * Store permalinks to avoid extra API requests, and get pages via API * Update snapshots * Fix double layout conflict * Switch back to ID and add permalink via block setting * snaps * Fix snapshot; add default shape for pages * Feedback * Better undefined handling * Update assets/js/blocks/cart-checkout/checkout/block.js Co-Authored-By: Darren Ethier <darren@roughsmootheng.in> Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
This commit is contained in:
parent
3e7a2d41e4
commit
01602f90bf
|
@ -6,3 +6,5 @@ export { default as ProductName } from './product-name';
|
|||
export { default as ProductPrice } from './product-price';
|
||||
export { default as ProductSaleBadge } from './product-sale-badge';
|
||||
export { default as ProductVariationData } from './product-variation-data';
|
||||
export { default as PlaceOrderButton } from './place-order-button';
|
||||
export { default as ReturnToCartButton } from './return-to-cart-button';
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useCheckoutContext } from '@woocommerce/base-context';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import Button from '../button';
|
||||
|
||||
const PlaceOrderButton = () => {
|
||||
const { submitLabel, onSubmit } = useCheckoutContext();
|
||||
|
||||
return (
|
||||
<Button
|
||||
className="wc-block-components-checkout-place-order-button"
|
||||
onClick={ onSubmit }
|
||||
>
|
||||
{ submitLabel }
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
export default PlaceOrderButton;
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { CART_URL } from '@woocommerce/block-settings';
|
||||
import { Icon, arrowBack } from '@woocommerce/icons';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import './style.scss';
|
||||
|
||||
const ReturnToCartButton = ( { link } ) => {
|
||||
return (
|
||||
<a
|
||||
href={ link || CART_URL }
|
||||
className="wc-block-components-checkout-return-to-cart-button"
|
||||
>
|
||||
<Icon srcElement={ arrowBack } />
|
||||
{ __( 'Return to Cart', 'woo-gutenberg-products-block' ) }
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
export default ReturnToCartButton;
|
|
@ -0,0 +1,10 @@
|
|||
.wc-block-components-checkout-return-to-cart-button {
|
||||
color: $gray-60;
|
||||
text-decoration: none !important;
|
||||
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
margin-right: 0.25em;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ $line-offset-from-circle-size: 8px;
|
|||
.wc-block-checkout-form fieldset.wc-block-checkout-step {
|
||||
position: relative;
|
||||
border: none;
|
||||
padding: 0 0 $gap-larger $gap-large;
|
||||
padding: 0 $gap-larger $gap-larger $gap-larger;
|
||||
background: none;
|
||||
margin: 0;
|
||||
|
||||
|
@ -63,7 +63,7 @@ $line-offset-from-circle-size: 8px;
|
|||
width: 1px;
|
||||
background-color: $gray-10;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
left: $circle-size/2;
|
||||
top: $circle-size + $line-offset-from-circle-size;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ $line-offset-from-circle-size: 8px;
|
|||
position: absolute;
|
||||
width: $circle-size;
|
||||
height: $circle-size;
|
||||
left: -$circle-size / 2;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background: $gray-20;
|
||||
color: $white;
|
||||
|
|
|
@ -1,12 +1,3 @@
|
|||
.wc-block-checkout-form {
|
||||
margin-right: $gap-large;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
// Responsive media styles.
|
||||
@include breakpoint( "<480px" ) {
|
||||
.wc-block-checkout-form {
|
||||
margin-left: $gap-smaller;
|
||||
margin-right: $gap;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
text-align: center;
|
||||
list-style: none outside;
|
||||
line-height: 1;
|
||||
margin: 2em 0 1em;
|
||||
margin: $gap-large 0;
|
||||
}
|
||||
.wc-block-components-checkout-policies__item {
|
||||
list-style: none outside;
|
||||
|
@ -18,5 +18,6 @@
|
|||
a {
|
||||
padding: 0 0.25em;
|
||||
text-decoration: underline;
|
||||
color: $gray-60;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
margin: auto;
|
||||
border: 2px solid $black;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
padding: 8px;
|
||||
|
||||
.wc-block-component-express-checkout__title {
|
||||
position: relative;
|
||||
|
@ -50,7 +50,7 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
padding: 0 ($gap-large+14px);
|
||||
padding: 0 $gap-larger;
|
||||
margin: $gap-large 0;
|
||||
|
||||
&::before {
|
||||
|
|
|
@ -18,13 +18,10 @@ import { EditorProvider } from '@woocommerce/base-context';
|
|||
import FullCart from './full-cart';
|
||||
import EmptyCart from './empty-cart';
|
||||
|
||||
/**
|
||||
* Component to handle edit mode of "Cart Block".
|
||||
*/
|
||||
const CartEditor = ( { className, attributes, setAttributes } ) => {
|
||||
const BlockSettings = ( { attributes, setAttributes } ) => {
|
||||
const { isShippingCalculatorEnabled, isShippingCostHidden } = attributes;
|
||||
|
||||
const BlockSettings = () => (
|
||||
return (
|
||||
<InspectorControls>
|
||||
<PanelBody
|
||||
title={ __( 'Shipping rates', 'woo-gutenberg-products-block' ) }
|
||||
|
@ -64,7 +61,13 @@ const CartEditor = ( { className, attributes, setAttributes } ) => {
|
|||
</PanelBody>
|
||||
</InspectorControls>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Component to handle edit mode of "Cart Block".
|
||||
*/
|
||||
const CartEditor = ( { className, attributes, setAttributes } ) => {
|
||||
const { isShippingCalculatorEnabled, isShippingCostHidden } = attributes;
|
||||
return (
|
||||
<div className={ className }>
|
||||
<ViewSwitcher
|
||||
|
@ -87,7 +90,12 @@ const CartEditor = ( { className, attributes, setAttributes } ) => {
|
|||
<>
|
||||
{ currentView === 'full' && (
|
||||
<>
|
||||
{ SHIPPING_ENABLED && <BlockSettings /> }
|
||||
{ SHIPPING_ENABLED && (
|
||||
<BlockSettings
|
||||
attributes={ attributes }
|
||||
setAttributes={ setAttributes }
|
||||
/>
|
||||
) }
|
||||
<BlockErrorBoundary
|
||||
header={ __(
|
||||
'Cart Block Error',
|
||||
|
|
|
@ -62,13 +62,16 @@ const getProps = ( el ) => {
|
|||
|
||||
Object.keys( blockAttributes ).forEach( ( key ) => {
|
||||
if ( typeof el.dataset[ key ] !== 'undefined' ) {
|
||||
if (
|
||||
el.dataset[ key ] === 'true' ||
|
||||
el.dataset[ key ] === 'false'
|
||||
) {
|
||||
attributes[ key ] = el.dataset[ key ] !== 'false';
|
||||
} else {
|
||||
attributes[ key ] = el.dataset[ key ];
|
||||
switch ( blockAttributes[ key ].type ) {
|
||||
case 'boolean':
|
||||
attributes[ key ] = el.dataset[ key ] !== 'false';
|
||||
break;
|
||||
case 'number':
|
||||
attributes[ key ] = parseInt( el.dataset[ key ], 10 );
|
||||
break;
|
||||
default:
|
||||
attributes[ key ] = el.dataset[ key ];
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
attributes[ key ] = blockAttributes[ key ].default;
|
||||
|
|
|
@ -32,6 +32,14 @@ const blockAttributes = {
|
|||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
showReturnToCart: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
cartPageId: {
|
||||
type: 'number',
|
||||
default: 0,
|
||||
},
|
||||
};
|
||||
|
||||
export default blockAttributes;
|
||||
|
|
|
@ -11,6 +11,10 @@ import {
|
|||
NoShipping,
|
||||
Policies,
|
||||
} from '@woocommerce/base-components/checkout';
|
||||
import {
|
||||
PlaceOrderButton,
|
||||
ReturnToCartButton,
|
||||
} from '@woocommerce/base-components/cart-checkout';
|
||||
import TextInput from '@woocommerce/base-components/text-input';
|
||||
import ShippingRatesControl from '@woocommerce/base-components/shipping-rates-control';
|
||||
import CheckboxControl from '@woocommerce/base-components/checkbox-control';
|
||||
|
@ -29,6 +33,7 @@ import {
|
|||
SidebarLayout,
|
||||
Main,
|
||||
} from '@woocommerce/base-components/sidebar-layout';
|
||||
import { getSetting } from '@woocommerce/settings';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -324,6 +329,20 @@ const Block = ( {
|
|||
}
|
||||
/>
|
||||
</FormStep>
|
||||
<div className="wc-block-checkout__actions">
|
||||
{ attributes.showReturnToCart && (
|
||||
<ReturnToCartButton
|
||||
link={
|
||||
getSetting(
|
||||
'page-' +
|
||||
attributes?.cartPageId,
|
||||
false
|
||||
)
|
||||
}
|
||||
/>
|
||||
) }
|
||||
<PlaceOrderButton />
|
||||
</div>
|
||||
{ attributes.showPolicyLinks && <Policies /> }
|
||||
</CheckoutForm>
|
||||
</Main>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { withFeedbackPrompt } from '@woocommerce/block-hocs';
|
||||
import FeedbackPrompt from '@woocommerce/block-components/feedback-prompt';
|
||||
import {
|
||||
previewCart,
|
||||
previewShippingRates,
|
||||
|
@ -12,6 +12,7 @@ import {
|
|||
PanelBody,
|
||||
ToggleControl,
|
||||
CheckboxControl,
|
||||
SelectControl,
|
||||
Notice,
|
||||
} from '@wordpress/components';
|
||||
import BlockErrorBoundary from '@woocommerce/base-components/block-error-boundary';
|
||||
|
@ -19,9 +20,12 @@ import {
|
|||
PRIVACY_URL,
|
||||
TERMS_URL,
|
||||
SHIPPING_METHODS_EXIST,
|
||||
CHECKOUT_PAGE_ID,
|
||||
} from '@woocommerce/block-settings';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { getAdminLink } from '@woocommerce/settings';
|
||||
import { __experimentalCreateInterpolateElement } from 'wordpress-element';
|
||||
import { EditorProvider, useEditorContext } from '@woocommerce/base-context';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -29,9 +33,8 @@ import { __experimentalCreateInterpolateElement } from 'wordpress-element';
|
|||
import Block from './block.js';
|
||||
import './editor.scss';
|
||||
|
||||
const CheckoutEditor = ( { attributes, setAttributes } ) => {
|
||||
const BlockSettings = ( { attributes, setAttributes } ) => {
|
||||
const {
|
||||
className,
|
||||
useShippingAsBilling,
|
||||
showCompanyField,
|
||||
showAddress2Field,
|
||||
|
@ -39,201 +42,296 @@ const CheckoutEditor = ( { attributes, setAttributes } ) => {
|
|||
requireCompanyField,
|
||||
requirePhoneField,
|
||||
showPolicyLinks,
|
||||
showReturnToCart,
|
||||
cartPageId,
|
||||
} = attributes;
|
||||
const { currentPostId } = useEditorContext();
|
||||
const pages =
|
||||
useSelect( ( select ) => {
|
||||
return select( 'core' ).getEntityRecords( 'postType', 'page', {
|
||||
status: 'publish',
|
||||
orderby: 'title',
|
||||
order: 'asc',
|
||||
per_page: 100,
|
||||
} );
|
||||
}, [] ) || null;
|
||||
|
||||
return (
|
||||
<div className={ className }>
|
||||
<InspectorControls>
|
||||
<PanelBody
|
||||
title={ __(
|
||||
'Form options',
|
||||
<InspectorControls>
|
||||
{ currentPostId !== CHECKOUT_PAGE_ID && (
|
||||
<Notice
|
||||
className="wc-block-checkout__page-notice"
|
||||
isDismissible={ false }
|
||||
status="warning"
|
||||
>
|
||||
{ __experimentalCreateInterpolateElement(
|
||||
__(
|
||||
'If you would like to use this block as your default checkout you must update your <a>page settings in WooCommerce</a>.',
|
||||
'woo-gutenberg-products-block'
|
||||
),
|
||||
{
|
||||
a: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
||||
<a
|
||||
href={ getAdminLink(
|
||||
'admin.php?page=wc-settings&tab=advanced'
|
||||
) }
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>
|
||||
),
|
||||
}
|
||||
) }
|
||||
</Notice>
|
||||
) }
|
||||
<PanelBody
|
||||
title={ __( 'Form options', 'woo-gutenberg-products-block' ) }
|
||||
>
|
||||
<p className="wc-block-checkout__controls-text">
|
||||
{ __(
|
||||
'Choose whether your checkout form requires extra information from customers.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
>
|
||||
<p className="wc-block-checkout__controls-text">
|
||||
{ __(
|
||||
'Choose whether your checkout form requires extra information from customers.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</p>
|
||||
<ToggleControl
|
||||
</p>
|
||||
<ToggleControl
|
||||
label={ __( 'Company', 'woo-gutenberg-products-block' ) }
|
||||
checked={ showCompanyField }
|
||||
onChange={ () =>
|
||||
setAttributes( {
|
||||
showCompanyField: ! showCompanyField,
|
||||
} )
|
||||
}
|
||||
/>
|
||||
{ showCompanyField && (
|
||||
<CheckboxControl
|
||||
label={ __(
|
||||
'Company',
|
||||
'Require company name?',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ showCompanyField }
|
||||
checked={ requireCompanyField }
|
||||
onChange={ () =>
|
||||
setAttributes( {
|
||||
showCompanyField: ! showCompanyField,
|
||||
requireCompanyField: ! requireCompanyField,
|
||||
} )
|
||||
}
|
||||
className="components-base-control--nested"
|
||||
/>
|
||||
{ showCompanyField && (
|
||||
<CheckboxControl
|
||||
label={ __(
|
||||
'Require company name?',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ requireCompanyField }
|
||||
onChange={ () =>
|
||||
setAttributes( {
|
||||
requireCompanyField: ! requireCompanyField,
|
||||
} )
|
||||
}
|
||||
className="components-base-control--nested"
|
||||
/>
|
||||
) }
|
||||
<ToggleControl
|
||||
label={ __(
|
||||
'Apartment, suite, etc.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ showAddress2Field }
|
||||
onChange={ () =>
|
||||
setAttributes( {
|
||||
showAddress2Field: ! showAddress2Field,
|
||||
} )
|
||||
}
|
||||
/>
|
||||
<ToggleControl
|
||||
label={ __( 'Phone', 'woo-gutenberg-products-block' ) }
|
||||
checked={ showPhoneField }
|
||||
onChange={ () =>
|
||||
setAttributes( {
|
||||
showPhoneField: ! showPhoneField,
|
||||
} )
|
||||
}
|
||||
/>
|
||||
{ showPhoneField && (
|
||||
<CheckboxControl
|
||||
label={ __(
|
||||
'Require phone number?',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ requirePhoneField }
|
||||
onChange={ () =>
|
||||
setAttributes( {
|
||||
requirePhoneField: ! requirePhoneField,
|
||||
} )
|
||||
}
|
||||
className="components-base-control--nested"
|
||||
/>
|
||||
) }
|
||||
</PanelBody>
|
||||
<PanelBody
|
||||
title={ __(
|
||||
'Billing address',
|
||||
) }
|
||||
<ToggleControl
|
||||
label={ __(
|
||||
'Apartment, suite, etc.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
>
|
||||
<p className="wc-block-checkout__controls-text">
|
||||
{ __(
|
||||
'Reduce the number of fields required to checkout.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</p>
|
||||
<ToggleControl
|
||||
checked={ showAddress2Field }
|
||||
onChange={ () =>
|
||||
setAttributes( {
|
||||
showAddress2Field: ! showAddress2Field,
|
||||
} )
|
||||
}
|
||||
/>
|
||||
<ToggleControl
|
||||
label={ __( 'Phone', 'woo-gutenberg-products-block' ) }
|
||||
checked={ showPhoneField }
|
||||
onChange={ () =>
|
||||
setAttributes( {
|
||||
showPhoneField: ! showPhoneField,
|
||||
} )
|
||||
}
|
||||
/>
|
||||
{ showPhoneField && (
|
||||
<CheckboxControl
|
||||
label={ __(
|
||||
'Use the shipping address as the billing address',
|
||||
'Require phone number?',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ useShippingAsBilling }
|
||||
checked={ requirePhoneField }
|
||||
onChange={ () =>
|
||||
setAttributes( {
|
||||
useShippingAsBilling: ! useShippingAsBilling,
|
||||
requirePhoneField: ! requirePhoneField,
|
||||
} )
|
||||
}
|
||||
className="components-base-control--nested"
|
||||
/>
|
||||
</PanelBody>
|
||||
<PanelBody
|
||||
title={ __( 'Content', 'woo-gutenberg-products-block' ) }
|
||||
>
|
||||
<p className="wc-block-checkout__controls-text">
|
||||
{ __(
|
||||
'Choose additional content to display on checkout.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</p>
|
||||
<ToggleControl
|
||||
label={ __(
|
||||
'Show links to terms and conditions and privacy policy',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ showPolicyLinks }
|
||||
onChange={ () =>
|
||||
setAttributes( {
|
||||
showPolicyLinks: ! showPolicyLinks,
|
||||
} )
|
||||
}
|
||||
/>
|
||||
{ showPolicyLinks && ( ! PRIVACY_URL || ! TERMS_URL ) && (
|
||||
<Notice
|
||||
className="wc-block-base-control-notice"
|
||||
isDismissible={ false }
|
||||
>
|
||||
{ __experimentalCreateInterpolateElement(
|
||||
__(
|
||||
'Pages must be first setup in store settings: <a1>Privacy policy</a1>, <a2>Terms and conditions</a2>.',
|
||||
'woo-gutenberg-products-block'
|
||||
),
|
||||
{
|
||||
a1: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
||||
<a
|
||||
href={ getAdminLink(
|
||||
'admin.php?page=wc-settings&tab=account'
|
||||
) }
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>
|
||||
),
|
||||
a2: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
||||
<a
|
||||
href={ getAdminLink(
|
||||
'admin.php?page=wc-settings&tab=advanced'
|
||||
) }
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>
|
||||
),
|
||||
}
|
||||
) }
|
||||
</Notice>
|
||||
) }
|
||||
</PanelBody>
|
||||
</InspectorControls>
|
||||
<BlockErrorBoundary
|
||||
header={ __(
|
||||
'Checkout Block Error',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
text={ __(
|
||||
'There was an error whilst rendering the checkout block. If this problem continues, try re-creating the block.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
showErrorMessage={ true }
|
||||
errorMessagePrefix={ __(
|
||||
'Error message:',
|
||||
</PanelBody>
|
||||
<PanelBody
|
||||
title={ __(
|
||||
'Billing address',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
>
|
||||
<Block
|
||||
attributes={ attributes }
|
||||
cartItems={ previewCart.items }
|
||||
cartTotals={ previewCart.totals }
|
||||
isEditor={ true }
|
||||
shippingRates={
|
||||
SHIPPING_METHODS_EXIST ? previewShippingRates : []
|
||||
<p className="wc-block-checkout__controls-text">
|
||||
{ __(
|
||||
'Reduce the number of fields required to checkout.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</p>
|
||||
<ToggleControl
|
||||
label={ __(
|
||||
'Use the shipping address as the billing address',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ useShippingAsBilling }
|
||||
onChange={ () =>
|
||||
setAttributes( {
|
||||
useShippingAsBilling: ! useShippingAsBilling,
|
||||
} )
|
||||
}
|
||||
/>
|
||||
</BlockErrorBoundary>
|
||||
</div>
|
||||
</PanelBody>
|
||||
<PanelBody
|
||||
title={ __( 'Content', 'woo-gutenberg-products-block' ) }
|
||||
>
|
||||
<p className="wc-block-checkout__controls-text">
|
||||
{ __(
|
||||
'Choose additional content to display.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</p>
|
||||
<ToggleControl
|
||||
label={ __(
|
||||
'Show links to policies',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
help={ __(
|
||||
'Shows a list of links to your "terms and conditions" and "privacy policy" pages.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ showPolicyLinks }
|
||||
onChange={ () =>
|
||||
setAttributes( {
|
||||
showPolicyLinks: ! showPolicyLinks,
|
||||
} )
|
||||
}
|
||||
/>
|
||||
{ showPolicyLinks && ( ! PRIVACY_URL || ! TERMS_URL ) && (
|
||||
<Notice
|
||||
className="wc-block-base-control-notice"
|
||||
isDismissible={ false }
|
||||
>
|
||||
{ __experimentalCreateInterpolateElement(
|
||||
__(
|
||||
'Pages must be first setup in store settings: <a1>Privacy policy</a1>, <a2>Terms and conditions</a2>.',
|
||||
'woo-gutenberg-products-block'
|
||||
),
|
||||
{
|
||||
a1: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
||||
<a
|
||||
href={ getAdminLink(
|
||||
'admin.php?page=wc-settings&tab=account'
|
||||
) }
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>
|
||||
),
|
||||
a2: (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
||||
<a
|
||||
href={ getAdminLink(
|
||||
'admin.php?page=wc-settings&tab=advanced'
|
||||
) }
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>
|
||||
),
|
||||
}
|
||||
) }
|
||||
</Notice>
|
||||
) }
|
||||
<ToggleControl
|
||||
label={ __(
|
||||
'Show a "return to cart" link',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ showReturnToCart }
|
||||
onChange={ () =>
|
||||
setAttributes( {
|
||||
showReturnToCart: ! showReturnToCart,
|
||||
} )
|
||||
}
|
||||
/>
|
||||
{ showReturnToCart &&
|
||||
( currentPostId !== CHECKOUT_PAGE_ID || cartPageId ) &&
|
||||
pages && (
|
||||
<SelectControl
|
||||
label={ __(
|
||||
'Link to',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
value={ cartPageId }
|
||||
options={ [
|
||||
...[
|
||||
{
|
||||
label: __(
|
||||
'WooCommerce Cart Page',
|
||||
'woo-gutenberg-products-block'
|
||||
),
|
||||
value: '',
|
||||
},
|
||||
],
|
||||
...Object.values( pages ).map( ( page ) => {
|
||||
return {
|
||||
label: page.title.raw,
|
||||
value: parseInt( page.id, 10 ),
|
||||
};
|
||||
} ),
|
||||
] }
|
||||
onChange={ ( value ) =>
|
||||
setAttributes( {
|
||||
cartPageId: parseInt( value, 10 ),
|
||||
} )
|
||||
}
|
||||
/>
|
||||
) }
|
||||
</PanelBody>
|
||||
<FeedbackPrompt
|
||||
text={ __(
|
||||
'We are currently working on improving our cart and checkout blocks, providing merchants with the tools and customization options they need.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
/>
|
||||
</InspectorControls>
|
||||
);
|
||||
};
|
||||
|
||||
export default withFeedbackPrompt(
|
||||
__(
|
||||
'We are currently working on improving our cart and checkout blocks, providing merchants with the tools and customization options they need.',
|
||||
'woo-gutenberg-products-block'
|
||||
)
|
||||
)( CheckoutEditor );
|
||||
const CheckoutEditor = ( { attributes, setAttributes } ) => {
|
||||
const { className } = attributes;
|
||||
return (
|
||||
<EditorProvider>
|
||||
<div className={ className }>
|
||||
<BlockSettings
|
||||
attributes={ attributes }
|
||||
setAttributes={ setAttributes }
|
||||
/>
|
||||
<BlockErrorBoundary
|
||||
header={ __(
|
||||
'Checkout Block Error',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
text={ __(
|
||||
'There was an error whilst rendering the checkout block. If this problem continues, try re-creating the block.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
showErrorMessage={ true }
|
||||
errorMessagePrefix={ __(
|
||||
'Error message:',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
>
|
||||
<Block
|
||||
attributes={ attributes }
|
||||
cartItems={ previewCart.items }
|
||||
cartTotals={ previewCart.totals }
|
||||
isEditor={ true }
|
||||
shippingRates={
|
||||
SHIPPING_METHODS_EXIST ? previewShippingRates : []
|
||||
}
|
||||
/>
|
||||
</BlockErrorBoundary>
|
||||
</div>
|
||||
</EditorProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default CheckoutEditor;
|
||||
|
|
|
@ -13,3 +13,7 @@
|
|||
padding-left: 52px;
|
||||
margin-top: -12px;
|
||||
}
|
||||
|
||||
.wc-block-checkout__page-notice {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -70,13 +70,16 @@ const getProps = ( el ) => {
|
|||
|
||||
Object.keys( blockAttributes ).forEach( ( key ) => {
|
||||
if ( typeof el.dataset[ key ] !== 'undefined' ) {
|
||||
if (
|
||||
el.dataset[ key ] === 'true' ||
|
||||
el.dataset[ key ] === 'false'
|
||||
) {
|
||||
attributes[ key ] = el.dataset[ key ] !== 'false';
|
||||
} else {
|
||||
attributes[ key ] = el.dataset[ key ];
|
||||
switch ( blockAttributes[ key ].type ) {
|
||||
case 'boolean':
|
||||
attributes[ key ] = el.dataset[ key ] !== 'false';
|
||||
break;
|
||||
case 'number':
|
||||
attributes[ key ] = parseInt( el.dataset[ key ], 10 );
|
||||
break;
|
||||
default:
|
||||
attributes[ key ] = el.dataset[ key ];
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
attributes[ key ] = blockAttributes[ key ].default;
|
||||
|
|
|
@ -83,6 +83,22 @@
|
|||
}
|
||||
}
|
||||
|
||||
.wc-block-checkout__actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: $gap-large 0 $gap-large*2;
|
||||
padding: 0 $gap-larger;
|
||||
|
||||
.wc-block-components-checkout-place-order-button {
|
||||
width: 50%;
|
||||
padding: 1em;
|
||||
border-radius: 3px;
|
||||
height: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint( ">480px" ) {
|
||||
.wc-block-checkout__billing-fields,
|
||||
.wc-block-checkout__shipping-fields {
|
||||
|
|
|
@ -4,11 +4,7 @@
|
|||
import { Fragment } from '@wordpress/element';
|
||||
import { InspectorControls } from '@wordpress/block-editor';
|
||||
import { createHigherOrderComponent } from '@wordpress/compose';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import FeedbackPrompt from './feedback-prompt.js';
|
||||
import FeedbackPrompt from '@woocommerce/block-components/feedback-prompt';
|
||||
|
||||
/**
|
||||
* Adds a feedback prompt with custom text to the editor sidebar.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export { default as Icon } from './icon';
|
||||
|
||||
export { default as arrowBack } from './library/arrow-back';
|
||||
export { default as bill } from './library/bill';
|
||||
export { default as card } from './library/card';
|
||||
export { default as cart } from './library/cart';
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { SVG } from 'wordpress-components';
|
||||
|
||||
const arrowBack = (
|
||||
<SVG
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path d="M20 11H7.8l5.6-5.6L12 4l-8 8 8 8 1.4-1.4L7.8 13H20v-2z" />
|
||||
</SVG>
|
||||
);
|
||||
|
||||
export default arrowBack;
|
|
@ -55,18 +55,27 @@ export const SHIPPING_METHODS_EXIST = getSetting(
|
|||
);
|
||||
|
||||
const defaultPage = {
|
||||
name: '',
|
||||
url: '',
|
||||
id: 0,
|
||||
title: '',
|
||||
permalink: '',
|
||||
};
|
||||
const storePages = getSetting( 'storePages', {
|
||||
shop: defaultPage,
|
||||
cart: defaultPage,
|
||||
checkout: defaultPage,
|
||||
privacy: defaultPage,
|
||||
terms: defaultPage,
|
||||
} );
|
||||
export const SHOP_URL = storePages.shop.url;
|
||||
export const CHECKOUT_URL = storePages.checkout.url;
|
||||
export const PRIVACY_URL = storePages.privacy.url;
|
||||
export const TERMS_URL = storePages.terms.url;
|
||||
export const PRIVACY_PAGE_NAME = storePages.privacy.name;
|
||||
export const TERMS_PAGE_NAME = storePages.terms.name;
|
||||
export const SHOP_URL = storePages.shop.permalink;
|
||||
|
||||
export const CHECKOUT_PAGE_ID = storePages.checkout.id;
|
||||
export const CHECKOUT_URL = storePages.checkout.permalink;
|
||||
|
||||
export const PRIVACY_URL = storePages.privacy.permalink;
|
||||
export const PRIVACY_PAGE_NAME = storePages.privacy.title;
|
||||
|
||||
export const TERMS_URL = storePages.terms.permalink;
|
||||
export const TERMS_PAGE_NAME = storePages.terms.title;
|
||||
|
||||
export const CART_PAGE_ID = storePages.cart.id;
|
||||
export const CART_URL = storePages.cart.permalink;
|
||||
|
|
|
@ -103,6 +103,7 @@ class Assets {
|
|||
$product_counts = wp_count_posts( 'product' );
|
||||
$page_ids = [
|
||||
'shop' => wc_get_page_id( 'shop' ),
|
||||
'cart' => wc_get_page_id( 'cart' ),
|
||||
'checkout' => wc_get_page_id( 'checkout' ),
|
||||
'privacy' => wc_privacy_policy_page_id(),
|
||||
'terms' => wc_terms_and_conditions_page_id(),
|
||||
|
@ -142,27 +143,40 @@ class Assets {
|
|||
],
|
||||
'homeUrl' => esc_url( home_url( '/' ) ),
|
||||
'storePages' => [
|
||||
'shop' => $page_ids['shop'] ? [
|
||||
'name' => get_the_title( $page_ids['shop'] ),
|
||||
'url' => get_permalink( $page_ids['shop'] ),
|
||||
] : false,
|
||||
'checkout' => $page_ids['checkout'] ? [
|
||||
'name' => get_the_title( $page_ids['checkout'] ),
|
||||
'url' => get_permalink( $page_ids['checkout'] ),
|
||||
] : false,
|
||||
'privacy' => $page_ids['privacy'] ? [
|
||||
'name' => get_the_title( $page_ids['privacy'] ),
|
||||
'url' => get_permalink( $page_ids['privacy'] ),
|
||||
] : false,
|
||||
'terms' => $page_ids['terms'] ? [
|
||||
'name' => get_the_title( $page_ids['terms'] ),
|
||||
'url' => get_permalink( $page_ids['terms'] ),
|
||||
] : false,
|
||||
'shop' => self::format_page_resource( $page_ids['shop'] ),
|
||||
'cart' => self::format_page_resource( $page_ids['cart'] ),
|
||||
'checkout' => self::format_page_resource( $page_ids['checkout'] ),
|
||||
'privacy' => self::format_page_resource( $page_ids['privacy'] ),
|
||||
'terms' => self::format_page_resource( $page_ids['terms'] ),
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a page object into a standard array of data.
|
||||
*
|
||||
* @param WP_Post|int $page Page object or ID.
|
||||
* @return array
|
||||
*/
|
||||
protected static function format_page_resource( $page ) {
|
||||
if ( is_numeric( $page ) ) {
|
||||
$page = get_post( $page );
|
||||
}
|
||||
if ( ! $page ) {
|
||||
return [
|
||||
'id' => 0,
|
||||
'title' => '',
|
||||
'permalink' => false,
|
||||
];
|
||||
}
|
||||
return [
|
||||
'id' => $page->ID,
|
||||
'title' => $page->post_title,
|
||||
'permalink' => get_permalink( $page->ID ),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file modified time as a cache buster if we're in dev mode.
|
||||
*
|
||||
|
|
|
@ -50,6 +50,12 @@ class Checkout extends AbstractBlock {
|
|||
$data_registry = Package::container()->get(
|
||||
\Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry::class
|
||||
);
|
||||
if ( ! empty( $attributes['cartPageId'] ) && ! $data_registry->exists( 'page-' . $attributes['cartPageId'] ) ) {
|
||||
$permalink = get_permalink( $attributes['cartPageId'] );
|
||||
if ( $permalink ) {
|
||||
$data_registry->add( 'page-' . $attributes['cartPageId'], get_permalink( $attributes['cartPageId'] ) );
|
||||
}
|
||||
}
|
||||
if ( ! $data_registry->exists( 'allowedCountries' ) ) {
|
||||
$data_registry->add( 'allowedCountries', WC()->countries->get_allowed_countries() );
|
||||
}
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
exports[`Checkout Block can be created 1`] = `
|
||||
"<!-- wp:woocommerce/checkout -->
|
||||
<div class=\\"wp-block-woocommerce-checkout\\" data-use-shipping-as-billing=\\"true\\" data-show-company-field=\\"false\\" data-require-company-field=\\"false\\" data-show-address-2-field=\\"true\\" data-show-phone-field=\\"true\\" data-require-phone-field=\\"false\\" data-show-policy-links=\\"true\\">Checkout block coming soon to store near you</div>
|
||||
<div class=\\"wp-block-woocommerce-checkout\\" data-use-shipping-as-billing=\\"true\\" data-show-company-field=\\"false\\" data-require-company-field=\\"false\\" data-show-address-2-field=\\"true\\" data-show-phone-field=\\"true\\" data-require-phone-field=\\"false\\" data-show-policy-links=\\"true\\" data-show-return-to-cart=\\"true\\" data-cart-page-id=\\"0\\">Checkout block coming soon to store near you</div>
|
||||
<!-- /wp:woocommerce/checkout -->"
|
||||
`;
|
||||
|
|
Loading…
Reference in New Issue