recal ack modal WIP
This commit is contained in:
parent
29f727a342
commit
933449fbdf
5 changed files with 253 additions and 16 deletions
|
|
@ -308,6 +308,7 @@ export default {
|
||||||
return (
|
return (
|
||||||
glassParts !== null
|
glassParts !== null
|
||||||
&& !!glassParts.find((part) => part.requiresRecalibration)
|
&& !!glassParts.find((part) => part.requiresRecalibration)
|
||||||
|
&& !!glassParts.find((part) => part.canSafeliteRecalibrate)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
totalServicePrice() {
|
totalServicePrice() {
|
||||||
|
|
|
||||||
118
src/layouts/schedule-page/recal-ack-modal/recal-ack-modal.vue
Normal file
118
src/layouts/schedule-page/recal-ack-modal/recal-ack-modal.vue
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
<template>
|
||||||
|
<div id="recal-ack-modal-container">
|
||||||
|
<modal
|
||||||
|
:ref="ModalName"
|
||||||
|
:modalId="ModalName"
|
||||||
|
:footerButtonText="ModalCloseButtonText"
|
||||||
|
:isButtonDisabled="isButtonDisabled"
|
||||||
|
@footerButtonEvent="footerButtonClick"
|
||||||
|
:displayCloseButton="false"
|
||||||
|
:displayCloseLink="true">
|
||||||
|
<div class="form-test-invalid">
|
||||||
|
<h5>{{ ModalHeadline }}</h5>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="mb-4"
|
||||||
|
v-html="ModalBodyText"></div>
|
||||||
|
<recalAckToggle
|
||||||
|
class="mb-5"
|
||||||
|
cmsWidgetName="RecalAckModalToggle" />
|
||||||
|
<checkBox
|
||||||
|
ref="recalAcknowledgement"
|
||||||
|
v-model="acknowledged"
|
||||||
|
class="mb-2 mt-4"
|
||||||
|
:class="showAcknowledgementError && ' has-error'"
|
||||||
|
:validationRules="rules.optionRequired"
|
||||||
|
checkboxName="recalAcknowledgement"
|
||||||
|
buttonID="recalAcknowledgement"
|
||||||
|
:tabIndex="0"
|
||||||
|
:checkboxLabel="ModalSubBodyText"
|
||||||
|
:screenReaderOnlyText="ModalSubBodyText"
|
||||||
|
isRequired />
|
||||||
|
<div
|
||||||
|
v-if="showAcknowledgementError"
|
||||||
|
class="row form-test-error mt-1">
|
||||||
|
<p>{{ errorMessage }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import modal from "@/digital-components/modal/modal";
|
||||||
|
import recalAckToggle from '@/layouts/schedule-page/recal-ack-modal/recal-ack-toggle/recal-ack-toggle.vue';
|
||||||
|
import checkBox from '@/ux-components/checkbox/checkbox.vue';
|
||||||
|
import globalRules from '@/constants/global-rules';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "recal-ack-modal",
|
||||||
|
components: {
|
||||||
|
modal,
|
||||||
|
checkBox,
|
||||||
|
recalAckToggle
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
cmsWidgetName: String,
|
||||||
|
ackError: String
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
acknowledged: false,
|
||||||
|
showAcknowledgementError: false,
|
||||||
|
rules: {
|
||||||
|
optionRequired: globalRules.OPTION_REQUIRED
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
ModalName() {
|
||||||
|
return this.cmsWidgetName;
|
||||||
|
},
|
||||||
|
ModalHeadline() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
||||||
|
},
|
||||||
|
ModalBodyText() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'BodyText');
|
||||||
|
},
|
||||||
|
ModalSubBodyText() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'BodyText2');
|
||||||
|
},
|
||||||
|
ModalCloseButtonText() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'FooterText');
|
||||||
|
},
|
||||||
|
isButtonDisabled() {
|
||||||
|
return !this.acknowledged;
|
||||||
|
},
|
||||||
|
errorMessage() {
|
||||||
|
if (this.showAcknowledgementError) {
|
||||||
|
return this.ackError;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
acknowledged() {
|
||||||
|
this.showAcknowledgementError = false;
|
||||||
|
this.emit('recalAcknowledged', this.acknowledged);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
openModal() {
|
||||||
|
this.$refs[this.ModalName].openModal();
|
||||||
|
},
|
||||||
|
footerButtonClick() {
|
||||||
|
if (this.acknowledged) {
|
||||||
|
this.$refs[this.ModalName]?.closeModal();
|
||||||
|
} else {
|
||||||
|
this.showAcknowledgementError = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,109 @@
|
||||||
|
<template>
|
||||||
|
<div class="recal-ack-toggle mt-2 mb-3">
|
||||||
|
<textLink
|
||||||
|
id="moreDetails"
|
||||||
|
class="d-inline-block"
|
||||||
|
linkType="text"
|
||||||
|
href="#!"
|
||||||
|
:text="textForToggle"
|
||||||
|
@click="handleClickToggle" />
|
||||||
|
<div
|
||||||
|
class="recal-ack-toggle d-inline-block"
|
||||||
|
:class="[isDetailVisible ? 'active' : '']"
|
||||||
|
@click="handleClickToggle"></div>
|
||||||
|
<Transition>
|
||||||
|
<div
|
||||||
|
v-show="isDetailVisible"
|
||||||
|
id="recal-ack-detail-wrapper"
|
||||||
|
class="mt-2">
|
||||||
|
<div
|
||||||
|
id="recal-ack-detail-content"
|
||||||
|
class="mb-2"
|
||||||
|
v-html="detailContent" />
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import textLink from '@/ux-components/text-link/text-link.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'recal-ack-toggle',
|
||||||
|
components: {
|
||||||
|
textLink
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
cmsWidgetName: String
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isDetailVisible: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
textForToggle() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
||||||
|
},
|
||||||
|
detailContent() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'BodyText');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleClickToggle() {
|
||||||
|
this.isDetailVisible = !this.isDetailVisible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "@/styles/ux-variables-svg-strings.scss";
|
||||||
|
.recal-ack-toggle {
|
||||||
|
.recal-ack-toggle {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
width: 16px;
|
||||||
|
height: 9px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
&.active::after {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#recal-ack-detail-wrapper {
|
||||||
|
// START - Vue Transition
|
||||||
|
&.v-enter-active,
|
||||||
|
&.v-leave-active {
|
||||||
|
transition: opacity 250ms ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.v-enter-from,
|
||||||
|
&.v-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
// END - Vue Transition
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#recal-ack-detail-content {
|
||||||
|
font-size: 1rem;
|
||||||
|
p {
|
||||||
|
font-size: 1rem;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
ol {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
:customSelectableDatesCallback="getAvailableDatesMethod"
|
:customSelectableDatesCallback="getAvailableDatesMethod"
|
||||||
@dateSelected="dateSelectedFromPicker"
|
@dateSelected="dateSelectedFromPicker"
|
||||||
@timeSlotSelected="timeSlotSelectedFromPicker" />
|
@timeSlotSelected="timeSlotSelectedFromPicker" />
|
||||||
<modal
|
<!-- <modal
|
||||||
ref="recalAckModal"
|
ref="recalAckModal"
|
||||||
class="recal-ack-modal"
|
class="recal-ack-modal"
|
||||||
:headerText="recalModalContent.headerText"
|
:headerText="recalModalContent.headerText"
|
||||||
|
|
@ -58,7 +58,7 @@
|
||||||
<div
|
<div
|
||||||
class="recal-ack-modal-body"
|
class="recal-ack-modal-body"
|
||||||
v-html="recalModalContent.bodyText"></div>
|
v-html="recalModalContent.bodyText"></div>
|
||||||
</modal>
|
</modal> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="site-footer-container iss-heritage-content-container-width">
|
<div class="site-footer-container iss-heritage-content-container-width">
|
||||||
|
|
@ -73,6 +73,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<recalAckModal
|
||||||
|
ref="recalAckModal"
|
||||||
|
cmsWidgetName="RecalAckModalWidget"
|
||||||
|
:ackError="ackError"
|
||||||
|
/>
|
||||||
</Form>
|
</Form>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -84,6 +89,7 @@ import datePicker from '@/digital-components/date-picker/date-picker.vue';
|
||||||
import serviceLocation from '@/layouts/schedule-page/service-location/service-location.vue';
|
import serviceLocation from '@/layouts/schedule-page/service-location/service-location.vue';
|
||||||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
||||||
import modal from '@/digital-components/modal/modal.vue';
|
import modal from '@/digital-components/modal/modal.vue';
|
||||||
|
import recalAckModal from '@/layouts/schedule-page/recal-ack-modal/recal-ack-modal.vue';
|
||||||
|
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import {
|
import {
|
||||||
|
|
@ -110,7 +116,8 @@ import {
|
||||||
import { Form } from 'vee-validate';
|
import { Form } from 'vee-validate';
|
||||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
import { containsRecalParts } from '@/helpers/recal-helper';
|
import { containsRecalParts, anyPartWithRequiresRecalFlag } from '@/helpers/recal-helper';
|
||||||
|
import errorMessages from '@/constants/error-messages';
|
||||||
|
|
||||||
// Define constants
|
// Define constants
|
||||||
const TIME_SLOTS_CALL_DAYS_LIMIT = 15;
|
const TIME_SLOTS_CALL_DAYS_LIMIT = 15;
|
||||||
|
|
@ -235,7 +242,7 @@ export default {
|
||||||
serviceLocation,
|
serviceLocation,
|
||||||
siteFooter,
|
siteFooter,
|
||||||
Form,
|
Form,
|
||||||
modal
|
recalAckModal
|
||||||
},
|
},
|
||||||
mixins: [BaseFormMixin],
|
mixins: [BaseFormMixin],
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
|
|
@ -410,7 +417,7 @@ export default {
|
||||||
supportingItems() {
|
supportingItems() {
|
||||||
return useMainStore().lineItems.supportingItems;
|
return useMainStore().lineItems.supportingItems;
|
||||||
},
|
},
|
||||||
displayRecalAckModalwidget() {
|
displayRecalAckModalWidget() {
|
||||||
// if any of the glass parts contain an item with the requiresRecalibration flag set to true
|
// if any of the glass parts contain an item with the requiresRecalibration flag set to true
|
||||||
// and the order does not contain a recalibration part, show the recalibration acknowledgement modal
|
// and the order does not contain a recalibration part, show the recalibration acknowledgement modal
|
||||||
const containsRecalPart = containsRecalParts(useMainStore().order.lineItems);
|
const containsRecalPart = containsRecalParts(useMainStore().order.lineItems);
|
||||||
|
|
@ -421,16 +428,9 @@ export default {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
recalModalContent() {
|
ackError() {
|
||||||
const widgetName = 'RecalAckModalWidget';
|
return errorMessages.ACKNOWLEDGEMENT_REQUIRED;
|
||||||
return {
|
}
|
||||||
headerText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT),
|
|
||||||
subHeaderText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.SUBHEADER_TEXT),
|
|
||||||
bodyText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT),
|
|
||||||
bodyText2: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT_2),
|
|
||||||
footerButtonText: this.getCmsContent(widgetName, widgetFields.CONTENT_GROUP_WIDGET.FOOTER_TEXT)
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
inShopDatesData(newData) {
|
inShopDatesData(newData) {
|
||||||
|
|
@ -761,6 +761,12 @@ export default {
|
||||||
this.showDatePickerError = false;
|
this.showDatePickerError = false;
|
||||||
},
|
},
|
||||||
async forwardButtonAction() {
|
async forwardButtonAction() {
|
||||||
|
if (this.displayRecalAckModal) {
|
||||||
|
showIssLoadingModal(false);
|
||||||
|
this.$refs.recalAckModal.openModal();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.isFormValid) {
|
if (!this.isFormValid) {
|
||||||
this.showDatePickerError = true;
|
this.showDatePickerError = true;
|
||||||
return;
|
return;
|
||||||
|
|
@ -777,6 +783,9 @@ export default {
|
||||||
this.navigationScenarios.CLICKED_FORWARD,
|
this.navigationScenarios.CLICKED_FORWARD,
|
||||||
this.$route
|
this.$route
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
updateRecalAcknowledged(isAcknowledged) {
|
||||||
|
this.displayRecalAckModal = !isAcknowledged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
process.env.VUE_APP_CONSUMER_CF_DISTRO = 'https://digitalapi.dev.safelite.io';
|
process.env.VUE_APP_CONSUMER_CF_DISTRO = 'https://digitalapi.test.safelite.io';
|
||||||
process.env.VUE_APP_CURRENT_ENVIRONMENT = 'Localhost';
|
process.env.VUE_APP_CURRENT_ENVIRONMENT = 'Localhost';
|
||||||
process.env.VUE_APP_CUSTOMER_PORTAL_URL = 'https://myaccountdev.safelite.com/';
|
process.env.VUE_APP_CUSTOMER_PORTAL_URL = 'https://myaccountdev.safelite.com/';
|
||||||
process.env.VUE_APP_GOOGLE_PLACES_API_KEY = 'AIzaSyCuLhQcDdZTTb4JzpUFms1OCch2dk5lHF0';
|
process.env.VUE_APP_GOOGLE_PLACES_API_KEY = 'AIzaSyCuLhQcDdZTTb4JzpUFms1OCch2dk5lHF0';
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue