Merge pull request #1436 from Safelite/feature/CSR-1384-modals-for-add-vaps
CSR-1384: adding modals with add to cart buttons
This commit is contained in:
commit
5998f13e9c
4 changed files with 181 additions and 20 deletions
|
|
@ -12,6 +12,7 @@
|
||||||
class="my-4 caption modal-sub-body"
|
class="my-4 caption modal-sub-body"
|
||||||
v-if="ModalSubBodyText"
|
v-if="ModalSubBodyText"
|
||||||
v-html="ModalSubBodyText"></p>
|
v-html="ModalSubBodyText"></p>
|
||||||
|
<slot></slot>
|
||||||
</modal>
|
</modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -22,6 +23,10 @@ export default {
|
||||||
name: "content-group-modal",
|
name: "content-group-modal",
|
||||||
props: {
|
props: {
|
||||||
cmsWidgetName: String,
|
cmsWidgetName: String,
|
||||||
|
footerButtonActionName: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
ModalName() {
|
ModalName() {
|
||||||
|
|
@ -50,10 +55,16 @@ export default {
|
||||||
openModal() {
|
openModal() {
|
||||||
this.$refs[this.ModalName].openModal();
|
this.$refs[this.ModalName].openModal();
|
||||||
},
|
},
|
||||||
|
closeModal() {
|
||||||
footerButtonClick() {
|
|
||||||
this.$refs[this.ModalName].closeModal();
|
this.$refs[this.ModalName].closeModal();
|
||||||
},
|
},
|
||||||
|
footerButtonClick() {
|
||||||
|
if (this.footerButtonActionName) {
|
||||||
|
this.$emit(this.footerButtonActionName, this.ModalName);
|
||||||
|
} else {
|
||||||
|
this.closeModal();
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
modal,
|
modal,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,164 @@
|
||||||
|
<template>
|
||||||
|
<transition name="fade" mode="out-in">
|
||||||
|
<div class="add-vaps-buttons" aria-live="polite">
|
||||||
|
<buttonQuestion
|
||||||
|
ref="buttonQuestion"
|
||||||
|
:answers="answersToDisplay"
|
||||||
|
groupName="addVaps"
|
||||||
|
v-model="answersToDisplay"
|
||||||
|
buttonTypeString="addVapsButton"
|
||||||
|
:buttonTypeObject="addVapsButton"
|
||||||
|
:isWide="answersToDisplay.length > 1 ? false : true"
|
||||||
|
@update:modelValue="openModal" />
|
||||||
|
|
||||||
|
<contentGroupModal
|
||||||
|
ref="RainDefenseModal"
|
||||||
|
cmsWidgetName="RainDefenseModal"
|
||||||
|
v-if="rainDefenseItem"
|
||||||
|
@footer-button-action="addToCart('RainDefenseModal', rainDefenseItem)"
|
||||||
|
footerButtonActionName="footer-button-action">
|
||||||
|
<p class="price">{{ rainDefenseItem.listPrice }}</p>
|
||||||
|
</contentGroupModal>
|
||||||
|
|
||||||
|
<contentGroupModal
|
||||||
|
ref="WipersModal"
|
||||||
|
cmsWidgetName="WipersModal"
|
||||||
|
v-if="wipersItem"
|
||||||
|
@footer-button-action="addToCart('WipersModal', wipersItem)"
|
||||||
|
footerButtonActionName="footer-button-action">
|
||||||
|
<p class="price">{{ wipersItem.listPrice }}</p>
|
||||||
|
</contentGroupModal>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import buttonQuestion from "@/digital-components/button-question/button-question";
|
||||||
|
import addVapsButton from "./add-vaps-button/add-vaps-button";
|
||||||
|
import contentGroupModal from "@/fmg-components/content-group-modal/content-group-modal";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "add-vaps-modal-buttons",
|
||||||
|
props: {
|
||||||
|
vapsTilesCmsName: String,
|
||||||
|
availableLineItems: Object,
|
||||||
|
modelValue: Object,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
addVapsButton: addVapsButton,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
openModal(modalName) {
|
||||||
|
this.$refs[modalName].openModal();
|
||||||
|
},
|
||||||
|
addToCart(modalName, part) {
|
||||||
|
const vapsItems = this.currentCartItems.vaps;
|
||||||
|
const alreadyInVaps = vapsItems.some((item) => {
|
||||||
|
return item.partType === part.partType;
|
||||||
|
});
|
||||||
|
if (!alreadyInVaps) {
|
||||||
|
if (part.subItems) {
|
||||||
|
// for wipers, a "combined" part (w/ subItems)
|
||||||
|
part.subItems.forEach((part) => {
|
||||||
|
this.currentCartItems.vaps.push(part);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// for rain defense, a "single" part (w/o subItems)
|
||||||
|
this.currentCartItems.vaps.push(part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.$refs[modalName].closeModal();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentCartItems() {
|
||||||
|
return this.modelValue;
|
||||||
|
},
|
||||||
|
showAddRainDefense() {
|
||||||
|
// show if not in cart
|
||||||
|
return !this.currentCartItems.vaps?.some((vap) => {
|
||||||
|
return vap?.partType === "RAIN DEFENSE";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
showAddWipers() {
|
||||||
|
// show if not in cart
|
||||||
|
if (this.currentCartItems && this.currentCartItems.vaps) {
|
||||||
|
return !this.currentCartItems.vaps.some((vap) => {
|
||||||
|
return vap?.partType?.includes(" WIPER");
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rainDefenseItem() {
|
||||||
|
const lineItem = this.availableLineItems.find((item) => {
|
||||||
|
return item.partType === "RAIN DEFENSE";
|
||||||
|
});
|
||||||
|
if (lineItem)
|
||||||
|
lineItem.listPrice = parseFloat(
|
||||||
|
lineItem?.laborAmount + lineItem?.sellingPrice + lineItem?.kitPrice
|
||||||
|
).toFixed(2);
|
||||||
|
return lineItem;
|
||||||
|
},
|
||||||
|
wipersItem() {
|
||||||
|
const wiperLineItems = this.availableLineItems.filter((item) => {
|
||||||
|
return item.partType.includes("WIPER");
|
||||||
|
});
|
||||||
|
let wiperLineItem;
|
||||||
|
if (wiperLineItems.length === 1) {
|
||||||
|
wiperLineItem = wiperLineItems[0];
|
||||||
|
wiperLineItem.listPrice = parseFloat(
|
||||||
|
wiperLineItem.laborAmount + wiperLineItem.sellingPrice + wiperLineItem.kitPrice
|
||||||
|
).toFixed(2);
|
||||||
|
return wiperLineItem;
|
||||||
|
} else if (wiperLineItems.length > 1) {
|
||||||
|
let combinedPrice = 0;
|
||||||
|
wiperLineItems?.forEach((item) => {
|
||||||
|
combinedPrice += item?.laborAmount + item?.sellingPrice + item?.kitPrice;
|
||||||
|
});
|
||||||
|
wiperLineItem = {
|
||||||
|
description: "COMBINED ITEM",
|
||||||
|
partType: "WIPERS",
|
||||||
|
subItems: [],
|
||||||
|
listPrice: parseFloat(combinedPrice).toFixed(2),
|
||||||
|
};
|
||||||
|
wiperLineItems?.forEach((item) => {
|
||||||
|
wiperLineItem.subItems.push(item);
|
||||||
|
});
|
||||||
|
return wiperLineItem;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
answersCmsData() {
|
||||||
|
return this.getCmsContent(this.vapsTilesCmsName, "Answers");
|
||||||
|
},
|
||||||
|
answersToDisplay() {
|
||||||
|
const answers = [];
|
||||||
|
if (!this.answersCmsData) return answers;
|
||||||
|
const getAnswer = (name, answers) => {
|
||||||
|
const answerIndex = answers.findIndex((answer) => {
|
||||||
|
return answer.Name === name;
|
||||||
|
});
|
||||||
|
return answers[answerIndex];
|
||||||
|
};
|
||||||
|
if (this.showAddWipers) {
|
||||||
|
const answer = getAnswer("WipersModal", this.answersCmsData);
|
||||||
|
answer.SubText = "+$" + this.wipersItem.listPrice;
|
||||||
|
answers.push(answer);
|
||||||
|
}
|
||||||
|
if (this.showAddRainDefense) {
|
||||||
|
const answer = getAnswer("RainDefenseModal", this.answersCmsData);
|
||||||
|
answer.SubText = "+$" + this.rainDefenseItem.listPrice;
|
||||||
|
answers.push(answer);
|
||||||
|
}
|
||||||
|
return answers;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
buttonQuestion,
|
||||||
|
contentGroupModal,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -42,12 +42,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<add-vaps-modal-buttons
|
<add-vaps-modal-buttons
|
||||||
:cartItems="cartItems"
|
v-model="lineItems"
|
||||||
:availableLineItems="availableLineItems"
|
:availableLineItems="availableLineItems"
|
||||||
vapsTilesCmsName="VapsProductTiles"
|
vapsTilesCmsName="VapsProductTiles" />
|
||||||
v-on="{ 'buttonEvent.openModal': openModal }" />
|
|
||||||
|
|
||||||
<contentGroupModal ref="RainDefenseModal" cmsWidgetName="RainDefenseModal" />
|
|
||||||
<paymentMethodQuestion
|
<paymentMethodQuestion
|
||||||
v-if="!isPiaDisabled"
|
v-if="!isPiaDisabled"
|
||||||
v-model="paymentMethodInternalModel"
|
v-model="paymentMethodInternalModel"
|
||||||
|
|
@ -74,11 +72,11 @@ import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-heade
|
||||||
import paymentMethodQuestion from "@/layouts/payment-method/payment-method-question/payment-method-question";
|
import paymentMethodQuestion from "@/layouts/payment-method/payment-method-question/payment-method-question";
|
||||||
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
|
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
|
||||||
import cart from "@/fmg-components/cart/cart";
|
import cart from "@/fmg-components/cart/cart";
|
||||||
import addVapsModalButtons from "@/fmg-components/add-vaps-modal-buttons/add-vaps-modal-buttons";
|
import addVapsModalButtons from "./add-vaps-modal-buttons/add-vaps-modal-buttons";
|
||||||
import contentGroupModal from "@/fmg-components/content-group-modal/content-group-modal";
|
|
||||||
import { submitWorkOrder } from "@/helpers/heritage-integration/order-helper.js";
|
import { submitWorkOrder } from "@/helpers/heritage-integration/order-helper.js";
|
||||||
import alert from "@/ux-components/alert/alert";
|
import alert from "@/ux-components/alert/alert";
|
||||||
|
|
||||||
|
// Supporting Items
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
import { storeActions } from "@/constants/store-actions";
|
import { storeActions } from "@/constants/store-actions";
|
||||||
|
|
@ -252,9 +250,6 @@ export default {
|
||||||
packageReqs && serviceLocationReqs && isInsuranceSet && scheduleReqs && customerReqs
|
packageReqs && serviceLocationReqs && isInsuranceSet && scheduleReqs && customerReqs
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
openModal(modalName) {
|
|
||||||
this.$refs[modalName].openModal();
|
|
||||||
},
|
|
||||||
getPiaAlert() {
|
getPiaAlert() {
|
||||||
return store.getters.order.payment.piaErrorCode ? true : false;
|
return store.getters.order.payment.piaErrorCode ? true : false;
|
||||||
},
|
},
|
||||||
|
|
@ -271,13 +266,6 @@ export default {
|
||||||
return paymentMethods.LATER;
|
return paymentMethods.LATER;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
vapsItemsSelectedAction(vapsItemsSelected) {
|
|
||||||
this.cartItems = vapsItemsSelected;
|
|
||||||
},
|
|
||||||
// TODO (as part of CSR-1384) enable adding to the cart
|
|
||||||
// vapsItemsSelectedAction(vapsItemsSelected) {
|
|
||||||
// this.cartItems = vapsItemsSelected;
|
|
||||||
// },
|
|
||||||
cartRemove(item) {
|
cartRemove(item) {
|
||||||
const matchedIndices = [];
|
const matchedIndices = [];
|
||||||
this.cartItems.forEach((cartItem, i) => {
|
this.cartItems.forEach((cartItem, i) => {
|
||||||
|
|
@ -320,7 +308,6 @@ export default {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async piaSetup(payNowType) {
|
async piaSetup(payNowType) {
|
||||||
this.$refs.loadingModal.showModal();
|
this.$refs.loadingModal.showModal();
|
||||||
|
|
||||||
|
|
@ -398,7 +385,6 @@ export default {
|
||||||
cart,
|
cart,
|
||||||
alert,
|
alert,
|
||||||
addVapsModalButtons,
|
addVapsModalButtons,
|
||||||
contentGroupModal,
|
|
||||||
paymentMethodQuestion,
|
paymentMethodQuestion,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue