141 lines
3.1 KiB
JavaScript
141 lines
3.1 KiB
JavaScript
/**
|
|
* External dependencies
|
|
*/
|
|
import { camelCase, mapKeys } from 'lodash';
|
|
|
|
/**
|
|
* Internal dependencies
|
|
*/
|
|
import { ACTION_TYPES as types } from './action-types';
|
|
import { defaultCartState } from '../default-states';
|
|
|
|
/**
|
|
* 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;
|
|
} );
|
|
}
|
|
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 = defaultCartState, 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_PENDING_QUANTITY:
|
|
// Remove key by default - handles isQuantityPending==false
|
|
// and prevents duplicates when isQuantityPending===true.
|
|
const keysPendingQuantity = state.cartItemsPendingQuantity.filter(
|
|
( key ) => key !== action.cartItemKey
|
|
);
|
|
if ( action.isPendingQuantity ) {
|
|
keysPendingQuantity.push( action.cartItemKey );
|
|
}
|
|
state = {
|
|
...state,
|
|
cartItemsPendingQuantity: keysPendingQuantity,
|
|
};
|
|
break;
|
|
case types.RECEIVE_REMOVED_ITEM:
|
|
const keysPendingDelete = state.cartItemsPendingDelete.filter(
|
|
( key ) => key !== action.cartItemKey
|
|
);
|
|
if ( action.isPendingDelete ) {
|
|
keysPendingDelete.push( action.cartItemKey );
|
|
}
|
|
state = {
|
|
...state,
|
|
cartItemsPendingDelete: keysPendingDelete,
|
|
};
|
|
break;
|
|
// Delegate to cartItemsReducer.
|
|
case types.RECEIVE_CART_ITEM:
|
|
state = {
|
|
...state,
|
|
errors: [],
|
|
cartData: {
|
|
...state.cartData,
|
|
items: cartItemsReducer( state.cartData.items, action ),
|
|
},
|
|
};
|
|
break;
|
|
case types.UPDATING_SHIPPING_ADDRESS:
|
|
state = {
|
|
...state,
|
|
metaData: {
|
|
...state.metaData,
|
|
updatingShipping: action.isResolving,
|
|
},
|
|
};
|
|
break;
|
|
case types.UPDATING_SELECTED_SHIPPING_RATE:
|
|
state = {
|
|
...state,
|
|
metaData: {
|
|
...state.metaData,
|
|
updatingSelectedRate: action.isResolving,
|
|
},
|
|
};
|
|
}
|
|
return state;
|
|
};
|
|
|
|
export default reducer;
|