Skip to content

Commit

Permalink
Merge pull request #267 from moderntribe/release/4.11.0
Browse files Browse the repository at this point in the history
packaged version 4.11.0
  • Loading branch information
becomevocal committed May 5, 2021
2 parents dd5249f + 06cb50d commit cf01abf
Show file tree
Hide file tree
Showing 51 changed files with 1,417 additions and 375 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## [4.11.0]

### Added
- Added support for a generic Segment tracking event on order completion via Embedded Checkout.
- Added Customizer option and cart functionality to process coupon/promo codes.

### Changed
- Optimized Brand and Category import. (Less time to import by skipping terms that did not change)

### Fixed
- Addressed issues with the Shipping Calculator not properly accommodating
Free and Ship by Weight/Total options.
- Fixed CLI importer warnings


## [4.10.0]

### Added
Expand Down Expand Up @@ -1382,6 +1397,7 @@
in fact, reset postdata, so far as Gutenberg 3.2.0 is concerned.


[4.11.0]: https://github.com/bigcommerce/bigcommerce-for-wordpress/compare/4.10.0...4.11.0
[4.10.0]: https://github.com/bigcommerce/bigcommerce-for-wordpress/compare/4.9.0...4.10.0
[4.9.0]: https://github.com/bigcommerce/bigcommerce-for-wordpress/compare/4.8.0...4.9.0
[4.8.0]: https://github.com/bigcommerce/bigcommerce-for-wordpress/compare/4.7.0...4.8.0
Expand Down
29 changes: 28 additions & 1 deletion assets/css/cart-amp.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/css/cart-amp.min.css

Large diffs are not rendered by default.

79 changes: 78 additions & 1 deletion assets/css/master.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/css/master.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/js/dist/admin/gutenberg/scripts.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/js/dist/admin/gutenberg/scripts.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/js/dist/admin/scripts.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/js/dist/admin/scripts.min.js

Large diffs are not rendered by default.

367 changes: 187 additions & 180 deletions assets/js/dist/scripts.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions assets/js/dist/scripts.min.js

Large diffs are not rendered by default.

231 changes: 116 additions & 115 deletions assets/js/dist/vendor.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions assets/js/dist/vendor.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions assets/js/src/constants/events.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// custom events
export const AJAX_CART_UPDATE = 'bigcommerce/ajax_cart_update';
export const HANDLE_CART_STATE = 'bigcommerce/handle_cart_state';
export const HANDLE_COUPON_CODE = 'bigcommerce/handle_coupon_code';
35 changes: 35 additions & 0 deletions assets/js/src/public/analytics/segment.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ const el = {
segment: tools.getNodes('bc-segment-tracker')[0],
};

