@open-tender/utils
Version:
A library of utils for use with Open Tender applications that utilize our cloud-based Order API.
148 lines (147 loc) • 6.21 kB
JavaScript
import { useEffect, useState } from 'react';
import { calcPrices } from '../utils';
export const useBuilder = (orderItem, orderTimeoutCallback) => {
const [item, setItem] = useState(orderItem);
useEffect(() => {
orderTimeoutCallback && orderTimeoutCallback();
}, [item, orderTimeoutCallback]);
const increment = () => {
const newQuantity = item.max
? Math.min(item.quantity + item.increment, item.max)
: item.quantity + item.increment;
const pricedItem = calcPrices(Object.assign(Object.assign({}, item), { quantity: newQuantity }));
setItem(pricedItem);
};
const decrement = () => {
const newQuantity = Math.max(item.quantity - item.increment, item.min);
const pricedItem = calcPrices(Object.assign(Object.assign({}, item), { quantity: newQuantity }));
setItem(pricedItem);
};
const setQuantity = (quantity) => {
const pricedItem = calcPrices(Object.assign(Object.assign({}, item), { quantity }));
setItem(pricedItem);
};
const setMadeFor = (madeFor) => {
setItem(Object.assign(Object.assign({}, item), { madeFor }));
};
const setNotes = (notes) => {
setItem(Object.assign(Object.assign({}, item), { notes }));
};
const setMadeForNotes = (madeFor, notes) => {
setItem(Object.assign(Object.assign({}, item), { madeFor, notes }));
};
const toggleGroupOption = (group, optionId) => {
const options = group.options.map(option => {
return Object.assign(Object.assign({}, option), { quantity: option.id === optionId ? 1 : 0 });
});
return Object.assign(Object.assign({}, group), { options });
};
const incrementGroupOption = (group, optionId) => {
const count = group.options
.filter(o => o.id !== optionId)
.reduce((t, o) => t + o.quantity, 0);
if (group.max !== 0 && count >= group.max)
return group;
const options = group.options.map(option => {
if (option.id === optionId) {
let quantity = option.quantity + option.increment;
const quantities = [quantity];
if (option.max !== 0)
quantities.push(option.max);
if (group.max !== 0)
quantities.push(group.max - count);
quantity = Math.min(...quantities);
return Object.assign(Object.assign({}, option), { quantity });
}
return option;
});
return Object.assign(Object.assign({}, group), { options });
};
const decrementGroupOption = (group, optionId) => {
const options = group.options.map(option => {
if (option.id === optionId) {
const quantity = Math.max(option.quantity - option.increment, 0);
return Object.assign(Object.assign({}, option), { quantity });
}
return option;
});
return Object.assign(Object.assign({}, group), { options });
};
const setGroupOptionQuantity = (group, optionId, quantity) => {
if (quantity === undefined)
return group;
const count = group.options
.filter(o => o.id !== optionId)
.reduce((t, o) => t + o.quantity, 0);
if (group.max !== 0 && count >= group.max)
return group;
const options = group.options.map(option => {
if (option.id === optionId) {
const quantities = quantity ? [quantity] : [0];
if (option.max !== 0)
quantities.push(option.max);
if (group.max !== 0)
quantities.push(group.max - count);
quantity = Math.min(...quantities);
quantity = Math.max(quantity, option.min);
return Object.assign(Object.assign({}, option), { quantity });
}
return option;
});
return Object.assign(Object.assign({}, group), { options });
};
const updateGroups = (groups, levels, fn, quantity) => {
const [[groupId, optionId], ...rest] = levels;
return groups.map(group => {
if (group.id === groupId) {
if (!rest.length)
return fn(group, optionId, quantity);
const options = group.options.map(option => {
if (option.id === optionId) {
return Object.assign(Object.assign({}, option), { groups: updateGroups(option.groups, rest, fn) });
}
return option;
});
return Object.assign(Object.assign({}, group), { options });
}
return group;
});
};
const toggleOption = (levels) => {
const groups = updateGroups(item.groups, levels, toggleGroupOption);
const pricedItem = calcPrices(Object.assign(Object.assign({}, item), { groups: groups }));
setItem(pricedItem);
return pricedItem;
};
const incrementOption = (levels) => {
const groups = updateGroups(item.groups, levels, incrementGroupOption);
const pricedItem = calcPrices(Object.assign(Object.assign({}, item), { groups: groups }));
setItem(pricedItem);
return pricedItem;
};
const decrementOption = (levels) => {
const groups = updateGroups(item.groups, levels, decrementGroupOption);
const pricedItem = calcPrices(Object.assign(Object.assign({}, item), { groups: groups }));
setItem(pricedItem);
return pricedItem;
};
const setOptionQuantity = (levels, quantity) => {
const groups = updateGroups(item.groups, levels, setGroupOptionQuantity, quantity);
const pricedItem = calcPrices(Object.assign(Object.assign({}, item), { groups: groups }));
setItem(pricedItem);
return pricedItem;
};
return {
item,
increment,
decrement,
setQuantity,
setMadeFor,
setNotes,
setMadeForNotes,
toggleOption,
incrementOption,
decrementOption,
setOptionQuantity
};
};