Merge branch 'release/2025.07.10' into feature/CASH-845-stage-2

This commit is contained in:
AdamCaouetteSafelite 2025-07-08 16:27:36 -04:00
commit d4ed508c1f
6 changed files with 249 additions and 190 deletions

View file

@ -36,9 +36,13 @@
:id="modalId + '-modalbtn'" :id="modalId + '-modalbtn'"
ref="modalButtonMain" ref="modalButtonMain"
loaderColor="white" loaderColor="white"
:isDisabled="footerButtonDisabled"
:buttonText="footerButtonText" :buttonText="footerButtonText"
@click-event="validateAndEmit" @click-event="validateAndEmit"
:class="isFooterButtonDisabled && 'form-test-invalid'" /> :class="[
isFooterButtonDisabled && 'form-test-invalid',
{ 'form-test-invalid': footerButtonDisabled === true },
]" />
</div> </div>
</div> </div>
</div> </div>
@ -59,6 +63,7 @@ export default {
footerButtonText: String, footerButtonText: String,
suppressPageScroll: Boolean, suppressPageScroll: Boolean,
staticBackdrop: Boolean, staticBackdrop: Boolean,
footerButtonDisabled: Boolean,
onModalOpenedCallback: { onModalOpenedCallback: {
type: Function, type: Function,
}, },

View file

@ -4,6 +4,10 @@
<script> <script>
import analyticsMixin from "@/mixins/analytics-mixin"; import analyticsMixin from "@/mixins/analytics-mixin";
import store from "@/store";
import { routeData } from "@/router/constants/routes";
import { deepClone } from "@/helpers/object-helper";
export default { export default {
name: "sierraWebchat", name: "sierraWebchat",
mixins: [analyticsMixin], mixins: [analyticsMixin],
@ -24,7 +28,10 @@ export default {
}, },
createSierraConfig() { createSierraConfig() {
return { return {
variables: { application: "funnel" }, variables: {
application: "funnel",
...this.getSierraContext(),
},
display: "corner", display: "corner",
onLoad: () => this.openSierraChatModal(), onLoad: () => this.openSierraChatModal(),
onOpen: () => {}, onOpen: () => {},
@ -35,6 +42,39 @@ export default {
), ),
}; };
}, },
getSierraContext() {
const glassDamage = store.getters?.order?.damage?.glassToReplace;
const glassType =
glassDamage && glassDamage.length > 0
? glassDamage.length > 1
? "Multiglass"
: glassDamage[0].glassType // todo: clarify?
: "";
const damageType = store.getters.order?.damage?.isRepair ? "repair" : "replace";
const paymentType = store.getters.oreder?.payment?.isInsurance ? "insurance" : "cash";
const glassParts = store.getters.order?.lineItems?.glassParts;
const partId = glassParts && glassParts.length > 0 ? glassParts[0].partId : "";
const packageData = deepClone(store.getters?.pageData(routeData.QUOTE.name));
return {
current_page: this.pageName,
vehicle_year: store.getters.order?.vehicle?.year ?? "",
vehicle_make: store.getters.order?.vehicle?.make ?? "",
vehicle_model: store.getters.order?.vehicle?.model ?? "",
vehicle_style: store.getters.order?.vehicle?.style ?? "",
service_zip: store.getters.order?.serviceLocation?.serviceZip ?? "",
glass_type: glassType ?? "",
damage_type: damageType ?? "",
payment_type: paymentType ?? "",
quote: packageData ?? [],
part_id: partId ?? "",
recalibration: store.getters?.isRecalibrationOnOrder ?? "",
};
},
launchSierraChat() { launchSierraChat() {
window.sierraConfig = this.createSierraConfig(); window.sierraConfig = this.createSierraConfig();
// Preload CSS if not already present // Preload CSS if not already present

View file

@ -561,8 +561,12 @@ export default {
skipToInsurance: null, skipToInsurance: null,
}; };
}, },
mounted() { async mounted() {
this.attachCustomEventsForAnalytics(); this.attachCustomEventsForAnalytics();
await this.$nextTick();
this.$refs?.servicePackage?.savePackageInfoToPageData?.();
}, },
computed: { computed: {
lineItemsCloneForWatcher() { lineItemsCloneForWatcher() {

View file

@ -44,6 +44,7 @@ import {
import { containsRecalParts, getItemsWithoutRecalParts } from "@/helpers/recal-helper"; import { containsRecalParts, getItemsWithoutRecalParts } from "@/helpers/recal-helper";
import experimentMixin from "@/mixins/experiment-mixin.js"; import experimentMixin from "@/mixins/experiment-mixin.js";
import { experimentSettings } from "@/constants/experiments"; import { experimentSettings } from "@/constants/experiments";
import { savePageData } from "@/router/methods/helpers/save-page-data";
export default { export default {
name: "servicePackageQuestion", name: "servicePackageQuestion",
@ -434,6 +435,15 @@ export default {
return null; return null;
} }
}, },
async savePackageInfoToPageData() {
const answers = this.servicePackageAnswers;
const toLog = answers.map((ans) => ({
packageName: ans.buttonLabel,
price: ans.buttonAuxillaryCopy,
}));
await savePageData(this.pageName, toLog);
},
}, },
components: { components: {
buttonQuestion, buttonQuestion,

View file

@ -115,9 +115,9 @@
:selectedAppointmentType="selectedAppointmentType" :selectedAppointmentType="selectedAppointmentType"
:modelValue="{ :modelValue="{
zipCode: zipCode, zipCode: zipCode,
providerNumber: selectedProvider?.providerNumber, state: state,
}" }"
:preselectedProviderNumber="selectedProvider?.providerNumber" :preSelectedProviderNumber="selectedProvider?.providerNumber"
:shopProviderData="shopProviderData" :shopProviderData="shopProviderData"
:isServiceableInshop="isServiceableInshop" :isServiceableInshop="isServiceableInshop"
@updated-serviceability="setServiceabilityDetails" @updated-serviceability="setServiceabilityDetails"
@ -844,25 +844,10 @@ export default {
let provider = this.shopProviderData?.shopProviders?.find( let provider = this.shopProviderData?.shopProviders?.find(
(p) => p.providerNumber === providerObject?.providerNumber (p) => p.providerNumber === providerObject?.providerNumber
); );
if (!provider && this.shopProviderData?.shopProviders?.length > 0) {
provider = this.shopProviderData.shopProviders[0];
}
this.selectedProvider = provider; this.selectedProvider = provider;
if (provider && provider.address) {
this.zipCode = provider.address.zipCode;
this.state = provider.address.state;
}
if (
!this.selectedProvider ||
!this.shopProviderData?.shopProviders?.some(
(p) => p.providerNumber === this.selectedProvider?.providerNumber
)
) {
this.selectedProvider = this.shopProviderData?.shopProviders?.[0];
}
if (providerObject && providerObject.address) { if (providerObject && providerObject.address) {
this.zipCode = providerObject.address.zipCode; this.zipCode = providerObject.searchedZip;
this.state = providerObject.address.state; this.state = providerObject.searchedState;
} }
}, },
setZipcodeCtu(zipcodeCtu) { setZipcodeCtu(zipcodeCtu) {

View file

@ -1,18 +1,10 @@
<template> <template>
<transition name="fade" mode="out-in"> <transition name="fade" mode="out-in">
<div v-if="isDisplayed" class="shop-question" aria-live="polite"> <div v-if="isDisplayed" class="shop-question" aria-live="polite">
<alert
ref="alertDropoffInformation"
v-if="displayDropoffInformation"
class="mb-4 drop-off-alert"
cmsWidgetName="AlertDropoffInformationWidget"
alertClass="alert-info"
v-bind:isDismissible="false" />
<div class="modal-link"> <div class="modal-link">
<text-link <text-link
linkType="text" linkType="text"
:text="shopQuestionLinkText" :text="shopQuestionLinkText"
:shopProviderData="shopProviderData"
href="#!" href="#!"
@click-event="openModal"></text-link> @click-event="openModal"></text-link>
</div> </div>
@ -24,86 +16,60 @@
:onModalOpenedCallback="onModalOpened" :onModalOpenedCallback="onModalOpened"
:onModalClosedCallback="onModalClosed" :onModalClosedCallback="onModalClosed"
:footerButtonText="modalFooterText" :footerButtonText="modalFooterText"
@footer-button-event="SetZipCodeAndShop"> :footerButtonDisabled="
<div class="zip-search-group"> displayInvalidZipAlert || displayNoShopsAlert || !selectedProviderNumber
<div class="zip-search-input"> "
<serviceZipQuestion @footer-button-event="setZipCodeAndShop">
ref="serviceZipQuestion" <serviceZipQuestion
class="shop-question-zipcode" ref="serviceZipQuestion"
customInputId="serviceZipCode" class="shop-question-zipcode"
v-model="internalModel.zipCode" customInputId="serviceZipCode"
v-on="{ 'textboxQuestionEvent.inputIdAssigned': onInputIdAssigned }" v-model="internalModel.zipCode"
cmsWidgetName="ServiceZipQuestionWidget" v-on="{ 'textboxQuestionEvent.inputIdAssigned': onInputIdAssigned }"
@search-icon-click="onSearchZip" cmsWidgetName="ServiceZipQuestionWidget"
@keydown.enter="onSearchZip" @search-icon-click="onSearchZip"
includeSearchIcon @keydown.enter="onSearchZip"
:isRequired="false" /> includeSearchIcon
</div> :isRequired="false"
</div> :validationRules="''" />
<alert <alert
ref="alertMilitaryBaseZip" ref="alertInvalidZip"
class="my-5" v-if="displayInvalidZipAlert"
cmsWidgetName="AlertMilitaryBaseZipWidget" class="mb-4"
v-if="displayMilitaryZipAlert" cmsWidgetName="AlertInvalidZipWidget"
alertClass="alert-warning" /> alertClass="alert-danger"
v-bind:isDismissible="false" />
<alert
ref="alertMobileOnly"
class="my-5"
cmsWidgetName="AlertMobileOnlyWidget"
v-if="displayServiceableMobileOnly"
alertClass="alert-warning" />
<alert
ref="alertRecalNoMobile"
class="my-5"
cmsWidgetName="AlertRecalNoMobileWidget"
v-if="displayRecalibrationWarning"
@text-link-clicked="openModalAction"
alertClass="alert-warning" />
<alert
ref="alertInshopOnly"
class="my-5"
cmsWidgetName="AlertInshopOnlyWidget"
v-if="displayServiceableInshopOnly"
alertClass="alert-warning" />
<alert <alert
ref="alertNoShops" ref="alertNoShops"
class="my-5" class="my-5"
cmsWidgetName="AlertNoShopsWidget" cmsWidgetName="AlertNoShopsWidget"
v-if="displayNoShopsAlert" v-if="displayNoShopsAlert"
alertClass="alert-warning" /> alertClass="alert-warning" />
<alert <div v-if="!displayInvalidZipAlert">
ref="alertMobileFeeFree" <buttonQuestion
class="my-5" ref="buttonQuestion"
cmsWidgetName="AlertMobileFeeFreeWidget" buttonTypeString="shopListButton"
v-if="showMobileFreeAlert" :buttonTypeObject="shopListButton"
alertClass="alert-success" /> class="radioQuestion"
<buttonQuestion :questionText="questionText"
ref="buttonQuestion" :answers="answers"
buttonTypeString="shopListButton" groupName="chooseShop"
:buttonTypeObject="shopListButton" textPosition="text-start"
class="radioQuestion" v-model="selectedProviderNumber"
:questionText="questionText" isRequired
:answers="answers" :validationRules="this.selectedProviderNumber ? '' : 'option-required'" />
groupName="chooseShop" <div class="show-more-shops-link">
textPosition="text-start" <textLink
v-model="selectedProviderNumber" v-if="displaySeeMoreLocationsLink"
isRequired ref="showMoreShopsLink"
validationRules="option-required" /> id="showMoreShopsId2"
<div class="show-more-shops-link"> cmsWidgetName="ShowMoreShopsLinkWidget"
<textLink linkType="text"
v-if="displaySeeMoreLocationsLink" :text="showMoreShopsLinkText"
ref="showMoreShopsLink" href="#!"
id="showMoreShopsId2" @click-event="getNextShopsFromList(3)"
cmsWidgetName="ShowMoreShopsLinkWidget" :aria-label="showMoreShopsLinkText" />
linkType="text" </div>
:text="showMoreShopsLinkText"
href="#!"
@click-event="getNextShopsFromList(3)"
:aria-label="showMoreShopsLinkText" />
</div> </div>
</modal> </modal>
</template> </template>
@ -124,6 +90,7 @@ import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages"; import { errorMessages } from "@/constants/error-messages";
import baseMixin from "@/mixins/base-mixin.js"; import baseMixin from "@/mixins/base-mixin.js";
import { nextTick } from "vue"; import { nextTick } from "vue";
import { regex } from "@/helpers/validation-rules";
import { getAvailabilityRating } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper"; import { getAvailabilityRating } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
@ -141,13 +108,7 @@ import {
} from "@/layouts/service-location/helpers/service-location-helper/service-location-helper"; } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
defineRule("option-required", required(errorMessages.OPTION_REQUIRED)); defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
defineRule("zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT));
function getShopsByZip(zipCode, shops, numberToGet = 3) {
return shops
.filter((shop) => shop.address && shop.address.zipCode && shop.address.zipCode !== "")
.sort((a, b) => a.distanceInMiles - b.distanceInMiles)
.slice(0, numberToGet);
}
export default { export default {
name: "shop-question-popup", name: "shop-question-popup",
@ -167,6 +128,9 @@ export default {
lastSearchedZip: "", lastSearchedZip: "",
lastSuccessfulZip: "", lastSuccessfulZip: "",
hasLoadedShopData: false, hasLoadedShopData: false,
displayInvalidZipAlert: false,
areShopsAvialable: true,
displayNoShopsAlert: false,
}; };
}, },
props: { props: {
@ -193,7 +157,7 @@ export default {
default: "", default: "",
}, },
preSelectedProviderNumber: { preSelectedProviderNumber: {
type: [String, Number], type: String,
default: null, default: null,
}, },
}, },
@ -243,9 +207,6 @@ export default {
showMoreShopsLinkText() { showMoreShopsLinkText() {
return this.getCmsContent("ShowMoreShopsLinkWidget", "Text"); return this.getCmsContent("ShowMoreShopsLinkWidget", "Text");
}, },
displayNoShopsAlert() {
return this.hasLoadedShopData && this.answers.length === 0;
},
}, },
methods: { methods: {
openModal(event) { openModal(event) {
@ -369,20 +330,22 @@ export default {
this.shopIndex = 0; this.shopIndex = 0;
}, },
onModalOpened() { onModalOpened() {
this.shopIndex = 3; const preSelectedIndex = this.shopProviders.findIndex(
(provider) => provider.providerNumber == this.preSelectedProviderNumber
);
if (preSelectedIndex > -1) {
this.shopIndex = Math.ceil((preSelectedIndex + 1) / 3) * 3;
} else {
this.shopIndex = 3;
}
this.internalModel = this.copyModel(this.modelValue); this.internalModel = this.copyModel(this.modelValue);
this.internalModel.zipCode = this.zipCode; this.internalModel.zipCode = this.zipCode;
this.localShopProviderData = this.shopProviderData; this.localShopProviderData = this.shopProviderData;
this.answers = []; this.answers = [];
this.updateShopsForZip(this.internalModel.zipCode); this.onSearchZip();
this.focusOnZipInput(); this.focusOnZipInput();
this.selectedProviderNumber = this.preSelectedProviderNumber; this.selectedProviderNumber = this.preSelectedProviderNumber;
if (this.internalModel.zipCode && this.shopProviders.length > 0) {
this.updateShopsForZip(this.internalModel.zipCode);
} else {
this.internalModel.zipCode = this.zipCode;
this.updateShopsForZip(this.internalModel.zipCode);
}
if ( if (
(!this.selectedProviderNumber || (!this.selectedProviderNumber ||
!this.shopProviders.some( !this.shopProviders.some(
@ -398,14 +361,7 @@ export default {
}, },
onModalClosed() { onModalClosed() {
this.internalModel = this.copyModel(this.modelValue); this.internalModel = this.copyModel(this.modelValue);
this.selectedProviderNumber = this.preSelectedProviderNumber;
this.resetsOnZipInput(); this.resetsOnZipInput();
let selectedProvider = this.shopProviders.find(
(provider) => provider.providerNumber == this.selectedProviderNumber
);
if (!selectedProvider && this.shopProviders.length > 0) {
selectedProvider = this.shopProviders[0];
}
}, },
resetsOnZipInput() { resetsOnZipInput() {
this.resetAlerts(); this.resetAlerts();
@ -415,33 +371,49 @@ export default {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
} }
this.resetsOnZipInput();
this.displayNoShopsAlert = false;
const zip = this.internalModel.zipCode; const zip = this.internalModel.zipCode;
if (this.isVehicleHeavyTruck) { const zipCodeData = await this.getZipCodeData(
// check the location endpoint to verify this zip can service a heavy truck this.internalModel.zipCode,
const closestShops = await getClosestApplicableShops( "service-location"
this.internalModel.zipCode, );
this.carId, if (!zipCodeData.isValid) {
"service-location" this.displayInvalidZipAlert = true;
); //this.selectedProviderNumber = null;
this.focusOnZipInput();
if (!closestShops || closestShops.providers?.length === 0) { this.resetModalButtonStyle();
this.displayNoServiceAlert = true;
this.focusOnZipInput();
this.resetModalButtonStyle();
return null;
}
} else { } else {
getShopProviderData(zip).then(async (result) => { if (this.isVehicleHeavyTruck) {
this.localShopProviderData = result.data; // check the location endpoint to verify this zip can service a heavy truck
this.updateShopsForZip(this.internalModel.zipCode); const closestShops = await getClosestApplicableShops(
if (this.selectedAppointmentType === "Mobile") { this.internalModel.zipCode,
this.selectedProvider = new Provider( this.carId,
this.shopProviderData.mobileProviderNumber "service-location"
); );
} else {
this.selectedProvider = new Provider(); if (!closestShops || closestShops.providers?.length === 0) {
this.displayNoServiceAlert = true;
this.focusOnZipInput();
this.resetModalButtonStyle();
return null;
} }
}); } else {
getShopProviderData(zip).then(async (result) => {
if (this.displayNoShopsAlert === true) {
this.displayNoShopsAlert = false;
}
this.localShopProviderData = result.data;
this.updateShopsForZip(this.internalModel.zipCode);
if (this.selectedAppointmentType === "Mobile") {
this.selectedProvider = new Provider(
this.shopProviderData.mobileProviderNumber
);
} else {
this.selectedProvider = new Provider();
}
});
}
} }
}, },
async updateShopsForZip(zipCode) { async updateShopsForZip(zipCode) {
@ -458,11 +430,23 @@ export default {
} }
this.isLoadingShops = true; this.isLoadingShops = true;
if (!zipCode || !this.shopProviders.length) { if (!zipCode || !this.shopProviders.length) {
this.handleUpdate(); this.answers = [];
this.displayNoShopsAlert = true;
this.displaySeeMoreLocationsLink = false;
this.isLoadingShops = false;
return; return;
} }
const sortedShops = getShopsByZip(zipCode, this.shopProviders, 3); const selectedIndex = this.shopProviders.findIndex(
(provider) => provider.providerNumber == this.selectedProviderNumber
);
// If not found, only show the first 3 shops
if (selectedIndex === -1) {
this.shopIndex = 3;
}
const sortedShops = this.getShopsByZip(zipCode, this.shopProviders, this.shopIndex);
const toTitleCase = (str) => { const toTitleCase = (str) => {
return str.replace(/\w\S*/g, function (txt) { return str.replace(/\w\S*/g, function (txt) {
@ -498,12 +482,22 @@ export default {
}; };
}); });
this.answers = mappedData; this.answers = mappedData;
if (
this.selectedProviderNumber &&
!this.answers.some((a) => String(a.value) === String(this.selectedProviderNumber))
) {
this.selectedProviderNumber = null;
}
this.shopIndex = mappedData.length; this.shopIndex = mappedData.length;
this.displaySeeMoreLocationsLink = this.shopIndex < this.shopProviders.length; this.displaySeeMoreLocationsLink = this.shopIndex < this.shopProviders.length;
if (mappedData.length > 0) { if (mappedData.length > 0) {
this.lastSuccessfulZip = zipCode; this.lastSuccessfulZip = zipCode;
} }
this.isLoadingShops = false; this.isLoadingShops = false;
this.displayNoShopsAlert = this.answers.length === 0;
},
resetModalButtonStyle() {
this.modal.resetButtonStyle();
}, },
onInputIdAssigned(inputId) { onInputIdAssigned(inputId) {
this.serviceZipCodeTextInputId = inputId; this.serviceZipCodeTextInputId = inputId;
@ -515,17 +509,24 @@ export default {
resetAlerts() { resetAlerts() {
this.displayInvalidZipAlert = false; this.displayInvalidZipAlert = false;
this.displayNoServiceAlert = false; this.displayNoServiceAlert = false;
this.displayNoShopsAlert = false;
}, },
async SetZipCodeAndShop() { async setZipCodeAndShop() {
if (
this.displayInvalidZipAlert ||
this.displayNoShopsAlert ||
!this.selectedProviderNumber
) {
return;
}
const zipToEmit = this.lastSearchedZip;
const selectedProvider = this.shopProviders.find( const selectedProvider = this.shopProviders.find(
(provider) => provider.providerNumber == this.selectedProviderNumber (provider) => provider.providerNumber == this.selectedProviderNumber
); );
this.resetAlerts(); this.resetAlerts();
const zipCodeData = await this.getZipCodeData( const zipCodeData = await this.getZipCodeData(zipToEmit, "service-location");
selectedProvider.address.zipCode,
"service-location"
);
if (!zipCodeData.isValid) { if (!zipCodeData.isValid) {
this.displayInvalidZipAlert = true; this.displayInvalidZipAlert = true;
@ -548,7 +549,6 @@ export default {
} }
} }
selectedProvider.address.state = zipCodeData.state;
selectedProvider.address.zipCodeCtu = zipCodeData.zipCodeCtu; selectedProvider.address.zipCodeCtu = zipCodeData.zipCodeCtu;
// retrieve mobile fee part // retrieve mobile fee part
@ -585,11 +585,25 @@ export default {
this.$emit("update:modelValue", this.selectedValue); this.$emit("update:modelValue", this.selectedValue);
this.$emit("update-shop-provider-data", this.localShopProviderData); this.$emit("update-shop-provider-data", this.localShopProviderData);
this.$emit("shop-selected", selectedProvider); this.internalModel.state = zipCodeData.state;
this.$emit("shop-selected", {
providerNumber: selectedProvider?.providerNumber,
address: selectedProvider?.address,
searchedZip: zipToEmit,
searchedState: this.internalModel.state,
});
this.closeModal(); this.closeModal();
} }
}, },
getShopsByZip(zipCode, shops, numberToGet = 3) {
return shops
.filter(
(shop) => shop.address && shop.address.zipCode && shop.address.zipCode !== ""
)
.sort((a, b) => a.distanceInMiles - b.distanceInMiles)
.slice(0, numberToGet);
},
}, },
watch: { watch: {
shopProviderData: { shopProviderData: {
@ -597,14 +611,8 @@ export default {
handler(newVal) { handler(newVal) {
this.localShopProviderData = newVal; this.localShopProviderData = newVal;
this.hasLoadedShopData = true; this.hasLoadedShopData = true;
if (this.internalModel && this.internalModel.zipCode) {
this.updateShopsForZip(this.internalModel.zipCode);
}
}, },
}, },
preSelectedProviderNumber(newVal) {
this.selectedProviderNumber = newVal;
},
}, },
components: { components: {
modal, modal,
@ -613,9 +621,6 @@ export default {
buttonQuestion, buttonQuestion,
alert, alert,
}, },
mounted() {
this.handleUpdate();
},
}; };
</script> </script>
@ -658,7 +663,7 @@ export default {
.modal.modal-component .modal-dialog .modal-content .modal-body .textbox-question { .modal.modal-component .modal-dialog .modal-content .modal-body .textbox-question {
padding: 0; padding: 0;
} }
.zip-search-group { .shop-question-zipcode {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: stretch; align-items: stretch;
@ -673,44 +678,40 @@ export default {
height: auto; height: auto;
padding-left: 0; padding-left: 0;
} }
.zip-search-input { .input-wrapper.has-search-icon {
display: flex;
align-items: stretch; align-items: stretch;
flex: 1 1 0; flex: 1 1 0;
height: 100%; height: 100%;
margin-bottom: 0; margin-bottom: 0;
input { input,
.form-control {
width: 100%; width: 100%;
height: 100%; height: 48px;
min-height: 48px;
max-height: 48px;
border: none; border: none;
padding-top: 0; padding: 0 1.5rem 0 1.5rem;
padding-bottom: 0;
outline: none; outline: none;
font-size: 1rem; font-size: 1rem;
background: transparent; background: transparent;
box-sizing: border-box; box-sizing: border-box;
border-radius: 48px 0 0 48px; border-radius: 2.5rem 0 0 2.5rem;
padding-left: 0;
} }
} }
.btn { .search-icon-button {
display: flex; display: flex;
align-items: center; align-items: center;
background-color: #e5f1fa;
justify-content: center; justify-content: center;
width: 48px; background-color: #e5f1fa !important;
width: 2.5rem;
height: 48px; height: 48px;
border: none; border: none;
max-height: 48px;
border-radius: 0 48px 48px 0; border-radius: 0 2.5rem 2.5rem 0;
cursor: pointer; cursor: pointer;
} }
} }
@media (max-width: 767.98px) {
.zip-search-group {
padding-left: 0;
}
}
.show-more-shops-link a { .show-more-shops-link a {
text-align: center; text-align: center;
display: block; display: block;
@ -732,4 +733,18 @@ export default {
border-radius: 2.5rem; border-radius: 2.5rem;
padding-left: 1.5rem; padding-left: 1.5rem;
} }
.shop-question-zipcode .form-test-error {
display: block;
width: 100%;
margin-top: 0.25rem;
margin-left: 0;
color: #d32f2f; // or your error color
position: static !important;
font-size: 0.875rem;
clear: both;
float: none;
display: block;
width: 100%;
}
</style> </style>