Initial addition of "More Locations" modal
This commit is contained in:
parent
a43480dd02
commit
cc3ed87815
12 changed files with 285 additions and 81 deletions
|
|
@ -329,7 +329,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.question-text {
|
.question-text {
|
||||||
margin-bottom: .625rem;
|
margin-bottom: 1rem;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
line-height: 1.625rem;
|
line-height: 1.625rem;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,11 @@
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true">
|
aria-modal="true">
|
||||||
<div class="modal-header mb-2 mt-2">
|
<div class="modal-header mb-2 mt-2">
|
||||||
<label
|
<span
|
||||||
v-if="headerText"
|
v-if="headerText"
|
||||||
class="modal-title d-flex justify-content-center pb-0 w-100">
|
class="modal-title d-flex justify-content-center pb-0 w-100"
|
||||||
{{ headerText }}
|
:innerHTML="headerText">
|
||||||
</label>
|
</span>
|
||||||
<button
|
<button
|
||||||
ref="closeButton"
|
ref="closeButton"
|
||||||
type="button"
|
type="button"
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,8 @@ export default {
|
||||||
[headerKeys.TRANSACTION_ID]: crypto.randomUUID(),
|
[headerKeys.TRANSACTION_ID]: crypto.randomUUID(),
|
||||||
[headerKeys.ENTERPRISE_ORDER_NUMBER]: store.order.eon,
|
[headerKeys.ENTERPRISE_ORDER_NUMBER]: store.order.eon,
|
||||||
[headerKeys.REFERRAL_SEQUENCE_NUMBER]: store.order.referralSequenceNumber,
|
[headerKeys.REFERRAL_SEQUENCE_NUMBER]: store.order.referralSequenceNumber,
|
||||||
[headerKeys.SESSION_SEQUENCE_NUMBER]: sessionKey
|
[headerKeys.SESSION_SEQUENCE_NUMBER]: sessionKey,
|
||||||
|
'Cache-Control': 'no-cache, no-store, max-age=1'
|
||||||
};
|
};
|
||||||
|
|
||||||
axios({
|
axios({
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,6 @@
|
||||||
<siteSubHeader
|
<siteSubHeader
|
||||||
cmsWidgetName="SiteSubHeaderWidget"
|
cmsWidgetName="SiteSubHeaderWidget"
|
||||||
class="subheader" />
|
class="subheader" />
|
||||||
<!-- <serviceZipModalQuestion
|
|
||||||
ref="serviceZipCodeQuestion"
|
|
||||||
v-model="serviceZipCodeQuestion"
|
|
||||||
modalWidgetName="ServiceZipModalWidget"
|
|
||||||
:onZipUpdateCallback="reloadShopData"
|
|
||||||
@updatedServiceability="setServiceabilityDetails"
|
|
||||||
@updatedContainsMilitaryBase="
|
|
||||||
setContainsMilitaryBase
|
|
||||||
" /> -->
|
|
||||||
<alert
|
<alert
|
||||||
v-if="displayMilitaryZipAlert"
|
v-if="displayMilitaryZipAlert"
|
||||||
ref="alertMilitaryBaseZip"
|
ref="alertMilitaryBaseZip"
|
||||||
|
|
@ -72,7 +63,7 @@
|
||||||
validationRules="option-required" />
|
validationRules="option-required" />
|
||||||
</div>
|
</div>
|
||||||
<mobileLocationModalQuestions
|
<mobileLocationModalQuestions
|
||||||
v-if="isMobileLocationDisplayed"
|
v-if="isMobile"
|
||||||
ref="mobileLocationQuestions"
|
ref="mobileLocationQuestions"
|
||||||
v-model="mobileLocationQuestions"
|
v-model="mobileLocationQuestions"
|
||||||
customComponentId="mobileLocationQuestions"
|
customComponentId="mobileLocationQuestions"
|
||||||
|
|
@ -80,21 +71,16 @@
|
||||||
validationRules="mobile-location-required"
|
validationRules="mobile-location-required"
|
||||||
linkWidgetName="MobileLocationLinkWidget"
|
linkWidgetName="MobileLocationLinkWidget"
|
||||||
modalWidgetName="MobileLocationModalWidget"
|
modalWidgetName="MobileLocationModalWidget"
|
||||||
:onZipUpdateCallback="reloadShopData"
|
|
||||||
@updated-mobile-fee-part="setMobileFeePart"
|
@updated-mobile-fee-part="setMobileFeePart"
|
||||||
@updated-serviceability="setServiceabilityDetails"
|
@updated-serviceability="setServiceabilityDetails"
|
||||||
@updated-contains-military-base="setContainsMilitaryBase"
|
@updated-contains-military-base="setContainsMilitaryBase"
|
||||||
@updated-mobile-ctu="setCtuForMobile" />
|
@updated-mobile-ctu="setCtuForMobile" />
|
||||||
<shopQuestion
|
<shopAddress
|
||||||
v-show="isShopQuestionDisplayed"
|
|
||||||
:ref="SHOP_QUESTION_REF_NAME"
|
|
||||||
v-model="selectedProvider"
|
v-model="selectedProvider"
|
||||||
:selectedAppointmentType="selectedAppointmentType"
|
:isDisplayed="isInshop"
|
||||||
:isDisplayed="isShopQuestionDisplayed"
|
:selectAppointmentType="selectedAppointmentType"
|
||||||
cmsWidgetName="ShopQuestionWidget"
|
modalWidgetName="ChangeLocationModalWidget"
|
||||||
@updatedMobileProviderNumber="
|
cmsWidgetName="ShopAddressWidget" />
|
||||||
setMobileProviderNumber
|
|
||||||
" />
|
|
||||||
<contentGroupModal
|
<contentGroupModal
|
||||||
:ref="RECAL_MODAL_REF_NAME"
|
:ref="RECAL_MODAL_REF_NAME"
|
||||||
cssModalHeadlineClass="text-center"
|
cssModalHeadlineClass="text-center"
|
||||||
|
|
@ -134,11 +120,11 @@ import baseFormMixin from '@/mixins/base-form-mixin';
|
||||||
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal.vue';
|
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal.vue';
|
||||||
import mobileLocationModalQuestions from '@/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue';
|
import mobileLocationModalQuestions from '@/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue';
|
||||||
import { Form, defineRule } from 'vee-validate';
|
import { Form, defineRule } from 'vee-validate';
|
||||||
import shopQuestion from '@/layouts/service-location/shop-question/shop-question.vue';
|
|
||||||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
||||||
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
||||||
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
|
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
|
||||||
import serviceZipModalQuestion from '@/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue';
|
import serviceZipModalQuestion from '@/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue';
|
||||||
|
import shopAddress from './shop-address/shop-address.vue';
|
||||||
|
|
||||||
// DEFINE VALIDATION RULES
|
// DEFINE VALIDATION RULES
|
||||||
defineRule('mobile-location-required', (value) => {
|
defineRule('mobile-location-required', (value) => {
|
||||||
|
|
@ -155,7 +141,6 @@ defineRule('mobile-location-required', (value) => {
|
||||||
});
|
});
|
||||||
defineRule('selection-required', required(errorMessages.OPTION_REQUIRED));
|
defineRule('selection-required', required(errorMessages.OPTION_REQUIRED));
|
||||||
|
|
||||||
const SHOP_QUESTION_REF_NAME = 'shopQuestion';
|
|
||||||
const RECAL_MODAL_REF_NAME = 'RecalModal';
|
const RECAL_MODAL_REF_NAME = 'RecalModal';
|
||||||
const SITE_FOOTER_REF_NAME = 'siteFooter';
|
const SITE_FOOTER_REF_NAME = 'siteFooter';
|
||||||
|
|
||||||
|
|
@ -172,7 +157,7 @@ export default {
|
||||||
// eslint-disable-next-line vue/no-reserved-component-names
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
Form,
|
Form,
|
||||||
serviceZipModalQuestion,
|
serviceZipModalQuestion,
|
||||||
shopQuestion
|
shopAddress
|
||||||
},
|
},
|
||||||
mixins: [baseFormMixin],
|
mixins: [baseFormMixin],
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
|
|
@ -182,8 +167,8 @@ export default {
|
||||||
const zipCodeData = getZipCodeData(serviceZipCode);
|
const zipCodeData = getZipCodeData(serviceZipCode);
|
||||||
const mobileFeePartPromise = getPricedMobileFeePart(serviceZipCode);
|
const mobileFeePartPromise = getPricedMobileFeePart(serviceZipCode);
|
||||||
const serviceabilityDetailsPromise = getServiceabilityDetails(serviceZipCode);
|
const serviceabilityDetailsPromise = getServiceabilityDetails(serviceZipCode);
|
||||||
const shopQuestionInitialDataPromise = shopQuestion.methods.loadInitialData(serviceZipCode);
|
|
||||||
const getGlassFeesPromise = useMainStore().getGlassFees();
|
const getGlassFeesPromise = useMainStore().getGlassFees();
|
||||||
|
const providersPromise = useMainStore().getProviders(serviceZipCode);
|
||||||
|
|
||||||
// Settle promises and get results
|
// Settle promises and get results
|
||||||
const promiseResultMap = [
|
const promiseResultMap = [
|
||||||
|
|
@ -203,13 +188,13 @@ export default {
|
||||||
resultKey: 'serviceabilityDetails',
|
resultKey: 'serviceabilityDetails',
|
||||||
promise: serviceabilityDetailsPromise
|
promise: serviceabilityDetailsPromise
|
||||||
},
|
},
|
||||||
{
|
|
||||||
resultKey: 'shopQuestionInitialData',
|
|
||||||
promise: shopQuestionInitialDataPromise
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
resultKey: 'zipCodeData',
|
resultKey: 'zipCodeData',
|
||||||
promise: zipCodeData
|
promise: zipCodeData
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resultKey: 'providers',
|
||||||
|
promise: providersPromise
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -221,10 +206,9 @@ export default {
|
||||||
resultMap.zipCodeData,
|
resultMap.zipCodeData,
|
||||||
resultMap.serviceabilityDetails,
|
resultMap.serviceabilityDetails,
|
||||||
resultMap.mobileFeePart,
|
resultMap.mobileFeePart,
|
||||||
resultMap.shopQuestionInitialData?.mobileProviderNumber,
|
resultMap.glassFees,
|
||||||
resultMap.glassFees
|
resultMap.providers
|
||||||
);
|
);
|
||||||
vm.$refs[SHOP_QUESTION_REF_NAME].initializeComponent(resultMap.shopQuestionInitialData);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
|
@ -249,7 +233,6 @@ export default {
|
||||||
mobileProviderNumber: null,
|
mobileProviderNumber: null,
|
||||||
zipContainsMilitaryBase: false,
|
zipContainsMilitaryBase: false,
|
||||||
zipCodeCtu: null,
|
zipCodeCtu: null,
|
||||||
SHOP_QUESTION_REF_NAME,
|
|
||||||
RECAL_MODAL_REF_NAME,
|
RECAL_MODAL_REF_NAME,
|
||||||
SITE_FOOTER_REF_NAME
|
SITE_FOOTER_REF_NAME
|
||||||
};
|
};
|
||||||
|
|
@ -264,27 +247,6 @@ export default {
|
||||||
answersFromCms() {
|
answersFromCms() {
|
||||||
return this.getCmsContent('ServiceTypeQuestionWidget', 'Answers');
|
return this.getCmsContent('ServiceTypeQuestionWidget', 'Answers');
|
||||||
},
|
},
|
||||||
serviceZipCodeQuestion: {
|
|
||||||
get() {
|
|
||||||
return {
|
|
||||||
state: this.state,
|
|
||||||
zipCode: this.zipCode
|
|
||||||
};
|
|
||||||
},
|
|
||||||
set(newValue) {
|
|
||||||
if (newValue.zipCode !== this.zipCode) {
|
|
||||||
this.resetMobileLocation();
|
|
||||||
this.selectedAppointmentType = null;
|
|
||||||
this.selectedProvider = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.state = newValue.state;
|
|
||||||
this.zipCode = newValue.zipCode;
|
|
||||||
|
|
||||||
// eslint-disable-next-line vue/valid-next-tick
|
|
||||||
this.$nextTick();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mobileLocationQuestions: {
|
mobileLocationQuestions: {
|
||||||
get() {
|
get() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -307,12 +269,7 @@ export default {
|
||||||
this.isVehicleProtected = newValue.isVehicleProtected;
|
this.isVehicleProtected = newValue.isVehicleProtected;
|
||||||
|
|
||||||
if (newValue.zipCode !== this.zipCode) {
|
if (newValue.zipCode !== this.zipCode) {
|
||||||
if (
|
if (!this.isMobile) {
|
||||||
!(
|
|
||||||
this.selectedAppointmentType === AppointmentTypeStrings.MOBILE
|
|
||||||
|| this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
this.selectedAppointmentType = null;
|
this.selectedAppointmentType = null;
|
||||||
}
|
}
|
||||||
this.selectedProvider = null;
|
this.selectedProvider = null;
|
||||||
|
|
@ -338,7 +295,7 @@ export default {
|
||||||
|
|
||||||
return this.isGlassServiceableInshop;
|
return this.isGlassServiceableInshop;
|
||||||
},
|
},
|
||||||
isShopQuestionDisplayed() {
|
isInshop() {
|
||||||
return (
|
return (
|
||||||
this.selectedAppointmentType === 'Inshop'
|
this.selectedAppointmentType === 'Inshop'
|
||||||
|| this.selectedAppointmentType === 'Dropoff'
|
|| this.selectedAppointmentType === 'Dropoff'
|
||||||
|
|
@ -347,7 +304,7 @@ export default {
|
||||||
isAppointmentTypeDisplayed() {
|
isAppointmentTypeDisplayed() {
|
||||||
return this.zipCode && !this.displayNoShopsAlert;
|
return this.zipCode && !this.displayNoShopsAlert;
|
||||||
},
|
},
|
||||||
isMobileLocationDisplayed() {
|
isMobile() {
|
||||||
return (
|
return (
|
||||||
this.selectedAppointmentType
|
this.selectedAppointmentType
|
||||||
=== AppointmentTypeStrings.MOBILE
|
=== AppointmentTypeStrings.MOBILE
|
||||||
|
|
@ -401,9 +358,6 @@ export default {
|
||||||
useMainStore().order.serviceLocation.zipCode !== null
|
useMainStore().order.serviceLocation.zipCode !== null
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
async reloadShopData(zipCode) {
|
|
||||||
await this.$refs[SHOP_QUESTION_REF_NAME].reloadShopData(zipCode);
|
|
||||||
},
|
|
||||||
async forwardButtonAction() {
|
async forwardButtonAction() {
|
||||||
let provider = this.selectedProvider;
|
let provider = this.selectedProvider;
|
||||||
this.mainStore.updateMobileFee(null);
|
this.mainStore.updateMobileFee(null);
|
||||||
|
|
@ -482,8 +436,8 @@ export default {
|
||||||
zipCodeData,
|
zipCodeData,
|
||||||
serviceabilityDetails,
|
serviceabilityDetails,
|
||||||
mobileFeePart,
|
mobileFeePart,
|
||||||
mobileProviderNumber,
|
glassFees,
|
||||||
glassFees
|
providers
|
||||||
) {
|
) {
|
||||||
if (zipCodeData) {
|
if (zipCodeData) {
|
||||||
this.zipContainsMilitaryBase = zipCodeData.containsMilitaryBase;
|
this.zipContainsMilitaryBase = zipCodeData.containsMilitaryBase;
|
||||||
|
|
@ -498,8 +452,11 @@ export default {
|
||||||
this.mobileFeePart = mobileFeePart;
|
this.mobileFeePart = mobileFeePart;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mobileProviderNumber) {
|
if (providers) {
|
||||||
this.setMobileProviderNumber(mobileProviderNumber);
|
this.setMobileProviderNumber(providers.mobileProviderNumber);
|
||||||
|
if(providers.shopProviders.length > 0) {
|
||||||
|
this.selectedProvider = providers.shopProviders[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glassFees) {
|
if (glassFees) {
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import textLink from '@/ux-components/text-link/text-link.vue';
|
import textLink from '@/ux-components/text-link/text-link.vue';
|
||||||
import serviceZipQuestion from '@/layouts/service-location/service-zip-modal-question/service-zip-question/service-zip-question.vue';
|
import serviceZipQuestion from '@/layouts/service-location/service-zip-question/service-zip-question.vue';
|
||||||
import modal from '@/digital-components/modal/modal.vue';
|
import modal from '@/digital-components/modal/modal.vue';
|
||||||
import alert from '@/ux-components/alert/alert.vue';
|
import alert from '@/ux-components/alert/alert.vue';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import errorMessages from '@/constants/error-messages';
|
||||||
|
|
||||||
// Define Validation Rules
|
// Define Validation Rules
|
||||||
defineRule('zip-required', required(errorMessages.SERVICE_ZIP_REQUIRED));
|
defineRule('zip-required', required(errorMessages.SERVICE_ZIP_REQUIRED));
|
||||||
defineRule('zip-format', regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT));
|
defineRule('zip-format', regex(/^\d{5}$/, errorMessages.SERVICE_ZIP_FORMAT));
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'service-zip-question',
|
name: 'service-zip-question',
|
||||||
247
src/layouts/service-location/shop-address/shop-address.vue
Normal file
247
src/layouts/service-location/shop-address/shop-address.vue
Normal file
|
|
@ -0,0 +1,247 @@
|
||||||
|
<template>
|
||||||
|
<transition
|
||||||
|
name="fade"
|
||||||
|
mode="out-in">
|
||||||
|
<div
|
||||||
|
v-if="isDisplayed"
|
||||||
|
class="shop-address"
|
||||||
|
aria-live="polite">
|
||||||
|
<alert
|
||||||
|
v-if="displayDropoffInformation"
|
||||||
|
ref="alertDropoffInformation"
|
||||||
|
class="mb-4 drop-off-alert"
|
||||||
|
cmsWidgetName="AlertDropoffInformationWidget"
|
||||||
|
alertClass="alert-info"
|
||||||
|
:isDismissible="false" />
|
||||||
|
<div class="address-header">{{ questionText }}</div>
|
||||||
|
<div class="current-address">
|
||||||
|
<div class="address-line">
|
||||||
|
<span class="shop-name">{{ displayedShopName }}</span>
|
||||||
|
<span class="shop-distance">{{ modelValue.distanceInMiles.toFixed(2) }} mi</span>
|
||||||
|
</div>
|
||||||
|
<div class="address-line">{{ toTitleCase(modelValue.address.streetAddress) }}</div>
|
||||||
|
<div class="address-line">
|
||||||
|
{{ toTitleCase(modelValue.address.city) }}, {{ modelValue.address.state }} {{ modelValue.address.zipCode }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<buttonMain
|
||||||
|
:buttonText="showMoreShopsLinkText"
|
||||||
|
:variant="'primary'"
|
||||||
|
@clickEvent="openModal" />
|
||||||
|
<modal
|
||||||
|
:ref="modalName"
|
||||||
|
:headerText="modalHeaderText"
|
||||||
|
:onModalOpenedCallback="onModalOpened"
|
||||||
|
:onModalClosedCallback="onModalClosed"
|
||||||
|
:footerButtonText="modalFooterText"
|
||||||
|
@footerButtonEvent="updateSelectedProvider">
|
||||||
|
<buttonQuestion
|
||||||
|
ref="buttonQuestion"
|
||||||
|
v-model="internalProviderNumber"
|
||||||
|
buttonTypeString="shopListButton"
|
||||||
|
:buttonTypeObject="shopListButton"
|
||||||
|
class="radioQuestion"
|
||||||
|
:questionText="questionText"
|
||||||
|
:answers="nearbyShops"
|
||||||
|
groupName="chooseShop"
|
||||||
|
textPosition="text-start"
|
||||||
|
isRequired
|
||||||
|
validationRules="option-required"
|
||||||
|
:additionalButtonData="additionalButtonData" />
|
||||||
|
<serviceZipQuestion
|
||||||
|
ref="serviceZipCodeQuestion"
|
||||||
|
v-model="internalZipcode"
|
||||||
|
customInputId="serviceZipCode"
|
||||||
|
:cmsWidgetName="textboxQuestionWidgetName"
|
||||||
|
v-on="{ 'textboxQuestionEvent.inputIdAssigned': onInputIdAssigned }" />
|
||||||
|
<alert
|
||||||
|
v-if="displayInvalidZipAlert"
|
||||||
|
ref="alertInvalidZip"
|
||||||
|
class="my-4"
|
||||||
|
:cmsWidgetName="alertInvalidZipWidgetName"
|
||||||
|
alertClass="alert-danger"
|
||||||
|
:isDismissible="false" />
|
||||||
|
</modal>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Components
|
||||||
|
import alert from '@/ux-components/alert/alert.vue';
|
||||||
|
import buttonMain from '@/ux-components/button-main/button-main.vue';
|
||||||
|
import modal from '@/digital-components/modal/modal.vue';
|
||||||
|
import serviceZipQuestion from '@/layouts/service-location/service-zip-question/service-zip-question.vue';
|
||||||
|
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
|
||||||
|
import shopListButton from '@/iss-components/shop-list-button/shop-list-button.vue';
|
||||||
|
|
||||||
|
// Supporting files
|
||||||
|
import baseMixin from '@/mixins/base-mixin.js';
|
||||||
|
import { toTitleCase } from '@/helpers/text-helper.js';
|
||||||
|
import { markRaw, nextTick } from 'vue';
|
||||||
|
import { getServiceabilityDetails, getZipCodeData,getAvailabilityRating } from '@/helpers/service-location-helper';
|
||||||
|
import { useMainStore } from '@/store';
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'shop-address',
|
||||||
|
components: {
|
||||||
|
alert,
|
||||||
|
buttonMain,
|
||||||
|
modal,
|
||||||
|
serviceZipQuestion,
|
||||||
|
buttonQuestion
|
||||||
|
},
|
||||||
|
mixins: [baseMixin],
|
||||||
|
props: {
|
||||||
|
modelValue: {
|
||||||
|
type: Object,
|
||||||
|
default: () => null
|
||||||
|
},
|
||||||
|
cmsWidgetName: String,
|
||||||
|
validationRules: String,
|
||||||
|
isDisplayed: Boolean,
|
||||||
|
modalWidgetName: String,
|
||||||
|
selectedAppointmentType: String
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
toTitleCase,
|
||||||
|
serviceZipCodeTextInputId: '',
|
||||||
|
displayInvalidZipAlert: false,
|
||||||
|
internalZipcode: this.modelValue.address.zipCode,
|
||||||
|
internalProviderNumber: this.modelValue.providerNumber,
|
||||||
|
textboxQuestionWidgetName: 'ChangeLocationZipQuestionWidget',
|
||||||
|
alertInvalidZipWidgetName: 'AlertInvalidZipWidget',
|
||||||
|
shopListButton: markRaw(shopListButton),
|
||||||
|
searchRadiusInMiles: 25,
|
||||||
|
nearbyShops: this.getNearbyShops(25)
|
||||||
|
};
|
||||||
|
},
|
||||||
|
emits: ['update:modelValue'],
|
||||||
|
computed: {
|
||||||
|
questionText() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'QuestionText');
|
||||||
|
},
|
||||||
|
showMoreShopsLinkText() {
|
||||||
|
return this.getCmsContent('ShowMoreShopsLinkWidget', 'Text');
|
||||||
|
},
|
||||||
|
displayedShopName() {
|
||||||
|
if(this.modelValue.isSafeliteShop) {
|
||||||
|
return this.getCmsContent('SafeliteShopNameWidget', 'Text');
|
||||||
|
}
|
||||||
|
return toTitleCase(this.modelValue.companyName);
|
||||||
|
},
|
||||||
|
modalHeaderText() {
|
||||||
|
return this.getCmsContent(this.modalWidgetName, 'HeaderText').replaceAll('{custom:serviceZipcode}', this.internalZipcode);
|
||||||
|
},
|
||||||
|
modalFooterText() {
|
||||||
|
return this.getCmsContent(this.modalWidgetName, 'FooterText');
|
||||||
|
},
|
||||||
|
modalName() {
|
||||||
|
return this.modalWidgetName;
|
||||||
|
},
|
||||||
|
additionalButtonData() {
|
||||||
|
const startDate = new Date();
|
||||||
|
const endDate = new Date();
|
||||||
|
endDate.setDate(startDate.getDate() + 6);
|
||||||
|
|
||||||
|
const formattedStartDate = startDate.toISOString().split('T')[0];
|
||||||
|
const formattedEndDate = endDate.toISOString().split('T')[0];
|
||||||
|
|
||||||
|
return {
|
||||||
|
displayAvailabilityIndicators: true,
|
||||||
|
availabilityRatingCallback: getAvailabilityRating,
|
||||||
|
startDate: formattedStartDate,
|
||||||
|
endDate: formattedEndDate,
|
||||||
|
shopAppointmentType: this.selectedAppointmentType
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
internalZipcode(newZipcode) {
|
||||||
|
this.resetsOnZipInput();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
resetAlerts() {
|
||||||
|
this.displayInvalidZipAlert = false;
|
||||||
|
},
|
||||||
|
async resetsOnZipInput() {
|
||||||
|
this.resetAlerts();
|
||||||
|
this.nearbyShops = await this.getNearbyShops(this.searchRadiusInMiles);
|
||||||
|
},
|
||||||
|
focusOnZipInput() {
|
||||||
|
const input = document.getElementById(this.serviceZipCodeTextInputId);
|
||||||
|
input?.focus();
|
||||||
|
},
|
||||||
|
openModal() {
|
||||||
|
this.$refs[this.modalName].openModal();
|
||||||
|
},
|
||||||
|
closeModal() {
|
||||||
|
this.$refs[this.modalName].closeModal();
|
||||||
|
},
|
||||||
|
onInputIdAssigned(inputId) {
|
||||||
|
this.serviceZipCodeTextInputId = inputId;
|
||||||
|
},
|
||||||
|
onModalOpened() {
|
||||||
|
this.internalZipcode = this.modelValue.address.zipCode;
|
||||||
|
this.internalProviderNumber = this.modelValue.providerNumber;
|
||||||
|
this.focusOnZipInput();
|
||||||
|
},
|
||||||
|
onModalClosed() {
|
||||||
|
this.internalZipcode = this.modelValue.address.zipCode;
|
||||||
|
this.internalProviderNumber = this.modelValue.providerNumber;
|
||||||
|
this.resetsOnZipInput();
|
||||||
|
},
|
||||||
|
async updateSelectedProvider() {
|
||||||
|
// TODO: Do something with the zipcode?
|
||||||
|
},
|
||||||
|
async getNearbyShops(radiusInMiles) {
|
||||||
|
const result = await useMainStore().getProviders(this.internalZipcode, radiusInMiles);
|
||||||
|
|
||||||
|
const mappedData = result.data.shopProviders.map((shopProvider) => {
|
||||||
|
const streetAddress = toTitleCase(shopProvider.address.streetAddress);
|
||||||
|
const city = toTitleCase(shopProvider.address.city);
|
||||||
|
const { state } = shopProvider.address;
|
||||||
|
const { zipCode } = shopProvider.address;
|
||||||
|
const distanceInMiles = Math.round(shopProvider.distanceInMiles * 2) / 2;
|
||||||
|
|
||||||
|
return {
|
||||||
|
buttonLabel: city,
|
||||||
|
buttonLabelSubCopy: `${distanceInMiles} mi`,
|
||||||
|
buttonBodyCopy: `${streetAddress}, ${city}, ${state} ${zipCode}`,
|
||||||
|
value: shopProvider.providerNumber
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Internal provider number after getting shops:', this.internalProviderNumber);
|
||||||
|
|
||||||
|
return mappedData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "@/styles/ux-variables-svg-strings.scss";
|
||||||
|
.shop-address {
|
||||||
|
.address-header {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 0.625rem;
|
||||||
|
}
|
||||||
|
.address-line {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.shop-distance {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
.current-address {
|
||||||
|
margin: .625rem 0;
|
||||||
|
}
|
||||||
|
:deep(.modal-title) {
|
||||||
|
font-weight: 400;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1011,14 +1011,13 @@ export const useMainStore = defineStore({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getProviders(serviceZipCode) {
|
getProviders(serviceZipCode, shopRadiusInMiles = 100) {
|
||||||
const { carId, isBigTruck } = this.order.vehicle;
|
const { carId, isBigTruck } = this.order.vehicle;
|
||||||
const damageType = this.damage.isRepair ? 'Repair' : 'Replace';
|
const damageType = this.damage.isRepair ? 'Repair' : 'Replace';
|
||||||
const { parentAccountNumber } = this.order;
|
const { parentAccountNumber } = this.order;
|
||||||
const partsWithRecal = getTopLevelGlassPartsWithRecal(this.order.lineItems.glassParts);
|
const partsWithRecal = getTopLevelGlassPartsWithRecal(this.order.lineItems.glassParts);
|
||||||
const windshieldPartWithRecal = partsWithRecal?.length > 0 ? partsWithRecal[0] : null;
|
const windshieldPartWithRecal = partsWithRecal?.length > 0 ? partsWithRecal[0] : null;
|
||||||
const safeliteOnly = true;
|
const safeliteOnly = true;
|
||||||
const shopRadiusInMiles = 100;
|
|
||||||
|
|
||||||
let url = `${endpoints.GetProviders.url}/${serviceZipCode}/${damageType}/${shopRadiusInMiles}/${parentAccountNumber}/${safeliteOnly}/${carId}`;
|
let url = `${endpoints.GetProviders.url}/${serviceZipCode}/${damageType}/${shopRadiusInMiles}/${parentAccountNumber}/${safeliteOnly}/${carId}`;
|
||||||
if (windshieldPartWithRecal) {
|
if (windshieldPartWithRecal) {
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ $font-weight-lighter: lighter;
|
||||||
$font-weight-light: 300;
|
$font-weight-light: 300;
|
||||||
$font-weight-normal: 400;
|
$font-weight-normal: 400;
|
||||||
$font-weight-bold: 500;
|
$font-weight-bold: 500;
|
||||||
$font-weight-bolder: bolder;
|
$font-weight-bolder: 600;
|
||||||
|
|
||||||
|
|
||||||
//Border Radius
|
//Border Radius
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ export default {
|
||||||
color: $black;
|
color: $black;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
background: #e7f1f6;
|
background: #e7f1f6;
|
||||||
border-color: #0070d1;
|
border-color: $heritage-blue-primary;
|
||||||
}
|
}
|
||||||
&:checked + .list-button-content p,
|
&:checked + .list-button-content p,
|
||||||
&:checked + .list-button-content span {
|
&:checked + .list-button-content span {
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ export default {
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
a {
|
a {
|
||||||
color: #0070d1;
|
color: $heritage-blue-primary;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
line-height: 1.56;
|
line-height: 1.56;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue