@ecomplus/storefront-components
Version:
Vue components for E-Com Plus Storefront
232 lines (208 loc) • 5.56 kB
JavaScript
import {
i19addToFavorites,
i19buy,
i19connectionErrorProductMsg,
i19outOfStock,
i19unavailable
} from '@ecomplus/i18n'
import {
i18n,
name as getName,
inStock as checkInStock,
onPromotion as checkOnPromotion,
price as getPrice
} from '@ecomplus/utils'
import Vue from 'vue'
import { store } from '@ecomplus/client'
import ecomCart from '@ecomplus/shopping-cart'
import ALink from '../ALink.vue'
import APicture from '../APicture.vue'
import APrices from '../APrices.vue'
import ecomPassport from '@ecomplus/passport-client'
import { toggleFavorite, checkFavorite } from './helpers/favorite-products'
const getExternalHtml = (varName, product) => {
if (typeof window === 'object') {
varName = `productCard${varName}Html`
const html = typeof window[varName] === 'function'
? window[varName](product)
: window[varName]
if (typeof html === 'string') {
return html
}
}
return undefined
}
export default {
name: 'ProductCard',
components: {
ALink,
APicture,
APrices
},
props: {
product: Object,
productId: String,
isSmall: Boolean,
headingTag: {
type: String,
default: 'h3'
},
buyText: String,
transitionClass: {
type: String,
default: 'animated fadeIn'
},
canAddToCart: {
type: Boolean,
default: true
},
ecomPassport: {
type: Object,
default () {
return ecomPassport
}
},
accountUrl: {
type: String,
default: '/app/#/account/'
},
isLoaded: Boolean,
installmentsOption: Object,
discountOption: Object
},
data () {
return {
body: {},
isLoading: false,
isWaitingBuy: false,
isHovered: false,
isFavorite: false,
error: ''
}
},
computed: {
i19addToFavorites: () => i18n(i19addToFavorites),
i19outOfStock: () => i18n(i19outOfStock),
i19unavailable: () => i18n(i19unavailable),
i19uponRequest: () => 'Sob consulta',
isWithoutPrice () {
return !getPrice(this.body)
},
ratingHtml () {
return getExternalHtml('Rating', this.body)
},
buyHtml () {
return getExternalHtml('Buy', this.body)
},
footerHtml () {
return getExternalHtml('Footer', this.body)
},
name () {
return getName(this.body)
},
strBuy () {
return this.buyText ||
(typeof window === 'object' && window.productCardBuyText) ||
i18n(i19buy)
},
isInStock () {
return checkInStock(this.body)
},
isActive () {
return this.body.available && this.body.visible && this.isInStock
},
isLogged () {
return ecomPassport.checkAuthorization()
},
discount () {
const { body } = this
return checkOnPromotion(body)
? Math.round(((body.base_price - getPrice(body)) * 100) / body.base_price)
: 0
}
},
methods: {
setBody (data) {
this.body = Object.assign({}, data)
delete this.body.body_html
delete this.body.body_text
delete this.body.inventory_records
delete this.body.price_change_records
this.isFavorite = checkFavorite(this.body._id, this.ecomPassport)
},
fetchItem () {
if (this.productId) {
this.isLoading = true
store({ url: `/products/${this.productId}.json` })
.then(({ data }) => {
this.$emit('update:product', data)
this.setBody(data)
this.$emit('update:is-loaded', true)
})
.catch(err => {
console.error(err)
if (!this.body.name || !this.body.slug || !this.body.pictures) {
this.error = i18n(i19connectionErrorProductMsg)
}
})
.finally(() => {
this.isLoading = false
})
}
},
toggleFavorite () {
if (this.isLogged) {
this.isFavorite = toggleFavorite(this.body._id, this.ecomPassport)
}
},
buy () {
const product = this.body
this.$emit('buy', { product })
if (this.canAddToCart) {
this.isWaitingBuy = true
store({ url: `/products/${product._id}.json` })
.then(({ data }) => {
const selectFields = ['variations', 'customizations', 'kit_composition']
for (let i = 0; i < selectFields.length; i++) {
const selectOptions = data[selectFields[i]]
if (selectOptions && selectOptions.length) {
return import('../ProductQuickview.vue')
.then(quickview => {
new Vue({
render: h => h(quickview.default, {
props: {
product: data
}
})
}).$mount(this.$refs.quickview)
})
}
}
const { quantity, price } = data
ecomCart.addProduct({ ...product, quantity, price })
})
.catch(err => {
console.error(err)
window.location = `/${product.slug}`
})
.finally(() => {
this.isWaitingBuy = false
})
}
}
},
created () {
if (this.product) {
this.setBody(this.product)
if (this.product.available === undefined) {
this.body.available = true
}
if (this.product.visible === undefined) {
this.body.visible = true
}
}
if (!this.isLoaded) {
this.fetchItem()
}
}
}