woocommerce/plugins/woocommerce-blocks/assets/js/base/context/cart-checkout/checkout/reducer.js

151 lines
2.9 KiB
JavaScript

/**
* External dependencies
*/
import isShallowEqual from '@wordpress/is-shallow-equal';
/**
* Internal dependencies
*/
import { TYPES, DEFAULT_STATE, STATUS } from './constants';
const {
SET_PRISTINE,
SET_PROCESSING,
SET_REDIRECT_URL,
SET_COMPLETE,
SET_HAS_ERROR,
SET_NO_ERROR,
INCREMENT_CALCULATING,
DECREMENT_CALCULATING,
SET_BILLING_DATA,
} = TYPES;
const { PRISTINE, IDLE, CALCULATING, PROCESSING, COMPLETE } = STATUS;
/**
* Reducer for the checkout state
*
* @param {Object} state Current state.
* @param {Object} action Incoming action object.
*/
export const reducer = ( state = DEFAULT_STATE, { url, type, data } ) => {
let status, nextStatus, newState;
switch ( type ) {
case SET_PRISTINE:
newState = DEFAULT_STATE;
break;
case SET_REDIRECT_URL:
newState =
url !== state.url
? {
...state,
redirectUrl: url,
}
: state;
break;
case SET_COMPLETE:
status = COMPLETE;
nextStatus = state.status;
if ( state.status === CALCULATING ) {
status = CALCULATING;
nextStatus = COMPLETE;
}
newState =
status !== state.status
? {
...state,
status,
nextStatus,
}
: state;
break;
case SET_PROCESSING:
status = PROCESSING;
nextStatus = state.status;
if ( state.status === CALCULATING ) {
status = CALCULATING;
nextStatus = PROCESSING;
}
newState =
status !== state.status
? {
...state,
status,
nextStatus,
hasError: false,
}
: state;
// clear any error state.
newState =
newState.hasError === false
? newState
: { ...newState, hasError: false };
break;
case SET_HAS_ERROR:
newState = state.hasError
? state
: {
...state,
hasError: true,
};
newState =
state.status === PROCESSING
? {
...newState,
status: IDLE,
}
: newState;
break;
case SET_NO_ERROR:
newState = state.hasError
? {
...state,
hasError: false,
}
: state;
break;
case INCREMENT_CALCULATING:
newState = {
...state,
status: CALCULATING,
nextStatus: state.status,
calculatingCount: state.calculatingCount + 1,
};
break;
case DECREMENT_CALCULATING:
status = CALCULATING;
nextStatus = state.status;
if ( state.calculatingCount <= 1 ) {
status = state.nextStatus;
nextStatus = IDLE;
}
newState = {
...state,
status,
nextStatus,
calculatingCount: Math.max( 0, state.calculatingCount - 1 ),
};
break;
case SET_BILLING_DATA:
newState = isShallowEqual( state.billingData, data )
? state
: {
...state,
billingData: {
...data,
},
};
break;
}
// automatically update state to idle from pristine as soon as it
// initially changes.
if (
newState !== state &&
type !== SET_PRISTINE &&
newState.status === PRISTINE
) {
newState.status = IDLE;
}
return newState;
};