56 lines
1.3 KiB
TypeScript
56 lines
1.3 KiB
TypeScript
import {
|
|
addOrderLine,
|
|
calculateOrderItemCount,
|
|
calculateOrderTotal,
|
|
updateOrderLineQuantity,
|
|
} from '../shared/order-line';
|
|
import type { CartAction, CartState } from './entities';
|
|
|
|
/** Pure cart state machine — no React, no localStorage. */
|
|
export function cartReducer(state: CartState, action: CartAction): CartState {
|
|
switch (action.type) {
|
|
case 'ADD_ITEM':
|
|
return { ...state, items: addOrderLine(state.items, action.payload) };
|
|
|
|
case 'REMOVE_ITEM':
|
|
return {
|
|
...state,
|
|
items: state.items.filter((item) => item.id !== action.payload),
|
|
};
|
|
|
|
case 'UPDATE_QUANTITY':
|
|
return {
|
|
...state,
|
|
items: updateOrderLineQuantity(
|
|
state.items,
|
|
action.payload.id,
|
|
action.payload.quantity
|
|
),
|
|
};
|
|
|
|
case 'CLEAR_CART':
|
|
return { ...state, items: [] };
|
|
|
|
case 'RESTORE_ITEMS':
|
|
return { ...state, items: action.payload };
|
|
|
|
case 'TOGGLE_CART':
|
|
return { ...state, isOpen: !state.isOpen };
|
|
|
|
case 'OPEN_CART':
|
|
return { ...state, isOpen: true };
|
|
|
|
case 'CLOSE_CART':
|
|
return { ...state, isOpen: false };
|
|
|
|
default:
|
|
return state;
|
|
}
|
|
}
|
|
|
|
export function getCartTotals(items: CartState['items']) {
|
|
return {
|
|
totalItems: calculateOrderItemCount(items),
|
|
totalPrice: calculateOrderTotal(items),
|
|
};
|
|
} |