File: D:/HostingSpaces/SBogers95/rentman.io/resources/assets/js/components/singleProduct.vue
<template>
<div class="create-plan-product" :class="[isInShoppingCart ? 'create-plan-product__in-cart' : '', !this.$root.primaryProductSelected && product.requiresPrimary ? 'is-disabled' : '' ]" v-bind:data-icon="product.pricing_product_icon">
<div class="c-announcements__item" v-if="!this.$root.primaryProductSelected && product.requiresPrimary">
<div class="c-announcements__message c-announcements__message--pricing">
{{trans('available_with_equipment_scheduling_or_crew_scheduling')}}
</div>
</div>
<div class="c-announcements__item" v-else-if="!this.$root.equipmentSchedulingSelected && product.requiresEquipmentScheduling">
<div class="c-announcements__message c-announcements__message--pricing">
{{trans('available_with_equipment_scheduling')}}
</div>
</div>
<div class="c-announcements__item" v-else-if="!this.$root.equipmentSchedulingSelected && product.requiresEquipmentSchedulingPro">
<div class="c-announcements__message c-announcements__message--pricing">
{{trans('available_with_equipment_scheduling_pro')}}
</div>
</div>
<div class="create-plan-product__inner">
<div class="create-plan-product__icon"></div>
<div class="create-plan-product__meta">
<span v-if="!isAddon && !isLevels" class="create-plan-product__label">{{ trans('product') }}</span>
<span v-else class="create-plan-product__label">{{ trans('additional_product') }}</span>
<strong>{{ product.translation.name }}</strong>
<template v-if="product.levels.length === 0">
<p v-if="(price !== null)">{{ price }}
<span v-if="product.price_per_warehouse === 0">{{ trans('per_month') }}</span>
<span v-if="product.price_per_warehouse === 1">{{ trans('power_user_warehouse_month') }}</span>
</p>
</template>
<p v-if="product.translation.description !== ''">{{ product.translation.description }}</p>
<ul v-if="product.specs && product.specs.length > 0" class="create-plan__checks">
<li v-for="spec in product.specs" v-if="spec.length > 0">{{spec[0]}}</li>
</ul>
<div @click="openPopup" v-if="showCta && product.translation.features && product.levels.length === 0" class="create-plan__read-more">{{ trans('read_more') }} <span></span></div>
</div>
<!-- Additional warehouse -->
<div class="create-plan-product__button create-plan-product__button--suite" :class="{ 'disabled' : !this.$root.equipmentSchedulingProSelected}" v-if="product.requiresEquipmentSchedulingPro">
<div class="create-plan-product__tooltip" v-if="[8].includes(product.id)">
{{trans('available_with_equipment_scheduling_pro')}}
</div>
<template v-if="isAddon">
<button type="button" value="add product" @click="toggleProduct" :class="{'hidden': isInShoppingCart}">
<div></div>
{{ isInShoppingCart ? trans('added') : trans('add') }}
</button>
<div class="create-plan-product__numbers" v-if="isInShoppingCart">
<button @click="incrementAmount">+</button>
<input type="number" min="0" :value="cartState.amount" @change="changeAmount">
<button @click="decrementAmount">-</button>
</div>
</template>
<template v-else>
<button type="button" value="add product" @click="toggleProduct" :class="{'active': isInShoppingCart}">
<div></div>
{{ isInShoppingCart ? trans('added') : trans('add') }}
</button>
</template>
</div>
<div v-else class="create-plan-product__button create-plan-product__button--suite" :class="{ 'disabled' : !this.$root.primaryProductSelected && product.requiresPrimary || parentProductIsSelected }">
<!-- Equipment Tracking -->
<div class="create-plan-product__tooltip" v-if="[3].includes(product.id)">
{{trans('available_with_equipment_scheduling')}}
</div>
<!-- Quoting & Invoicing -->
<div class="create-plan-product__tooltip" v-if="[5,9].includes(product.id)">
{{trans('available_with_equipment_scheduling_or_crew_scheduling')}}
</div>
<template v-if="isAddon">
<button type="button" value="add product" @click="toggleProduct" :class="{'hidden': isInShoppingCart}">
<div></div>
{{ isInShoppingCart ? trans('added') : trans('add') }}
</button>
<div class="create-plan-product__numbers" v-if="isInShoppingCart">
<button @click="incrementAmount">+</button>
<input type="number" min="0" :value="cartState.amount" @change="changeAmount">
<button @click="decrementAmount">-</button>
</div>
</template>
<template v-else>
<button type="button" value="add product" @click="toggleProduct" :class="{'active': isInShoppingCart}">
<div></div>
{{ isInShoppingCart ? trans('added') : trans('add') }}
</button>
</template>
</div>
</div>
<template v-if="product.levels.length > 0">
<div class="create-plan-product__levels">
<div v-for="(level, index) in product.levels" @click="setLevel(index)" class="create-plan-product__level" :class="{'selected': isInShoppingCart && cartState.level == index}">
<strong>{{level[0]}}</strong>
<span>{{ displayCorrectCurrency(level[1], level[2]) }} {{ trans('power_user') }} <br>
/ {{trans('month')}}
</span>
</div>
</div>
<div v-if="showCta" @click="openPopup" class="create-plan__read-more">{{ trans('compare') }} <span></span></div>
</template>
<product-pop-up :active="popupOpened" v-on:close="closePopup" :product="product"></product-pop-up>
</div>
</template>
<script>
import mixin from './../createPlan/mixins'
import ProductPopUp from "./productPopUp";
export default {
name: "singleProduct",
components: {ProductPopUp},
mixins: [mixin],
props: {
product: {
type: Object,
required: true,
},
},
data() {
return {
amount: 1,
popupOpened: false,
cartState: null
}
},
created() {
if(window.location.hash === '#' + this.slugify(this.product.translation.name)) this.popupOpened = true;
},
methods: {
updateCartState() {
this.cartState = this.$root.productsInCart.find((p) => p.id == this.product.id)
if(this.cartState === undefined) this.cartState = null;
},
toggleProduct () {
if(this.isInShoppingCart) this.removeProduct()
else this.addProduct()
},
addProduct (level = null) {
if(this.product.levels.length > 0 && level === null) level = 0
this.$root.productsInCart.push({id: this.product.id, level: level, amount: 1})
this.updateCartState()
},
removeProduct() {
this.$root.productsInCart = this.$root.productsInCart.filter(p => p.id != this.product.id)
if (this.product.hinted_products.length > 0) {
this.product.hinted_products.forEach((hintedProduct) => {
this.$root.productsInCart = this.$root.productsInCart.filter(p => p.id !== hintedProduct.id)
})
}
this.updateCartState()
},
setLevel(level) {
if(!this.isInShoppingCart) {
this.addProduct(level)
return
}
const cartProduct = this.$root.productsInCart.find(p => p.id == this.product.id)
cartProduct.level = level
this.updateCartState()
},
setAmount(amount) {
const cartProduct = this.$root.productsInCart.find(p => p.id == this.product.id)
cartProduct.amount = amount
this.updateCartState()
},
changeAmount (event) {
const amount = parseInt(event.target.value)
if (amount === 0) this.removeProduct()
else this.setAmount(amount)
},
incrementAmount() {
let amount = this.cartState.amount + 1
if (amount === 0) this.removeProduct()
else this.setAmount(amount)
},
decrementAmount() {
let amount = this.cartState.amount - 1
if (amount === 0) this.removeProduct()
else this.setAmount(amount)
},
openPopup() {
history.replaceState("", document.title, window.location.pathname + '#' + this.slugify(this.product.translation.name));
this.popupOpened = true
},
closePopup() {
history.replaceState("", document.title, window.location.pathname);
this.popupOpened = false
}
},
computed: {
productCart() {
this.$root.productsInCart.find((p) => p.id == this.product.id)
},
isAddon() {
return this.product.pricing_product_type === 'addon';
},
isLevels() {
return this.product.pricing_product_type === 'levels';
},
showCta() {
return this.product.show_cta === 1;
},
isInShoppingCart() {
return this.cartState !== null;
},
price() {
return this.displayCorrectCurrency(this.product.euro_price, this.product.dollar_price)
},
parentProductIsSelected() {
if (this.product.parentProduct !== undefined) {
if (this.$root.productsInCart.find((p) => p.id === this.product.parentProduct)) return false
return true
} else {
return false
}
// return this.product.hasParentProduct;
}
}
}
</script>