UNPKG

@ecomplus/storefront-app

Version:

Vue.js ecommerce app with cart, checkout and account pages

141 lines (133 loc) 3.72 kB
import ecomPassport from '@ecomplus/passport-client' import ecomClient from '@ecomplus/client' import ecomCart from '@ecomplus/shopping-cart' import router from '../router/' let resolveCartId const fetchingCartId = new Promise(resolve => (resolveCartId = resolve)) const fetchCart = _id => ecomClient.store({ url: `/carts/${_id || ecomCart.data._id}.json` }).then(({ data }) => { const isCartOwner = Array.isArray(data.customers) && data.customers.includes(ecomPassport.getCustomer()._id) for (const field in data) { if (data[field] && field !== 'items' && field !== 'subtotal') { switch (field) { case 'items': case 'subtotal': continue case '_id': case 'customers': case 'created_at': case 'updated_at': if (!isCartOwner) { continue } } ecomCart.data[field] = data[field] } } data.items.forEach(item => { const currentItem = ecomCart.data.items.find(({ _id, sku }) => { return (item.sku && sku === item.sku) || _id === item._id }) if (!currentItem) { ecomCart.addItem(item) } else if (currentItem.quantity < item.quantity) { ecomCart.increaseItemQnt(item._id, item.quantity - currentItem.quantity) } }) resolveCartId(data._id) return data }) const prepareCartItem = item => { const fixedItem = {} ;[ '_id', 'product_id', 'variation_id', 'sku', 'name', 'picture', 'customizations', 'kit_product', 'gift_wrap', 'quantity', 'min_quantity', 'max_quantity', 'currency_id', 'currency_symbol', 'price', 'final_price', 'flags' ].forEach(itemField => { if (item[itemField] !== undefined) { fixedItem[itemField] = item[itemField] } }) if (fixedItem.picture) { delete fixedItem.picture._id } return fixedItem } const prepareCart = cart => { const { subtotal, completed, orders, flags } = cart const customerId = ecomPassport.getCustomer()._id let url, method if (cart.created_at && Array.isArray(cart.customers) && cart.customers.includes(customerId)) { url = `/carts/${cart._id}.json` method = 'PATCH' } else { url = '/carts.json' method = 'POST' if (router.currentRoute.name === 'confirmation' && !completed) { return {} } } return { url, method, cleanedData: { subtotal, completed, orders, flags: flags ? flags.slice(0, 10) : [], items: cart.items.map(item => prepareCartItem(item)) } } } let queueTimer const queueUpdateCart = tryRequestApi => new Promise(resolve => { if (!queueTimer) { queueTimer = setTimeout(() => { queueTimer = null tryRequestApi() .then(() => resolveCartId(ecomCart.data._id)) .finally(resolve) }, 3000) } }) const upsertCart = () => { if (ecomPassport.checkAuthorization() && ecomCart.data.items.length) { const { url, method, cleanedData } = prepareCart(ecomCart.data) if (!cleanedData) { return Promise.resolve(null) } const tryRequestApi = () => { return ecomPassport.requestApi(url, method, cleanedData) .catch(console.error) } return method === 'POST' ? tryRequestApi().then(({ data }) => { fetchCart(data._id) setTimeout(() => { ecomPassport.requestApi(`/carts/${data._id}.json`, 'PATCH', { permalink: `https://${window.location.host}${window.location.pathname}#/cart/${data._id}` }).catch(console.error) }, 300) }) : queueUpdateCart(tryRequestApi) } else { return Promise.resolve() } } export { fetchCart, fetchingCartId, upsertCart }