172 lines
3.5 KiB
JavaScript
172 lines
3.5 KiB
JavaScript
/**
|
|
* External dependencies
|
|
*/
|
|
import { camelCase, mapKeys } from 'lodash';
|
|
|
|
/**
|
|
* Internal dependencies
|
|
*/
|
|
import { ACTION_TYPES as types } from './action-types';
|
|
|
|
/**
|
|
* Sub-reducer for cart items array.
|
|
*
|
|
* @param {Array} state cartData.items state slice.
|
|
* @param {Object} action Action object.
|
|
*/
|
|
const cartItemsReducer = ( state = [], action ) => {
|
|
switch ( action.type ) {
|
|
case types.RECEIVE_CART_ITEM:
|
|
// Replace specified cart element with the new data from server.
|
|
return state.map( ( cartItem ) => {
|
|
if ( cartItem.key === action.cartItem.key ) {
|
|
return action.cartItem;
|
|
}
|
|
return cartItem;
|
|
} );
|
|
|
|
case types.RECEIVE_REMOVED_ITEM:
|
|
return state.filter( ( cartItem ) => {
|
|
return cartItem.key !== action.cartItemKey;
|
|
} );
|
|
}
|
|
return state;
|
|
};
|
|
|
|
/**
|
|
* Reducer for receiving items related to the cart.
|
|
*
|
|
* @param {Object} state The current state in the store.
|
|
* @param {Object} action Action object.
|
|
*
|
|
* @return {Object} New or existing state.
|
|
*/
|
|
const reducer = (
|
|
state = {
|
|
cartItemsQuantityPending: [],
|
|
cartData: {
|
|
coupons: [],
|
|
shippingRates: [],
|
|
shippingAddress: {
|
|
first_name: '',
|
|
last_name: '',
|
|
company: '',
|
|
address_1: '',
|
|
address_2: '',
|
|
city: '',
|
|
state: '',
|
|
postcode: '',
|
|
country: '',
|
|
},
|
|
items: [],
|
|
itemsCount: 0,
|
|
itemsWeight: 0,
|
|
needsShipping: true,
|
|
totals: {
|
|
currency_code: '',
|
|
currency_symbol: '',
|
|
currency_minor_unit: 2,
|
|
currency_decimal_separator: '.',
|
|
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',
|
|
tax_lines: [],
|
|
},
|
|
},
|
|
metaData: {},
|
|
errors: [],
|
|
},
|
|
action
|
|
) => {
|
|
switch ( action.type ) {
|
|
case types.RECEIVE_ERROR:
|
|
state = {
|
|
...state,
|
|
errors: state.errors.concat( action.error ),
|
|
};
|
|
break;
|
|
case types.REPLACE_ERRORS:
|
|
state = {
|
|
...state,
|
|
errors: [ action.error ],
|
|
};
|
|
break;
|
|
case types.RECEIVE_CART:
|
|
state = {
|
|
...state,
|
|
errors: [],
|
|
cartData: mapKeys( action.response, ( _, key ) =>
|
|
camelCase( key )
|
|
),
|
|
};
|
|
break;
|
|
case types.APPLYING_COUPON:
|
|
state = {
|
|
...state,
|
|
metaData: {
|
|
...state.metaData,
|
|
applyingCoupon: action.couponCode,
|
|
},
|
|
};
|
|
break;
|
|
case types.REMOVING_COUPON:
|
|
state = {
|
|
...state,
|
|
metaData: {
|
|
...state.metaData,
|
|
removingCoupon: action.couponCode,
|
|
},
|
|
};
|
|
break;
|
|
|
|
case types.ITEM_QUANTITY_PENDING:
|
|
// Remove key by default - handles isQuantityPending==false
|
|
// and prevents duplicates when isQuantityPending===true.
|
|
const newPendingKeys = state.cartItemsQuantityPending.filter(
|
|
( key ) => key !== action.cartItemKey
|
|
);
|
|
if ( action.isQuantityPending ) {
|
|
newPendingKeys.push( action.cartItemKey );
|
|
}
|
|
state = {
|
|
...state,
|
|
cartItemsQuantityPending: newPendingKeys,
|
|
};
|
|
break;
|
|
|
|
// Delegate to cartItemsReducer.
|
|
case types.RECEIVE_CART_ITEM:
|
|
case types.RECEIVE_REMOVED_ITEM:
|
|
state = {
|
|
...state,
|
|
cartData: {
|
|
...state.cartData,
|
|
items: cartItemsReducer( state.cartData.items, action ),
|
|
},
|
|
};
|
|
break;
|
|
case types.UPDATING_SHIPPING_ADDRESS:
|
|
state = {
|
|
...state,
|
|
metaData: {
|
|
...state.metaData,
|
|
updatingShipping: action.isResolving,
|
|
},
|
|
};
|
|
break;
|
|
}
|
|
return state;
|
|
};
|
|
|
|
export default reducer;
|