/**
* @function handleAddToCartTracker
* @description Event handler for tracking products added to the cart.
* @param e
*/
const handleAddToCartTracker = (e) => {
const cartTrigger = e ? e.detail.cartButton : tools.getNodes('[data-tracking-event="add_to_cart_message"]', false, document, true)[0];

Expand All @@ -30,6 +35,11 @@ const handleAddToCartTracker = (e) => {
console.info(`Segment has sent the following cart tracking data to your analytics account(s): ${analyticsData}`);
};

/**
* @function handleClickTracker
* @description Event handler for clicking on products to view PDP or Quick View.
* @param e
*/
const handleClickTracker = (e) => {
const target = e.delegateTarget;
const analyticsData = target.dataset.trackingData;
Expand All @@ -46,6 +56,30 @@ const handleClickTracker = (e) => {
console.info(`Segment has sent the following tracking data to your analytics account(s): ${analyticsData}`);
};

/**
* @function handleOrderCompleteTracker
* @description Event handler for embedded checkout order completion.
* @param e
* TODO: This needs to be overhauled once BC can provide proper order data in the ECO response.
*/
const handleOrderCompleteTracker = (e) => {
if (!e.detail) {
return;
}

const cartID = e.detail.cart_id;
analytics.track('BigCommerce Order Completed', {
cart_id: cartID,
});

console.info(`Segment has sent the following tracking data to your analytics account(s): Order Completed. Cart ID: ${cartID}`);
};

/**
* @function gaCrossDomainInit
* @description Enable GA x-domain tracking by default.
* @return {Promise<void>}
*/
const gaCrossDomainInit = async () => {
await analytics.ready(() => {
ga('require', 'linker');
Expand All @@ -64,6 +98,7 @@ const bindEvents = () => {
});

on(document, 'bigcommerce/analytics_trigger', handleAddToCartTracker);
on(document, 'bigcommerce/order_complete', handleOrderCompleteTracker);
};

const init = () => {
Expand Down
10 changes: 7 additions & 3 deletions assets/js/src/public/cart/ajax-items.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { on, trigger } from 'utils/events';
import cartState from 'publicConfig/cart-state';
import { CART_API_BASE } from 'publicConfig/wp-settings';
import { CART_ID_COOKIE_NAME, CART_ITEM_COUNT_COOKIE } from 'bcConstants/cookies';
import { AJAX_CART_UPDATE, HANDLE_CART_STATE } from 'bcConstants/events';
import { AJAX_CART_UPDATE, HANDLE_CART_STATE, HANDLE_COUPON_CODE } from 'bcConstants/events';
import { NLS } from 'publicConfig/i18n';
import { cartEmpty } from './cart-templates';
import { updateMenuQtyTotal, updateCartMenuItem, updateFlatsomeCartMenuQty, updateFlatsomeCartMenuPrice } from './cart-menu-item';
Expand Down Expand Up @@ -132,10 +132,12 @@ const updateCartItems = (data = {}) => {
* @param data
*/
const updatedCartTotals = (data = {}) => {
const cartData = data.detail ? data.detail.data : data;

tools.getNodes('bc-cart', true).forEach((cart) => {
const baseAmount = data.subtotal.formatted;
const baseAmount = cartData.subtotal.formatted;
const subTotal = tools.getNodes('.bc-cart-subtotal__amount', false, cart, true)[0];
const taxAmount = data.tax_amount.formatted;
const taxAmount = cartData.tax_amount.formatted;
const taxTotal = tools.getNodes('.bc-cart-tax__amount', false, cart, true)[0];

subTotal.textContent = baseAmount;
Expand Down Expand Up @@ -316,6 +318,8 @@ const bindEvents = () => {
delegate(document, '[data-js="bc-cart-item__quantity"]', 'input', handleQtyUpdate);
delegate(document, '[data-js="remove-cart-item"]', 'click', handleCartItemRemoval);
on(document, HANDLE_CART_STATE, handleCartState);
on(document, HANDLE_COUPON_CODE, handleCartState);
on(document, HANDLE_COUPON_CODE, updatedCartTotals);
};

const init = () => {
Expand Down
187 changes: 187 additions & 0 deletions assets/js/src/public/cart/coupon-code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/**
* @module Coupon Codes
* @description Scripts to handle cart submission of coupon codes.
*/

import * as tools from 'utils/tools';
import delegate from 'delegate';
import { wpAPICouponCodes } from 'utils/ajax';
import { on, trigger } from 'utils/events';
import { COUPON_CODE_ADD, COUPON_CODE_REMOVE, AJAX_CART_NONCE } from 'publicConfig/wp-settings';
import { AJAX_CART_UPDATE, HANDLE_CART_STATE, HANDLE_COUPON_CODE } from 'bcConstants/events';
import { NLS } from 'publicConfig/i18n';
import cartState from 'publicConfig/cart-state';

const el = {
container: tools.getNodes('bc-coupon-code')[0],
};

/**
* @function updateCouponDiscount
* @description Update discount amount on qty update or removal. Remove coupon section on empty cart.
* @param e
*/
const updateCouponDiscount = (e) => {
if (!e.detail.cartData) {
el.container.parentNode.removeChild(el.container);
return;
}

el.couponDetails.innerText = `${NLS.cart.coupon_discount}: -${e.detail.cartData.coupons[0].discounted_amount.formatted}`;
};

/**
* @function handleCouponSuccess
* @description Update cart data when a coupon has been applied.
* @param cartObject
*/
const handleCouponSuccess = (cartObject = {}) => {
if (!cartObject) {
return;
}

const couponCode = cartObject.coupons[0].code;

el.container.classList.add('bc-hide-add-form');
el.container.classList.remove('bc-hide-remove-form');
el.addCouponForm.setAttribute('aria-hidden', true);
el.removeCouponForm.setAttribute('aria-hidden', false);
el.cartErrorWrapper.classList.remove('message-active');
el.cartError.innerText = NLS.cart.coupon_success;
el.removeCouponButton.dataset.couponCode = couponCode;
el.removeCouponTitle.innerText = couponCode;
el.couponField.value = '';
el.couponDetails.innerText = `${NLS.cart.coupon_discount}: -${cartObject.coupons[0].discounted_amount.formatted}`;
};

/**
* @function handleCouponRemoval
* @description Update cart data when a coupon has been removed.
*/
const handleCouponRemoval = () => {
el.container.classList.add('bc-hide-remove-form');
el.container.classList.remove('bc-hide-add-form');
el.addCouponForm.setAttribute('aria-hidden', false);
el.removeCouponForm.setAttribute('aria-hidden', true);
el.cartErrorWrapper.classList.remove('message-active');
el.cartError.innerText = NLS.cart.coupon_success;
el.removeCouponButton.dataset.couponCode = '';
el.removeCouponTitle.innerText = '';
el.couponDetails.innerText = '';
};

/**
* @function handleCouponAddError
* @description Handle coupon errors when adding.
*/
const handleCouponAddError = () => {
el.couponField.focus();
el.container.classList.add('bc-hide-remove-form');
el.container.classList.remove('bc-hide-add-form');
el.cartErrorWrapper.classList.add('message-active');
el.cartError.innerText = NLS.cart.coupon_error;
};

/**
* @function handleCouponRemoveError
* @description Handle coupon errors when removing.
*/
const handleCouponRemoveError = () => {
el.cartErrorWrapper.classList.remove('message-active');
el.cartError.innerText = NLS.cart.coupon_removal_error;
el.container.classList.add('bc-hide-remove-form');
el.container.classList.remove('bc-hide-add-form');
};

/**
* @function handleCouponCodeAdd
* @description Main coupon function to apply a coupon to the cart.
*/
const handleCouponCodeAdd = () => {
if (!COUPON_CODE_ADD) {
return;
}

const queryObject = {
coupon_code: el.couponField.value,
};

cartState.isFetching = true;
trigger({ event: HANDLE_CART_STATE, native: false });

wpAPICouponCodes(COUPON_CODE_ADD, queryObject, AJAX_CART_NONCE)
.end((err, res) => {
cartState.isFetching = false;
trigger({ event: HANDLE_CART_STATE, native: false });

if (err || res.body.error) {
console.error(err, res.body ? res.body.error : '');
handleCouponAddError();
return;
}

trigger({ event: HANDLE_COUPON_CODE, data: { data: res.body }, native: false });
handleCouponSuccess(res.body);
});
};

/**
* @function handleCouponCodeRemove
* @description Main coupon function to remove a coupon from the cart.
* @param e
*/
const handleCouponCodeRemove = (e) => {
if (!COUPON_CODE_REMOVE) {
return;
}

const queryObject = {
coupon_code: e.delegateTarget.dataset.couponCode,
};

cartState.isFetching = true;
trigger({ event: HANDLE_CART_STATE, native: false });

wpAPICouponCodes(COUPON_CODE_REMOVE, queryObject, AJAX_CART_NONCE)
.end((err, res) => {
cartState.isFetching = false;
trigger({ event: HANDLE_CART_STATE, native: false });

if (err || res.body.error) {
console.error(err, res.body ? res.body.error : '');
handleCouponRemoveError();
return;
}

handleCouponRemoval();
trigger({ event: HANDLE_COUPON_CODE, data: { data: res.body }, native: false });
});
};

const cacheElements = () => {
el.addCouponForm = tools.getNodes('bc-add-coupon-form', false, el.container)[0];
el.couponField = tools.getNodes('bc-coupon-code-field', false, el.container)[0];
el.removeCouponForm = tools.getNodes('bc-remove-coupon-form', false, el.container)[0];
el.removeCouponButton = tools.getNodes('bc-coupon-code-remove', false, el.container)[0];
el.removeCouponTitle = tools.getNodes('.bc-coupon-name', false, el.removeCouponButton, true)[0];
el.couponDetails = tools.getNodes('bc-coupon-details', false, el.container)[0];
el.cartErrorWrapper = tools.getNodes('.bc-cart-error', false, document, true)[0];
el.cartError = tools.getNodes('bc-cart-error-message', false, el.cartErrorWrapper)[0];
};

const bindEvents = () => {
delegate(el.container, '[data-js="bc-coupon-code-submit"]', 'click', handleCouponCodeAdd);
delegate(el.container, '[data-js="bc-coupon-code-remove"]', 'click', handleCouponCodeRemove);
on(document, AJAX_CART_UPDATE, updateCouponDiscount);
};

const init = () => {
if (!el.container) {
return;
}

cacheElements();
bindEvents();
};

export default init;
2 changes: 2 additions & 0 deletions assets/js/src/public/cart/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import addToCart from './add-to-cart';
import miniCartWidget from './mini-cart-widget';
import miniCartNav from './mini-cart-nav';
import shippingCalc from './shipping-calculator';
import couponCode from './coupon-code';

const init = () => {
cartItemsAjax();
Expand All @@ -19,6 +20,7 @@ const init = () => {
miniCartWidget();
miniCartNav();
shippingCalc();
couponCode();
};

export default init;
10 changes: 6 additions & 4 deletions assets/js/src/public/cart/shipping-calculator.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as tools from 'utils/tools';
import delegate from 'delegate';
import cartState from 'publicConfig/cart-state';
import { Spinner } from 'spin.js/spin';
import { AJAX_CART_UPDATE, HANDLE_CART_STATE } from 'bcConstants/events';
import { AJAX_CART_UPDATE, HANDLE_CART_STATE, HANDLE_COUPON_CODE } from 'bcConstants/events';
import { SHIPPING_API_ZONES, SHIPPING_API_METHODS } from 'publicConfig/wp-settings';
import { NLS } from 'publicConfig/i18n';
import { wpAPIGetShippingZones, wpAPIGetShippingMethods } from 'utils/ajax';
Expand Down Expand Up @@ -80,11 +80,12 @@ const resetShippingCalculator = (e) => {
handleShippingError();

// On a cart ajax refresh event
if (e.detail.cartData) {
const cartData = e.detail.cartData ? e.detail.cartData : e.detail.data;
if (cartData) {
// First set the subtotal to the cart state.
state.subtotal = e.detail.cartData.subtotal.formatted;
state.subtotal = cartData.subtotal.formatted;
// If the only remaining items in the card are digital goods, remove the shipping calculator all together.
setValidCartCount(e.detail.cartData);
setValidCartCount(cartData);
if (state.shippingItemCount === 0) {
el.calculator.parentNode.removeChild(el.calculator);
return;
Expand Down Expand Up @@ -260,6 +261,7 @@ const bindEvents = () => {
delegate(el.calculator, '[data-js="bc-shipping-zones"]', 'change', getMethods);
delegate(el.calculator, '[data-js="shipping-calculator-update"]', 'click', updateCartPrice);
on(document, AJAX_CART_UPDATE, resetShippingCalculator);
on(document, HANDLE_COUPON_CODE, resetShippingCalculator);
};

const init = () => {
Expand Down
10 changes: 8 additions & 2 deletions assets/js/src/public/checkout/embedded-checkout.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Cookie from 'js-cookie';
import _ from 'lodash';
import * as tools from 'utils/tools';
import scrollTo from 'utils/dom/scroll-to';
import { trigger } from 'utils/events';
import { CART_ID_COOKIE_NAME, CART_ITEM_COUNT_COOKIE } from 'bcConstants/cookies';
import { cartEmpty } from '../cart/cart-templates';

Expand Down Expand Up @@ -51,6 +52,12 @@ const scrollIframe = () => {
_.delay(() => scrollTo(options), 1000);
};

const handleOrderCompleteEvents = () => {
trigger({ event: 'bigcommerce/order_complete', data: { cart_id: Cookie.get(CART_ID_COOKIE_NAME) }, native: false });
clearCartData();
scrollIframe();
};

/**
* @function loadEmbeddedCheckout
* @description Create an instance of the BC embedded checkout.
Expand All @@ -67,8 +74,7 @@ const loadEmbeddedCheckout = async () => {
}

// Set the onComplete callback to use the clearCartData function.
config.onComplete = clearCartData;
config.onComplete = scrollIframe;
config.onComplete = handleOrderCompleteEvents;

// Embed the checkout.
checkoutCDN.embedCheckout(config);
Expand Down
Loading

0 comments on commit cf01abf

Please sign in to comment.