Merge branch 'develop' into feature/CSR-1392
This commit is contained in:
commit
a16b494013
7 changed files with 548 additions and 101 deletions
|
|
@ -3,11 +3,11 @@
|
|||
This public/css folder uses a standalone .scss > .css setup.
|
||||
## Usage
|
||||
|
||||
From a Terminal window, run the Sass Watch command on this folder only:
|
||||
From a Terminal window, run the Sass Watch command from the public folder only:
|
||||
|
||||
```bash
|
||||
sass --no-source-map --watch public/css/hop-styling.scss:public/css/hop-styling.css
|
||||
sass --no-source-map --watch scss:css
|
||||
```
|
||||
This will output a CSS file that can be consumed by the Payment page.
|
||||
This will compile and output .css files (into the public/css folder) that can be consumed by the Payment page.
|
||||
|
||||
# Do not use the .css file on its own. You must use the .scss file and have Sass compile it to the .css file.
|
||||
# Do not use the .css files on their own. You must use the .scss files and have Sass compile them to .css files.
|
||||
|
|
|
|||
87
public/css/site-2020Styling.css
Normal file
87
public/css/site-2020Styling.css
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/* IMPORTANT: READ README.md in this folder! Do not edit .css file directly! */
|
||||
/* IMPORTANT: READ README.md in this folder! Do not edit .css file directly! */
|
||||
/* IMPORTANT: READ README.md in this folder! Do not edit .css file directly! */
|
||||
/* IMPORTANT: READ README.md in this folder! Do not edit .css file directly! */
|
||||
/* Style the modal when PayPal button is selected */
|
||||
#pageLoadingModal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1040;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.35);
|
||||
display: flex;
|
||||
}
|
||||
#pageLoadingModal .modal-content {
|
||||
margin: auto auto;
|
||||
}
|
||||
#pageLoadingModal p {
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
}
|
||||
#pageLoadingModal .modal {
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1040;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
outline: 0;
|
||||
}
|
||||
#pageLoadingModal .modal-content {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
background-clip: padding-box;
|
||||
outline: 0;
|
||||
width: 168px;
|
||||
height: 168px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
#pageLoadingModal .modal-content:before, #pageLoadingModal .modal-content:after {
|
||||
content: "";
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
box-shadow: 0 0 3px 2px rgba(0, 0, 0, 0.25) inset;
|
||||
top: 24px;
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
left: 24px;
|
||||
}
|
||||
#pageLoadingModal .modal-content:after {
|
||||
box-shadow: 0 3px 0 #da291c inset;
|
||||
animation: rotate 1s linear infinite;
|
||||
}
|
||||
#pageLoadingModal .modal-backdrop {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
background-color: #000000;
|
||||
}
|
||||
#pageLoadingModal .modal-backdrop.fade {
|
||||
opacity: 0;
|
||||
filter: alpha(opacity=0);
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
0% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.creditCardSpecific {
|
||||
display: none;
|
||||
}
|
||||
91
public/scss/site-2020Styling.scss
Normal file
91
public/scss/site-2020Styling.scss
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/* IMPORTANT: READ README.md in this folder! Do not edit .css file directly! */
|
||||
/* IMPORTANT: READ README.md in this folder! Do not edit .css file directly! */
|
||||
/* IMPORTANT: READ README.md in this folder! Do not edit .css file directly! */
|
||||
/* IMPORTANT: READ README.md in this folder! Do not edit .css file directly! */
|
||||
|
||||
/* Style the modal when PayPal button is selected */
|
||||
#pageLoadingModal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1040;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0,0,0,.35);
|
||||
display: flex;
|
||||
|
||||
.modal-content {
|
||||
margin: auto auto;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1040;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
background-clip: padding-box;
|
||||
outline: 0;
|
||||
width: 168px;
|
||||
height: 168px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
box-shadow: 0 0 3px 2px rgba(0, 0, 0, 0.25) inset;
|
||||
top: 24px;
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
left: 24px;
|
||||
}
|
||||
&:after {
|
||||
box-shadow: 0 3px 0 #da291c inset;
|
||||
animation: rotate 1s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-backdrop {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
background-color: #000000;
|
||||
&.fade {
|
||||
opacity: 0;
|
||||
filter: alpha(opacity=0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
0% { transform: rotate(0)}
|
||||
100% { transform: rotate(360deg)}
|
||||
}
|
||||
|
||||
.creditCardSpecific {
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -244,7 +244,7 @@ export default {
|
|||
|
||||
<style lang="scss">
|
||||
.main {
|
||||
padding: 1rem 0;
|
||||
padding: 1rem 1.5rem 1.5rem;
|
||||
box-shadow: 0 3px 10px rgb(0 0 0 / 0.2);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
|
@ -260,6 +260,7 @@ export default {
|
|||
|
||||
+ p {
|
||||
font-size: 1rem;
|
||||
margin-top: 0.5rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
|
@ -270,7 +271,7 @@ export default {
|
|||
}
|
||||
|
||||
.calendar-section .add-to-calendar {
|
||||
padding: 10px 0;
|
||||
padding: 1rem 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
|
@ -279,6 +280,10 @@ export default {
|
|||
background-color: #fff;
|
||||
}
|
||||
|
||||
.appoinmenttext p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.calendar-section .add-to-calendar .add-to-calendar-span {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
@ -296,12 +301,12 @@ export default {
|
|||
}
|
||||
.header-container {
|
||||
text-align: center;
|
||||
padding: 1rem 0 1.5rem 0;
|
||||
|
||||
p {
|
||||
display: inline-block;
|
||||
font-weight: 400;
|
||||
font-size: 1.25rem;
|
||||
padding: 0.3rem;
|
||||
color: $black;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,39 +3,75 @@
|
|||
<div class="add-vaps-buttons" aria-live="polite">
|
||||
<buttonQuestion
|
||||
ref="buttonQuestion"
|
||||
:answers="answersToDisplay"
|
||||
:answers="buttonsToDisplay"
|
||||
groupName="addVaps"
|
||||
v-model="answersToDisplay"
|
||||
v-model="buttonsToDisplay"
|
||||
buttonTypeString="addVapsButton"
|
||||
:buttonTypeObject="addVapsButton"
|
||||
:isWide="answersToDisplay.length > 1 ? false : true"
|
||||
:isWide="buttonsToDisplay.length > 1 ? false : true"
|
||||
@update:modelValue="openModal" />
|
||||
|
||||
<contentGroupModal
|
||||
ref="RainDefenseModal"
|
||||
cmsWidgetName="RainDefenseModal"
|
||||
v-if="rainDefenseItem"
|
||||
@footer-button-action="addToCart('RainDefenseModal', rainDefenseItem)"
|
||||
v-if="rainDefenseModal"
|
||||
@footer-button-action="addRainDefenseToCart('RainDefenseModal', rainDefenseModal)"
|
||||
footerButtonActionName="footer-button-action">
|
||||
<p class="price">{{ rainDefenseItem.listPrice }}</p>
|
||||
<p class="price">+${{ rainDefenseModal.listPrice }}</p>
|
||||
</contentGroupModal>
|
||||
|
||||
<contentGroupModal
|
||||
ref="WipersModal"
|
||||
cmsWidgetName="WipersModal"
|
||||
v-if="wipersItem"
|
||||
@footer-button-action="addToCart('WipersModal', wipersItem)"
|
||||
v-if="wipersModal"
|
||||
@footer-button-action="addWipersToCart('WipersModal', wipersModal)"
|
||||
footerButtonActionName="footer-button-action">
|
||||
<p class="price">{{ wipersItem.listPrice }}</p>
|
||||
<div v-if="wipersToDisplay === wipersToDisplayStrings.BOTH" class="wiper-options">
|
||||
<div>
|
||||
<checkboxQuestion
|
||||
class="mb-5"
|
||||
cmsWidgetName="AddFrontBladesQuestionWidget"
|
||||
v-model="selectedFrontWipers" />
|
||||
<p class="price">+${{ wipersModal.totalFrontPrice }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<checkboxQuestion
|
||||
class="mb-5"
|
||||
cmsWidgetName="AddRearBladesQuestionWidget"
|
||||
v-model="selectedRearWipers" />
|
||||
<p class="price">+${{ wipersModal.totalRearPrice }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="wipersToDisplay === wipersToDisplayStrings.FRONT"
|
||||
class="wiper-options">
|
||||
<p class="price">+${{ wipersModal.totalFrontPrice }}</p>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="wipersToDisplay === wipersToDisplayStrings.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";
|
||||
import checkboxQuestion from "@/digital-components/checkbox-question/checkbox-question";
|
||||
|
||||
// SUPPORTING
|
||||
import { partTypeStrings } from "@/constants/part-type-strings";
|
||||
|
||||
const wipersToDisplayStrings = {
|
||||
FRONT: "FRONT",
|
||||
REAR: "REAR",
|
||||
BOTH: "BOTH",
|
||||
};
|
||||
|
||||
export default {
|
||||
name: "add-vaps-modal-buttons",
|
||||
|
|
@ -47,54 +83,73 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
addVapsButton: addVapsButton,
|
||||
selectedFrontWipers: false,
|
||||
selectedRearWipers: false,
|
||||
wipersToDisplay: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
openModal(modalName) {
|
||||
this.$refs[modalName].openModal();
|
||||
},
|
||||
addToCart(modalName, part) {
|
||||
const vapsItems = this.currentCartItems.vaps;
|
||||
const alreadyInVaps = vapsItems.some((item) => {
|
||||
addRainDefenseToCart(modalName, part) {
|
||||
const alreadyInCart = this.currentCartItems.vaps.some((item) => {
|
||||
return item.partType === part.partType;
|
||||
});
|
||||
if (!alreadyInVaps) {
|
||||
if (part.subItems) {
|
||||
// for wipers, a "combined" part (w/ subItems)
|
||||
part.subItems.forEach((part) => {
|
||||
if (!alreadyInCart) {
|
||||
this.currentCartItems.vaps.push(part);
|
||||
}
|
||||
this.$refs[modalName].closeModal();
|
||||
},
|
||||
addWipersToCart(modalName, part) {
|
||||
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.wipersToDisplay === wipersToDisplayStrings.FRONT) {
|
||||
this.selectedFrontWipers = true; // set as true if front wipers is only option
|
||||
}
|
||||
if (this.wipersToDisplay === wipersToDisplayStrings.REAR) {
|
||||
this.selectedRearWipers = true; // set as true if rear wipers is only option
|
||||
}
|
||||
if (!frontWipersAlreadyInCart && this.selectedFrontWipers) {
|
||||
if (part.frontWiperLineItems) {
|
||||
// for wipers, a "combined" part (frontWiperLineItems)
|
||||
part.frontWiperLineItems.forEach((part) => {
|
||||
this.currentCartItems.vaps.push(part);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!rearWipersAlreadyInCart && this.selectedRearWipers) {
|
||||
if (part.rearWiperLineItems) {
|
||||
part.rearWiperLineItems.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();
|
||||
|
||||
if (this.wipersToDisplay === wipersToDisplayStrings.BOTH) {
|
||||
this.selectedFrontWipers = false; // set as false if both options are given
|
||||
this.selectedRearWipers = false; // set as false if both options are given
|
||||
}
|
||||
},
|
||||
updateWipersToDisplay(value) {
|
||||
this.wipersToDisplay = value;
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
currentCartItems() {
|
||||
return this.modelValue;
|
||||
const modelValue = this.modelValue;
|
||||
if (!modelValue.vaps) modelValue.vaps = [];
|
||||
return 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() {
|
||||
rainDefenseModal() {
|
||||
const lineItem = this.availableLineItems.find((item) => {
|
||||
return item.partType === "RAIN DEFENSE";
|
||||
return item.partType === partTypeStrings.RAIN_DEFENSE;
|
||||
});
|
||||
if (lineItem)
|
||||
lineItem.listPrice = parseFloat(
|
||||
|
|
@ -102,63 +157,161 @@ export default {
|
|||
).toFixed(2);
|
||||
return lineItem;
|
||||
},
|
||||
wipersItem() {
|
||||
const wiperLineItems = this.availableLineItems.filter((item) => {
|
||||
return item.partType.includes("WIPER");
|
||||
wipersModal() {
|
||||
// create a single wiper item for modal
|
||||
const frontWiperLineItems = this.availableLineItems.filter((item) => {
|
||||
return item.partType.includes(partTypeStrings.FRONT_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 [];
|
||||
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");
|
||||
},
|
||||
answersToDisplay() {
|
||||
const answers = [];
|
||||
if (!this.answersCmsData) return 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 (this.showAddWipers) {
|
||||
const answer = getAnswer("WipersModal", this.answersCmsData);
|
||||
answer.SubText = "+$" + this.wipersItem.listPrice;
|
||||
answers.push(answer);
|
||||
|
||||
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);
|
||||
}
|
||||
if (this.showAddRainDefense) {
|
||||
const answer = getAnswer("RainDefenseModal", this.answersCmsData);
|
||||
answer.SubText = "+$" + this.rainDefenseItem.listPrice;
|
||||
answers.push(answer);
|
||||
|
||||
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.updateWipersToDisplay(wipersToDisplayStrings.BOTH);
|
||||
buttons.push(modalData);
|
||||
} else {
|
||||
// NO FRONT WIPERS IN CART; SHOW ONLY FRONT WIPERS BUTTON
|
||||
modalData.SubText = "+$" + this.wipersModal?.totalFrontPrice;
|
||||
this.updateWipersToDisplay(wipersToDisplayStrings.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.updateWipersToDisplay(wipersToDisplayStrings.REAR);
|
||||
buttons.push(modalData);
|
||||
}
|
||||
return answers;
|
||||
|
||||
return buttons;
|
||||
},
|
||||
wipersToDisplayStrings() {
|
||||
return wipersToDisplayStrings;
|
||||
},
|
||||
},
|
||||
components: {
|
||||
buttonQuestion,
|
||||
contentGroupModal,
|
||||
checkboxQuestion,
|
||||
},
|
||||
};
|
||||
</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 {
|
||||
& > div {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.form-check {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
p.price {
|
||||
font-size: 0.875rem;
|
||||
padding-left: 0.5rem;
|
||||
color: $green;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,39 @@
|
|||
scrolling="no">
|
||||
</iframe>
|
||||
</div>
|
||||
<div>{{ switchPaymentText }}</div>
|
||||
<div>
|
||||
<button
|
||||
v-if="paymentType !== 'cc'"
|
||||
ref="switchToCCButton"
|
||||
type="button"
|
||||
@mousedown="switchPIAMethod('cc')"
|
||||
aria-label="Switch to Credit Card">
|
||||
Switch to Credit Card
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="paymentType !== 'cc'">or</div>
|
||||
<div>
|
||||
<button
|
||||
v-if="paymentType !== 'pp'"
|
||||
ref="switchToPPButton"
|
||||
type="button"
|
||||
@mousedown="switchPIAMethod('pp')"
|
||||
aria-label="Switch to PayPal">
|
||||
Switch to PayPal
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="paymentType === 'cc'">or</div>
|
||||
<div>
|
||||
<button
|
||||
v-if="paymentType !== 'ap'"
|
||||
ref="switchToAPButton"
|
||||
type="button"
|
||||
@mousedown="switchPIAMethod('ap')"
|
||||
aria-label="Switch to Afterpay">
|
||||
Switch to Afterpay
|
||||
</button>
|
||||
</div>
|
||||
<navbar
|
||||
cmsWidgetName="FunnelFooterWidget"
|
||||
isForwardActionDisabled="true"
|
||||
|
|
@ -32,7 +65,7 @@
|
|||
</Form>
|
||||
|
||||
<form
|
||||
ref="myForm"
|
||||
ref="hopForm"
|
||||
id="card-data"
|
||||
:target="paypalPayment ? '_top' : 'card-frame'"
|
||||
method="POST"
|
||||
|
|
@ -52,6 +85,7 @@
|
|||
<input type="hidden" name="sgNoKeystrokeProcessing" value="false" />
|
||||
|
||||
<input type="hidden" name="maskCharacter" value="*" />
|
||||
<input type="hidden" name="styleSheetCode" :value="dynamicCSSUrl" />
|
||||
<input type="hidden" name="styleSheetCode2" :value="dynamicHopCSSUrl" />
|
||||
|
||||
<input type="hidden" name="sgReceiptResponseURL" :value="piaResponseUrl" />
|
||||
|
|
@ -165,6 +199,7 @@ import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
|||
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||
import { applicationConfig } from "@/constants/application-config";
|
||||
import { paymentMethods } from "@/constants/payment-method-constants";
|
||||
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
|
||||
import baseMixin from "@/mixins/base-mixin.js";
|
||||
|
||||
// Validation
|
||||
|
|
@ -232,6 +267,10 @@ export default {
|
|||
});
|
||||
},
|
||||
computed: {
|
||||
dynamicCSSUrl() {
|
||||
const { protocol, hostname, port } = window.location;
|
||||
return `${protocol}//${hostname}:${port}/fmg/css/site-2020Styling.css`;
|
||||
},
|
||||
dynamicHopCSSUrl() {
|
||||
const { protocol, hostname, port } = window.location;
|
||||
return `${protocol}//${hostname}:${port}/fmg/css/hop-styling.css`;
|
||||
|
|
@ -248,11 +287,71 @@ export default {
|
|||
}
|
||||
return "";
|
||||
},
|
||||
switchPaymentText() {
|
||||
return this.getCmsContent("PaymentMethodWidget", "QuestionText");
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
arePagePrerequisitesValid() {
|
||||
// TODO
|
||||
return true;
|
||||
// Line Items
|
||||
const packageReqs = !!store.getters.order.lineItems.supportingItems;
|
||||
|
||||
// Service Location
|
||||
const serviceLocation = store.getters.order.serviceLocation;
|
||||
const mobileReqs = !!(
|
||||
serviceLocation.address &&
|
||||
serviceLocation.city &&
|
||||
serviceLocation.state &&
|
||||
serviceLocation.zipCode
|
||||
);
|
||||
|
||||
const providerLocation = serviceLocation.provider.address;
|
||||
const dropOffInshopReqs = !!(
|
||||
providerLocation.streetAddress &&
|
||||
providerLocation.city &&
|
||||
providerLocation.state &&
|
||||
providerLocation.zipCode
|
||||
);
|
||||
|
||||
const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE;
|
||||
|
||||
const serviceLocationReqs =
|
||||
(isMobile && mobileReqs) || (!isMobile && dropOffInshopReqs);
|
||||
|
||||
// Insurance
|
||||
const isInsuranceSet = store.getters.order.payment.isInsurance !== null;
|
||||
|
||||
// Schedule
|
||||
const schedule = store.getters.order.schedule;
|
||||
const scheduleReqs = !!(
|
||||
schedule.date &&
|
||||
schedule.startTime &&
|
||||
(!isMobile || schedule.endTime) &&
|
||||
schedule.jobMaxMinutes &&
|
||||
schedule.jobMinMinutes
|
||||
);
|
||||
|
||||
// Customer
|
||||
const customer = store.getters.order.customer;
|
||||
const customerReqs = !!(
|
||||
customer.firstName &&
|
||||
customer.lastName &&
|
||||
customer.phoneNumber &&
|
||||
customer.emailAddress
|
||||
);
|
||||
|
||||
const paymentMethodReqs =
|
||||
store.getters.order.payment.isPia !== null &&
|
||||
(store.getters.order.payment.isPia || !!store.getters.order.payment.piaType);
|
||||
|
||||
return (
|
||||
packageReqs &&
|
||||
serviceLocationReqs &&
|
||||
isInsuranceSet &&
|
||||
scheduleReqs &&
|
||||
customerReqs &&
|
||||
paymentMethodReqs
|
||||
);
|
||||
},
|
||||
getWOrkOrderNumber() {
|
||||
if (store.getters.order.workOrderNumber) {
|
||||
|
|
@ -345,6 +444,28 @@ export default {
|
|||
window.location = applicationConfig.PIA_CANCEL_URL;
|
||||
//this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
|
||||
},
|
||||
switchPIAMethod(payMethod) {
|
||||
this.paymentType = payMethod;
|
||||
this.submitHopForm();
|
||||
},
|
||||
submitHopForm() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.hopForm.submit();
|
||||
|
||||
const iframe = this.$refs.paymentFrame;
|
||||
if (iframe) {
|
||||
iframe.onload = () => {
|
||||
if (iframe.contentWindow) {
|
||||
if (this.paymentType == "cc") {
|
||||
iframe.contentWindow.postMessage("CreditCardChosen", "*");
|
||||
} else if (this.paymentType == "ap") {
|
||||
iframe.contentWindow.postMessage("afterpay", "*");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
async fetchSignatureInfo(signatureInfo) {
|
||||
if (this.isPaypal()) {
|
||||
this.$refs.loadingModal.showModal();
|
||||
|
|
@ -354,20 +475,7 @@ export default {
|
|||
this.authSignature = signatureInfo.signature;
|
||||
this.authSignatureStart = signatureInfo.startDate;
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$refs.myForm.submit();
|
||||
|
||||
if (this.paymentType == "ap") {
|
||||
const iframe = this.$refs.paymentFrame;
|
||||
if (iframe) {
|
||||
iframe.onload = () => {
|
||||
if (iframe.contentWindow) {
|
||||
iframe.contentWindow.postMessage("afterpay", "*");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
this.submitHopForm();
|
||||
},
|
||||
},
|
||||
components: {
|
||||
|
|
@ -385,4 +493,7 @@ export default {
|
|||
width: 100%;
|
||||
border: 0 none;
|
||||
}
|
||||
#pageLoadingModal {
|
||||
background-color: red;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in a new issue