MSV FM

dot.antimicrobial@66.96.161.157: ~ $
Path : /hermes/bosweb/b1705/reserva.events/menu/src/js/modules/
File Upload :
Current < : /hermes/bosweb/b1705/reserva.events/menu/src/js/modules/cart.js

import 'bootstrap/js/dist/modal'
import { $body, $bodyOverlay, currency } from '../globals'
import CustomControl from './custom-control'
import ls from 'local-storage'

const JSON_CATEGORIES = './data/categories.json'
const JSON_MENU = './data/menu.json'
const JSON_DELIVERY = './data/delivery.json'

const Cart = {
  activeItem: null,
  activeItemAdditionsTotal: 0,
  activeCategory: null,
  activeAdditions: [],
  categories: null,
  menu: null,
  items: ls.get('cartItems') || [],
  deliveryPrice: 3.99,
  orderTotal: 0,
  init: function() {
    const _ = this

    _.getData()

    _.Panel.init()
    _.Modal.init()
  },
  getData() {
    const _ = this

    $.getJSON(JSON_CATEGORIES, data => {
      _.categories = data
    })

    $.getJSON(JSON_MENU, data => {
      _.menu = data
    })

    $.getJSON(JSON_DELIVERY, data => {
      _.deliveryPrice = data.price
    })
  },
  addActiveItemToCart() {
    const _ = this
    const item = {
      _ref: new Date().getTime(),
      ..._.activeItem
    }

    _.items.push(item)
    _.Panel.update()
    ls('cartItems', _.items)
  },
  updateActiveItemInCart() {
    const _ = this
    const index = _.items.findIndex(item => item._ref === _.activeItem._ref)

    _.items[index] = _.activeItem
    _.Panel.update()
    ls('cartItems', _.items)
  },
  removeItem(payload) {
    const _ = this

    const index = _.items.findIndex(item => item._ref === payload.ref)
    _.items.splice(index, 1)
    _.Panel.update()
    ls('cartItems', _.items)
  },
  setActiveAdditions($item, payload) {
    const _ = this

    if ($item.is(':checked')) {
      _.activeItemAdditionsTotal += payload.price
      _.activeAdditions.push(payload)
    } else {
      const index = _.activeAdditions.findIndex(o => o.id === payload.id)
      _.activeItemAdditionsTotal -= payload.price
      _.activeAdditions.splice(index, 1)
    }

    _.activeItem.additions = _.activeAdditions
    _.activeItem.totalPrice = _.activeItem.sizes.find(o => o.active === true).price + _.activeItemAdditionsTotal

    _.Modal.updatePrice()
  },
  setActiveSize($item, payload) {
    const _ = this

    const oldSize = _.activeItem.sizes.find(o => o.active === true)
    if (oldSize) oldSize.active = false
    const newSize = _.activeItem.sizes.find(o => o.id === payload.id)
    newSize.active = true
    _.activeItem.totalPrice = _.activeItem.totalPrice - oldSize.price + newSize.price

    console.log(_.activeItem.sizes, oldSize)

    _.Modal.updatePrice()
  },
  setActiveItem(id) {
    const _ = this

    if (_.Modal.mode === 'EDIT') {
      _.activeItem = _.items.find(o => o._ref === id)
    } else {
      _.activeItem = _.menu.find(o => o.id === id)
      _.activeItem.totalPrice = _.activeItem.price
    }
    _.activeCategory = _.categories.find(o => o.id === _.activeItem.categoryId)
  },
  Panel: {
    DOM: {
      $panel: $('#panel-cart'),
      $panelToggler: $('[data-toggle="panel-cart"]'),
      $headerNotification: $('.module-cart .notification'),
      $headerValue: $('.module-cart .value'),
      $details: $('.cart-details'),
      $table: $('.cart-details .cart-table'),
      $productsTotal: $('.cart-details .cart-products-total'),
      $delivery: $('.cart-details .cart-delivery'),
      $orderTotal: $('.cart-details .cart-total'),
      $empty: $('.cart-details .cart-empty'),
      $summary: $('.cart-details .cart-summary')
    },
    init() {
      const _ = this

      _.DOM.$panelToggler.on('click', function() {
        if (_.DOM.$panel.hasClass('show')) {
          _.hidePanel()
        } else {
          _.showPanel()
        }
        return false
      })

      if (_.DOM.$details.length) {
        this.update()
      }
    },
    update() {
      const _ = this

      let productsTotal = 0
      const countItems = Cart.items.length

      _.DOM.$table.html('')

      Cart.items.forEach(item => {
        productsTotal += item.totalPrice
        const size = item.sizes.find(o => o.active)
        const $item = $(`
          <tr>
              <td class="title">
                  <span class="name"><a href="#product-modal" data-toggle="modal">${item.name}</a></span>
                  <span class="caption text-muted">${size.name} (${size.value})</span>
              </td>
              <td class="price">${currency}${item.totalPrice.toFixed(2)}</td>
              <td class="actions">
                  <button data-toggle="modal" class="action-icon" data-action="open-cart-modal" data-id="${item._ref}" data-edit="true"><i class="ti ti-pencil"></i></button>
                  <button class="action-icon" data-action="remove-from-cart"><i class="ti ti-close"></i></button>
              </td>
          </tr>
        `)
        $item.find('[data-action="remove-from-cart"]').on('click', function() {
          Cart.removeItem(item)
          $item.remove()
        })
        $item.appendTo(_.DOM.$table)
      })

      _.DOM.$productsTotal.text(productsTotal.toFixed(2))
      _.DOM.$delivery.text(Cart.deliveryPrice.toFixed(2))
      _.DOM.$orderTotal.text((Cart.deliveryPrice + productsTotal).toFixed(2))
      if (countItems === 0) {
        _.DOM.$headerNotification.hide()
        _.DOM.$empty.show()
        _.DOM.$summary.hide()
        _.DOM.$table.hide()
      } else {
        _.DOM.$headerNotification.show()
        _.DOM.$headerNotification.text(countItems)
        _.DOM.$empty.hide()
        _.DOM.$summary.show()
        _.DOM.$table.show()
      }

      _.DOM.$headerValue.text(productsTotal.toFixed(2))
    },
    showPanel() {
      const _ = this

      _.DOM.$panel.addClass('show')
      $bodyOverlay.fadeIn(400)
    },
    hidePanel() {
      const _ = this

      _.DOM.$panel.removeClass('show')
      $bodyOverlay.fadeOut(400)
    },
    handleClick(e) {
      const _ = this

      if (_.DOM.$panel.length && e.target.id == 'body-overlay') {
        _.hidePanel()
      }
    }
  },
  Modal: {
    DOM: {
      $modal: $('#product-modal'),
      $modalToggler: $('[data-action="open-cart-modal"]'),
      $addToCart: $('[data-action="add-to-cart"]'),
      $updateCart: $('[data-action="update-cart"]'),
      $details: $('#product-modal .panel-details'),
      $name: $('#product-modal .product-modal-name'),
      $ingredients: $('#product-modal .product-modal-ingredients'),
      $price: $('#product-modal .product-modal-price'),
      $sizes: $('#product-modal .panel-details-size'),
      $sizesList: $('#product-modal .product-modal-sizes'),
      $additions: $('#product-modal .panel-details-additions'),
      $additionsList: $('#product-modal .product-modal-additions')
    },
    mode: 'ADD',
    init() {
      const _ = this

      $body.on('click', '[data-action="open-cart-modal"]', function() {
        if ($(this).data('edit')) {
          _.mode = 'EDIT'
        } else {
          _.mode = 'ADD'
        }
        _.showProductModal($(this).data('id'))
      })

      _.DOM.$addToCart.on('click', function() {
        Cart.addActiveItemToCart()
        _.hideProductModal()
      })

      _.DOM.$updateCart.on('click', function() {
        Cart.updateActiveItemInCart()
        _.hideProductModal()
      })

      _.DOM.$modal.on('show.bs.modal', function() {
        if (_.mode === 'EDIT') {
          _.DOM.$addToCart.hide()
          _.DOM.$updateCart.show()
        } else {
          _.DOM.$addToCart.show()
          _.DOM.$updateCart.hide()
        }
        _.build()
      })

      _.DOM.$modal.on('hidden.bs.modal', function() {
        _.reset()
      })

      _.reset()
    },
    build() {
      const _ = this

      try {
        // Header
        _.DOM.$name.text(Cart.activeItem.name)
        _.DOM.$ingredients.text(Cart.activeItem.ingredients.join(', '))
        _.DOM.$price.text(Cart.activeItem.totalPrice.toFixed(2))

        // Sizes
        if (Cart.activeItem.sizes && Cart.activeItem.sizes.length > 1) {
          _.DOM.$sizesList.html('')
          Cart.activeItem.sizes.forEach(item => {
            const $item = $(`
            <div class="form-group">
                <label class="custom-control custom-radio">
                    <input name="radio_size" value="${item.id}" type="radio" class="custom-control-input" ${item.active ? 'checked' : ''}>
                    <span class="custom-control-indicator"></span>
                    <span class="custom-control-description">${item.name} - ${item.value} <span>(${currency}${item.price.toFixed(2)})</span></span>
                </label>
            </div>
          `)
            $item.find('input').on('change', function() {
              Cart.setActiveSize($(this), item)
            })
            $item.appendTo(_.DOM.$sizesList)
          })
          _.DOM.$sizes.show()
          _.DOM.$sizes.find('.collapse').addClass('show')
        } else {
          _.DOM.$sizes.hide()
        }

        // Additions
        if (Cart.activeCategory.additions && Cart.activeCategory.additions.length > 1) {
          _.DOM.$additionsList.html('')
          Cart.activeCategory.additions.forEach(item => {
            const $item = $(`
            <div class="col-sm-6">
                <div class="form-group">
                    <label class="custom-control custom-checkbox">
                        <input type="checkbox" value="${item.id}" class="custom-control-input" ${Cart.activeItem.additions && Cart.activeItem.additions.findIndex(o => o.id === item.id) !== -1 ? 'checked' : ''}>
                        <span class="custom-control-indicator"></span>
                        <span class="custom-control-description">${item.name} <span>(${currency}${item.price.toFixed(2)})</span></span>
                    </label>
                </div>
            </div>
          `)
            $item.find('input').on('change', function() {
              Cart.setActiveAdditions($(this), item)
            })
            $item.appendTo(_.DOM.$additionsList)
          })
          _.DOM.$additions.show()
          if (!Cart.activeItem.sizes || Cart.activeItem.sizes.length <= 1) {
            _.DOM.$additions.find('.collapse').addClass('show')
          }
        } else {
          _.DOM.$additions.hide()
        }

        CustomControl.init(_.$modal)
      } catch (error) {
        console.error('[CART_MODAL] Please check a JSON data source and data-id attribute on the button.')
      }
    },
    showProductModal(id) {
      const _ = this

      Cart.setActiveItem(id)
      _.DOM.$modal.modal('show')
    },
    hideProductModal() {
      const _ = this

      _.DOM.$modal.modal('hide')
    },
    updatePrice() {
      const _ = this

      _.DOM.$price.text(Cart.activeItem.totalPrice.toFixed(2))
    },
    reset() {
      const _ = this

      _.DOM.$details.each(function() {
        const $self = $(this)
        const $title = $self.find('.panel-details-title')
        const $content = $self.find('.panel-details-content').children()

        $self.find('.collapse').removeClass('show')
        $title.find('input').prop('checked', false)

        if (!$self.hasClass('panel-details-form')) {
          $content.html('')
        }
      })
    }
  }
}

export default Cart