DigitalConsumer.FixMyGlass/src/layouts/payment-method/add-vaps-modal-buttons/add-vaps-modal-buttons.vue
Scott Kiener fa2bccb518 CSR-1452 | More promo logic
Watch lineItems to automatically run revalidate when the cart changes
Add in auto add of addable vaps in beforeRouteEnter
Create adding of addableVaps to order in promo helper
2023-11-07 15:34:31 -05:00

427 lines
17 KiB
Vue

<template>
<transition name="fade" mode="out-in">
<div class="add-vaps-buttons" aria-live="polite">
<buttonQuestion
ref="buttonQuestion"
:answers="buttonsToDisplay"
groupName="addVaps"
v-model="buttonsToDisplay"
buttonTypeString="addVapsButton"
:buttonTypeObject="addVapsButton"
:isWide="buttonsToDisplay.length > 1 ? false : true"
@update:modelValue="openModal" />
<contentGroupModal
ref="RainDefenseModal"
cmsWidgetName="RainDefenseModal"
v-if="rainDefenseModal"
@footer-button-action="addRainDefenseToCart('RainDefenseModal', rainDefenseModal)"
footerButtonActionName="footer-button-action">
<p class="price">+${{ rainDefenseModal.listPrice }}</p>
</contentGroupModal>
<contentGroupModal
ref="WipersModal"
cmsWidgetName="WipersModal"
v-if="wipersModal"
@footer-button-action="addWipersToCart('WipersModal', wipersModal)"
footerButtonActionName="footer-button-action">
<div v-if="wipersOffered === wipersOfferedStrings.BOTH" class="wiper-options">
<buttonQuestion
ref="buttonQuestion"
buttonTypeString="checkbox"
class="mt-5"
:answers="wipersOptions"
groupName="wipers-options"
textPosition="text-center"
v-model="selectedWipers"
isMultiSelect
isRequired
validationRules="checkbox-required" />
</div>
<div v-else-if="wipersOffered === wipersOfferedStrings.FRONT" class="wiper-options">
<p class="price">+${{ wipersModal.totalFrontPrice }}</p>
</div>
<div v-else-if="wipersOffered === wipersOfferedStrings.REAR" class="wiper-options">
<p class="price">+${{ wipersModal.totalRearPrice }}</p>
</div>
</contentGroupModal>
</div>
</transition>
</template>
<script>
// COMPONENTS
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";
// SUPPORTING
import { partTypeStrings } from "@/constants/part-type-strings";
import { defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
import { processIfStatements } from "@/helpers/cms-content-helper";
// DEFINE VALIDATION RULES
defineRule("checkbox-required", required(errorMessages.OPTION_REQUIRED));
const wipersOfferedStrings = {
FRONT: "FRONT",
REAR: "REAR",
BOTH: "BOTH",
};
export default {
name: "add-vaps-modal-buttons",
props: {
vapsTilesCmsName: String,
availableLineItems: Object,
modelValue: Object,
},
data() {
return {
addVapsButton: addVapsButton,
wipersOffered: null,
isModalOpened: false,
selectedWipers: this.getSelectedWipers(),
};
},
methods: {
processIfStatements,
openModal(modalName) {
this.selectedWipers = this.getSelectedWipers(); // reset selectedWipers to null upon modal open
this.$refs[modalName].openModal();
},
closeModal(modalName) {
this.$refs[modalName].closeModal();
},
addRainDefenseToCart(modalName, part) {
// Clone vaps array, then replace this.currentCartItems.vaps with it at the end
// in order to successfully trigger parent's watcher
const clonedVaps = this.currentCartItems.vaps.slice(0);
clonedVaps.push(part);
this.currentCartItems.vaps = clonedVaps;
this.closeModal(modalName);
const message = this.getRainDefenseAddedMessage();
this.$emit("added-to-cart", {
messageHeadline: message,
type: "alert-success",
isDismissible: true,
});
},
addWipersToCart(modalName, part) {
const itemsForCart = [];
const frontWipersAlreadyInCart = this.currentCartItems.vaps.some((item) => {
return item.partType === part.frontWiperLineItems[0].partType;
});
const rearWipersAlreadyInCart = this.currentCartItems.vaps.some((item) => {
return item.partType === part.rearWiperLineItems[0]?.partType;
});
if (this.wipersOffered === wipersOfferedStrings.BOTH) {
this.selectedWipers.forEach((wiper) => {
itemsForCart.push(wiper);
});
} else {
if (
!frontWipersAlreadyInCart &&
this.wipersOffered === wipersOfferedStrings.FRONT
) {
itemsForCart.push(wipersOfferedStrings.FRONT);
this.selectedWipers = ["FRONT"];
}
if (!rearWipersAlreadyInCart && this.wipersOffered === wipersOfferedStrings.REAR) {
itemsForCart.push(wipersOfferedStrings.REAR);
this.selectedWipers = ["REAR"];
}
}
// Clone vaps array, then replace this.currentCartItems.vaps with it at the end
// in order to successfully trigger parent's watcher
const clonedVaps = this.currentCartItems.vaps.slice(0);
itemsForCart.forEach((type) => {
if (type === wipersOfferedStrings.FRONT) {
part.frontWiperLineItems.forEach((part) => {
clonedVaps.push(part);
});
}
if (type === wipersOfferedStrings.REAR) {
part.rearWiperLineItems.forEach((part) => {
clonedVaps.push(part);
});
}
});
this.currentCartItems.vaps = clonedVaps;
this.closeModal(modalName);
const message = this.getWipersAddedMessage();
this.$emit("added-to-cart", {
messageHeadline: message,
type: "alert-success",
isDismissible: true,
});
},
updateWipersOffered(value) {
this.wipersOffered = value;
},
getSelectedWipers() {
return null;
},
getRainDefenseAddedMessage() {
return this.AddRainDefenseSuccessMessageFromCms;
},
getWipersAddedMessage() {
return this.processIfStatements(
this.AddWipersSuccessMessageFromCms,
"custom",
this.getCustomValueFromString
);
},
getCustomValueFromString(str) {
switch (str) {
case "vapsAddedIsFrontWipers":
return (
this.selectedWipers?.length === 1 &&
this.selectedWipers[0] === wipersOfferedStrings.FRONT
);
case "vapsAddedIsRearWipers":
return (
this.selectedWipers?.length === 1 &&
this.selectedWipers[0] === wipersOfferedStrings.REAR
);
case "vapsAddedIsBothWipers":
return this.selectedWipers?.length > 1;
default:
return null;
}
},
},
computed: {
currentCartItems() {
const modelValue = this.modelValue;
if (!modelValue.vaps) modelValue.vaps = [];
return modelValue;
},
rainDefenseModal() {
const lineItem = this.availableLineItems.find((item) => {
return item.partType === partTypeStrings.RAIN_DEFENSE;
});
if (lineItem)
lineItem.listPrice = parseFloat(
lineItem?.laborAmount + lineItem?.sellingPrice + lineItem?.kitPrice
).toFixed(2);
return lineItem;
},
wipersModal() {
// create a single wiper item for modal
const frontWiperLineItems = this.availableLineItems.filter((item) => {
return item.partType.includes(partTypeStrings.FRONT_WIPER);
});
const rearWiperLineItems = this.availableLineItems.filter((item) => {
return item.partType.includes(partTypeStrings.REAR_WIPER);
});
let wipersModal;
let totalFrontPrice = 0;
let totalRearPrice = 0;
// calculate prices to display
frontWiperLineItems?.forEach((item) => {
totalFrontPrice += item?.laborAmount + item?.sellingPrice + item?.kitPrice;
});
rearWiperLineItems?.forEach((item) => {
totalRearPrice += item?.laborAmount + item?.sellingPrice + item?.kitPrice;
});
wipersModal = {
description: "WIPERS ITEM",
partType: "WIPERS",
frontWiperLineItems: frontWiperLineItems,
rearWiperLineItems: rearWiperLineItems,
totalFrontPrice: parseFloat(totalFrontPrice).toFixed(2),
totalRearPrice: parseFloat(totalRearPrice).toFixed(2),
};
return wipersModal;
},
answersCmsData() {
return this.getCmsContent(this.vapsTilesCmsName, "Answers");
},
buttonsToDisplay() {
const buttons = [];
if (!this.answersCmsData) return buttons;
const rainDefenseInCart = this.currentCartItems.vaps?.some((vap) => {
return vap?.partType === partTypeStrings.RAIN_DEFENSE;
});
const frontWipersInCart = this.currentCartItems.vaps?.some((vap) => {
return vap?.partType?.includes(partTypeStrings.FRONT_WIPER);
});
const rearWipersInCart = this.currentCartItems.vaps?.some((vap) => {
return vap?.partType?.includes(partTypeStrings.REAR_WIPER);
});
const getAnswer = (name, answers) => {
const answerIndex = answers.findIndex((answer) => {
return answer.Name === name;
});
return answers[answerIndex];
};
if (!rainDefenseInCart) {
// NO RAIN DEFENSE IN CART; SHOW RAIN DEFENSE BUTTON
const modalData = getAnswer("RainDefenseModal", this.answersCmsData);
modalData.SubText = "+$" + this.rainDefenseModal?.listPrice;
buttons.push(modalData);
}
const modalData = getAnswer("WipersModal", this.answersCmsData);
if (!frontWipersInCart) {
if (!rearWipersInCart && this.wipersModal?.rearWiperLineItems.length > 0) {
// NO REAR WIPERS or FRONT WIPERS IN CART; SHOW COMBO BUTTON
const prices = [
this.wipersModal?.totalFrontPrice,
this.wipersModal?.totalRearPrice,
];
prices.sort((a, b) => a - b);
modalData.SubText = "+$" + prices[0] + " - $" + prices[prices.length - 1];
this.updateWipersOffered(wipersOfferedStrings.BOTH);
buttons.push(modalData);
} else {
// NO FRONT WIPERS IN CART; SHOW ONLY FRONT WIPERS BUTTON
modalData.SubText = "+$" + this.wipersModal?.totalFrontPrice;
this.updateWipersOffered(wipersOfferedStrings.FRONT);
buttons.push(modalData);
}
} else if (!rearWipersInCart && this.wipersModal?.rearWiperLineItems.length > 0) {
// NO REAR WIPERS IN CART; SHOW ONLY REAR WIPERS BUTTON
modalData.SubText = "+$" + this.wipersModal?.totalRearPrice;
this.updateWipersOffered(wipersOfferedStrings.REAR);
buttons.push(modalData);
}
return buttons;
},
wipersOfferedStrings() {
return wipersOfferedStrings;
},
wipersOptions() {
const wipersOptions = [];
const wipersFrontCopy = this.getCmsContent(
"AddFrontBladesQuestionWidget",
"QuestionText"
);
const wipersRearCopy = this.getCmsContent(
"AddRearBladesQuestionWidget",
"QuestionText"
);
const frontWipersLineItems = this.wipersModal.frontWiperLineItems;
const rearWipersLineItems = this.wipersModal.rearWiperLineItems;
if (frontWipersLineItems) {
const wipersOption = {
buttonLabel: wipersFrontCopy,
groupName: "wipers-options",
value: wipersOfferedStrings.FRONT,
buttonLabelSubCopy: "buttonLabelSubCopy",
buttonBodyCopy: "buttonBodyCopy",
buttonAuxillaryCopy: "buttonAuxillaryCopy",
buttonFooterCopy: "buttonFooterCopy",
additionalButtonData: "+$" + this.wipersModal.totalFrontPrice,
};
wipersOptions.push(wipersOption);
}
if (rearWipersLineItems) {
const wipersOption = {
buttonLabel: wipersRearCopy,
groupName: "wipers-options",
value: wipersOfferedStrings.REAR,
buttonLabelSubCopy: "buttonLabelSubCopy",
buttonBodyCopy: "buttonBodyCopy",
buttonAuxillaryCopy: "buttonAuxillaryCopy",
buttonFooterCopy: "buttonFooterCopy",
additionalButtonData: "+$" + this.wipersModal.totalRearPrice,
};
wipersOptions.push(wipersOption);
}
return wipersOptions;
},
AddRainDefenseSuccessMessageFromCms() {
return this.getCmsContent("AddRainDefenseSuccessMessageWidget", "Text");
},
AddWipersSuccessMessageFromCms() {
return this.getCmsContent("AddWipersSuccessMessageWidget", "Text");
},
},
components: {
buttonQuestion,
contentGroupModal,
},
};
</script>
<style lang="scss">
.add-vaps-buttons {
// necessary overrides for modals
.modal {
&.modal-component {
.modal-dialog {
.modal-content {
.modal-body {
padding-bottom: 1.5rem;
& > img {
margin-bottom: 1.5rem;
line-height: 2;
text-align: center;
}
& > h5 {
text-align: center;
}
p {
margin-bottom: 1rem;
}
p.subheader-text {
text-align: center;
}
p.price {
text-align: center;
}
.wiper-options {
.ui-checkbox {
display: block;
& > div.col {
margin-bottom: 1rem;
&:last-child {
margin-bottom: 0;
}
}
.checkbox {
display: flex;
justify-content: space-between;
.additional-button-data {
font-size: 0.875rem;
line-height: 1.75;
padding-left: 0.5rem;
color: $green;
}
}
}
p {
margin-bottom: 0;
line-height: 1.75;
}
}
}
}
}
}
}
}
</style>