Merge remote-tracking branch 'origin/develop' into rlsmerge/develop-to-2025.09.25
This commit is contained in:
commit
e77c328f1e
26 changed files with 734 additions and 68 deletions
|
|
@ -53,6 +53,7 @@ body select {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
font-family: Urbanist, Arial, Helvetica, sans-serif;
|
font-family: Urbanist, Arial, Helvetica, sans-serif;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
body input:focus, body input:focus-visible,
|
body input:focus, body input:focus-visible,
|
||||||
body select:focus,
|
body select:focus,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ body {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
font-family: Urbanist, Arial, Helvetica, sans-serif;
|
font-family: Urbanist, Arial, Helvetica, sans-serif;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.2);
|
||||||
&:focus,
|
&:focus,
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
box-shadow: 0 0 0 2.5px #1574a1;
|
box-shadow: 0 0 0 2.5px #1574a1;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ const damageLocationsSelected = {
|
||||||
PASSENGERSIDE: "PassengerSide",
|
PASSENGERSIDE: "PassengerSide",
|
||||||
STATIONARY: "Stationary",
|
STATIONARY: "Stationary",
|
||||||
SLIDER: "Slider",
|
SLIDER: "Slider",
|
||||||
|
DOOR: "Door",
|
||||||
|
GLASS: "Glass",
|
||||||
};
|
};
|
||||||
|
|
||||||
export { damageLocationsSelected };
|
export { damageLocationsSelected };
|
||||||
|
|
|
||||||
|
|
@ -268,6 +268,9 @@ export default {
|
||||||
button {
|
button {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border-radius: 50rem;
|
border-radius: 50rem;
|
||||||
|
&.btn-secondary {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -214,6 +214,47 @@ export default {
|
||||||
|
|
||||||
&.is-insurance {
|
&.is-insurance {
|
||||||
padding-bottom: 3rem;
|
padding-bottom: 3rem;
|
||||||
|
|
||||||
|
@include media-breakpoint-down(md) {
|
||||||
|
padding-bottom: 0.75rem;
|
||||||
|
.pricing-info {
|
||||||
|
top: 0.75rem;
|
||||||
|
right: 0.75rem;
|
||||||
|
bottom: auto;
|
||||||
|
left: auto;
|
||||||
|
width: auto;
|
||||||
|
margin: 0;
|
||||||
|
text-align: end;
|
||||||
|
max-width: 60%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 320px) {
|
||||||
|
min-height: 80px;
|
||||||
|
max-height: 120px;
|
||||||
|
|
||||||
|
.pricing-info {
|
||||||
|
top: 2.1rem;
|
||||||
|
right: auto;
|
||||||
|
left: 2.3rem;
|
||||||
|
bottom: auto;
|
||||||
|
position: absolute;
|
||||||
|
width: calc(100% - 2.5rem);
|
||||||
|
text-align: left;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.has-subheader {
|
||||||
|
@media (max-width: 320px) {
|
||||||
|
min-height: 100px;
|
||||||
|
max-height: 160px;
|
||||||
|
|
||||||
|
.pricing-info {
|
||||||
|
top: 3.9rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.has-subheader {
|
&.has-subheader {
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,15 @@ export default {
|
||||||
}
|
}
|
||||||
this.globalAlertMessages.push(alertToPush);
|
this.globalAlertMessages.push(alertToPush);
|
||||||
},
|
},
|
||||||
|
removeGlobalAlert(alertId) {
|
||||||
|
const alertIndex = this.globalAlertMessages.findIndex((alert) => alert.id === alertId);
|
||||||
|
if (alertIndex !== -1) {
|
||||||
|
this.globalAlertMessages.splice(alertIndex, 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getGlobalAlerts() {
|
||||||
|
return this.globalAlertMessages;
|
||||||
|
},
|
||||||
webchatClicked(event) {
|
webchatClicked(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.launchWebchat();
|
this.launchWebchat();
|
||||||
|
|
|
||||||
|
|
@ -82,3 +82,56 @@ export async function isGlassAvailableForCarId(carId, pageNameToLog) {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSideDoorGlassString(glassLocation, glassName) {
|
||||||
|
let glassNameString;
|
||||||
|
switch (glassName) {
|
||||||
|
case glassLocations.BACK:
|
||||||
|
glassNameString = glassLocations.REAR + " " + glassLocations.DOOR; // "Back Door"
|
||||||
|
break;
|
||||||
|
case glassLocations.FRONT:
|
||||||
|
glassNameString = glassName + " " + glassLocations.DOOR; // "Front Door"
|
||||||
|
break;
|
||||||
|
case glassLocations.VENT:
|
||||||
|
case glassLocations.QUARTER:
|
||||||
|
glassNameString = glassName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return glassLocation + " " + glassName + " " + glassLocations.GLASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDamageInfoWordingText(damageInfo) {
|
||||||
|
const glassTextArray = [];
|
||||||
|
|
||||||
|
damageInfo.glassToReplace.forEach((item) => {
|
||||||
|
let string = "";
|
||||||
|
if (item.glassLocation === glassLocations.WINDSHIELD) {
|
||||||
|
string = item.glassLocation;
|
||||||
|
}
|
||||||
|
if (item.glassLocation === glassLocations.REAR) {
|
||||||
|
string = glassLocations.BACK + " " + glassLocations.GLASS;
|
||||||
|
}
|
||||||
|
if (item.glassLocation === glassLocations.DRIVER) {
|
||||||
|
string = getSideDoorGlassString(item.glassLocation, item.glassName);
|
||||||
|
// ONLY INCLUDE "DOOR" IF IT'S REAR or FRONT (vent or quarter should NOT)
|
||||||
|
}
|
||||||
|
if (item.glassLocation === glassLocations.PASSENGER) {
|
||||||
|
string = getSideDoorGlassString(item.glassLocation, item.glassName);
|
||||||
|
}
|
||||||
|
glassTextArray.push(string);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (glassTextArray.length === 1) {
|
||||||
|
return glassTextArray[0];
|
||||||
|
}
|
||||||
|
let damageInfoWordingText = glassTextArray.join(", "); // string
|
||||||
|
let lastCommaIndex = damageInfoWordingText.lastIndexOf(", ");
|
||||||
|
if (lastCommaIndex > -1) {
|
||||||
|
return (
|
||||||
|
damageInfoWordingText.slice(0, lastCommaIndex) +
|
||||||
|
" and " +
|
||||||
|
damageInfoWordingText.slice(lastCommaIndex + 2, damageInfoWordingText.length)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -286,5 +286,6 @@ export default {
|
||||||
.select-option {
|
.select-option {
|
||||||
font-family: UrbanistSemibold, Arial, Helvetica, sans-serif;
|
font-family: UrbanistSemibold, Arial, Helvetica, sans-serif;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
color: $black;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -240,4 +240,7 @@ export default {
|
||||||
color: $gray-600;
|
color: $gray-600;
|
||||||
font-family: UrbanistRegular;
|
font-family: UrbanistRegular;
|
||||||
}
|
}
|
||||||
|
:deep(.caption) {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,8 @@ export default {
|
||||||
"payment-method"
|
"payment-method"
|
||||||
);
|
);
|
||||||
|
|
||||||
const reviewDropdownPromise = reviewDropdown.methods.loadInitialData();
|
// const reviewDropdownPromise = reviewDropdown.methods.loadInitialData();
|
||||||
|
// (removed temporarily for Heritage parity effort)
|
||||||
|
|
||||||
const promiseResultMap = [
|
const promiseResultMap = [
|
||||||
{
|
{
|
||||||
|
|
@ -238,10 +239,11 @@ export default {
|
||||||
resultKey: "rainDefense",
|
resultKey: "rainDefense",
|
||||||
promise: rainDefensePromise,
|
promise: rainDefensePromise,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
resultKey: "reviewDropdownData",
|
// resultKey: "reviewDropdownData",
|
||||||
promise: reviewDropdownPromise,
|
// promise: reviewDropdownPromise,
|
||||||
},
|
// },
|
||||||
|
// (removed temporarily for Heritage parity effort)
|
||||||
];
|
];
|
||||||
|
|
||||||
const resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
@ -346,7 +348,8 @@ export default {
|
||||||
);
|
);
|
||||||
vm.updateFooterButtonText(vm.customCtaCopy);
|
vm.updateFooterButtonText(vm.customCtaCopy);
|
||||||
|
|
||||||
vm.$refs.reviewDropdown.initializeComponent(resultMap.reviewDropdownData);
|
// vm.$refs.reviewDropdown.initializeComponent(resultMap.reviewDropdownData);
|
||||||
|
// (removed temporarily for Heritage parity effort)
|
||||||
|
|
||||||
if (revalidatePromoResponse) {
|
if (revalidatePromoResponse) {
|
||||||
const revalidateAlerts = buildToastMessagesFromRevalidateOrValidatePromoResponse(
|
const revalidateAlerts = buildToastMessagesFromRevalidateOrValidatePromoResponse(
|
||||||
|
|
@ -847,6 +850,18 @@ export default {
|
||||||
(newPromo) => !oldPromoCodes.includes(newPromo.promoCode)
|
(newPromo) => !oldPromoCodes.includes(newPromo.promoCode)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Remove any existing promo error alerts for this promo code
|
||||||
|
const existingAlerts = this.$refs.funnelHeader.getGlobalAlerts();
|
||||||
|
if (existingAlerts.length > 0) {
|
||||||
|
const errorPromoAlertToRemove = existingAlerts.find(
|
||||||
|
(alert) =>
|
||||||
|
alert.messageHeadline === "Promo code error" &&
|
||||||
|
alert.messageCopy.includes(newlyActivatedPromoCodes[0].promoCode)
|
||||||
|
);
|
||||||
|
errorPromoAlertToRemove &&
|
||||||
|
this.$refs.funnelHeader.removeGlobalAlert(errorPromoAlertToRemove.id);
|
||||||
|
}
|
||||||
|
|
||||||
const alert = createPromoSuccessAlert(newlyActivatedPromoCodes[0].promoCode);
|
const alert = createPromoSuccessAlert(newlyActivatedPromoCodes[0].promoCode);
|
||||||
this.$refs.funnelHeader.pushGlobalAlert(alert, alert.shouldAutoFade);
|
this.$refs.funnelHeader.pushGlobalAlert(alert, alert.shouldAutoFade);
|
||||||
} else if (
|
} else if (
|
||||||
|
|
@ -892,6 +907,9 @@ export default {
|
||||||
text-transform: lowercase;
|
text-transform: lowercase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
:deep(.review-table p) {
|
||||||
|
margin: 0.25rem 0 0 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.checkbox-group {
|
.checkbox-group {
|
||||||
align-items: start;
|
align-items: start;
|
||||||
|
|
|
||||||
|
|
@ -15,30 +15,27 @@
|
||||||
<div v-html="apptWordingText" v-show="!isExpanded"></div>
|
<div v-html="apptWordingText" v-show="!isExpanded"></div>
|
||||||
|
|
||||||
<div class="review-table px-4">
|
<div class="review-table px-4">
|
||||||
<serviceLocationReview
|
<appointmentReview
|
||||||
class="service-location"
|
class="service-location"
|
||||||
cmsWidgetName="ServiceLocationTitleWidget"
|
cmsWidgetName="AppointmentWidget"
|
||||||
:serviceLocation="serviceLocationInfo" />
|
:apptWordingText="apptWordingText" />
|
||||||
|
|
||||||
<hr class="my-0" />
|
<hr class="my-0" />
|
||||||
|
|
||||||
<scheduleReview cmsWidgetName="ScheduleWidget" :appointmentType="appointmentType" />
|
<parityDamageReview
|
||||||
|
|
||||||
<hr class="my-0" />
|
|
||||||
|
|
||||||
<vehicleReview cmsWidgetName="VehicleReviewWidget" :vehicle="vehicleInfo" />
|
|
||||||
|
|
||||||
<hr class="my-0" />
|
|
||||||
|
|
||||||
<damageReview
|
|
||||||
cmsWidgetName="DamageReviewWidget"
|
cmsWidgetName="DamageReviewWidget"
|
||||||
damageLocationsWidgetName="DamageLocationsWidget"
|
damageLocationsWidgetName="DamageLocationsWidget"
|
||||||
:damage="damageInfo" />
|
:damage="damageInfo"
|
||||||
|
:vehicle="vehicleInfo" />
|
||||||
|
|
||||||
<hr class="my-0" />
|
<hr class="my-0" />
|
||||||
|
|
||||||
<customerReview cmsWidgetName="CustomerReviewWidget" :customer="customerInfo" />
|
<customerReview cmsWidgetName="CustomerReviewWidget" :customer="customerInfo" />
|
||||||
|
|
||||||
|
<hr class="my-0" />
|
||||||
|
|
||||||
|
<optInReview cmsWidgetName="OptInReviewWidget" :customer="customerInfo" />
|
||||||
|
|
||||||
<!-- the following was the order prior to Heritage parity
|
<!-- the following was the order prior to Heritage parity
|
||||||
<vehicleReview cmsWidgetName="VehicleReviewWidget" :vehicle="vehicleInfo" />
|
<vehicleReview cmsWidgetName="VehicleReviewWidget" :vehicle="vehicleInfo" />
|
||||||
|
|
||||||
|
|
@ -82,8 +79,11 @@
|
||||||
import textBlock from "@/digital-components/text-block/text-block";
|
import textBlock from "@/digital-components/text-block/text-block";
|
||||||
|
|
||||||
import customerReview from "@/layouts/payment-method/review-dropdown/review-sections/customer-review/customer-review";
|
import customerReview from "@/layouts/payment-method/review-dropdown/review-sections/customer-review/customer-review";
|
||||||
|
import optInReview from "@/layouts/payment-method/review-dropdown/review-sections/opt-in-review/opt-in-review";
|
||||||
import damageReview from "@/layouts/payment-method/review-dropdown/review-sections/damage-review/damage-review";
|
import damageReview from "@/layouts/payment-method/review-dropdown/review-sections/damage-review/damage-review";
|
||||||
|
import parityDamageReview from "@/layouts/payment-method/review-dropdown/review-sections/parity-damage-review/parity-damage-review";
|
||||||
import scheduleReview from "@/layouts/payment-method/review-dropdown/review-sections/schedule-review/schedule-review";
|
import scheduleReview from "@/layouts/payment-method/review-dropdown/review-sections/schedule-review/schedule-review";
|
||||||
|
import appointmentReview from "@/layouts/payment-method/review-dropdown/review-sections/appointment-review/appointment-review";
|
||||||
import serviceLocationReview from "@/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review";
|
import serviceLocationReview from "@/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review";
|
||||||
import servicePackageReview from "@/layouts/payment-method/review-dropdown/review-sections/service-package-review/service-package-review";
|
import servicePackageReview from "@/layouts/payment-method/review-dropdown/review-sections/service-package-review/service-package-review";
|
||||||
import vehicleReview from "@/layouts/payment-method/review-dropdown/review-sections/vehicle-review/vehicle-review";
|
import vehicleReview from "@/layouts/payment-method/review-dropdown/review-sections/vehicle-review/vehicle-review";
|
||||||
|
|
@ -95,6 +95,7 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
apptWordingText: String,
|
apptWordingText: String,
|
||||||
serviceLocationFullAddress: String,
|
serviceLocationFullAddress: String,
|
||||||
|
damageInfoHeader: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -102,21 +103,22 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async loadInitialData() {
|
// the following was used prior to Heritage parity
|
||||||
const servicePackageInitialDataPromise = servicePackageReview.methods.loadInitialData();
|
// async loadInitialData() {
|
||||||
|
// const servicePackageInitialDataPromise = servicePackageReview.methods.loadInitialData();
|
||||||
|
|
||||||
const promiseResultMap = [
|
// const promiseResultMap = [
|
||||||
{
|
// {
|
||||||
resultKey: "servicePackageData",
|
// resultKey: "servicePackageData",
|
||||||
promise: servicePackageInitialDataPromise,
|
// promise: servicePackageInitialDataPromise,
|
||||||
},
|
// },
|
||||||
];
|
// ];
|
||||||
|
|
||||||
return settleAllPromises(promiseResultMap);
|
// return settleAllPromises(promiseResultMap);
|
||||||
},
|
// },
|
||||||
initializeComponent(apiResponses) {
|
// initializeComponent(apiResponses) {
|
||||||
this.$refs.servicePackageReview.initializeComponent(apiResponses.servicePackageData);
|
// this.$refs.servicePackageReview.initializeComponent(apiResponses.servicePackageData);
|
||||||
},
|
// },
|
||||||
toggleIsExpanded() {
|
toggleIsExpanded() {
|
||||||
this.isExpanded = !this.isExpanded;
|
this.isExpanded = !this.isExpanded;
|
||||||
},
|
},
|
||||||
|
|
@ -143,10 +145,9 @@ export default {
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
customerReview,
|
customerReview,
|
||||||
damageReview,
|
optInReview,
|
||||||
scheduleReview,
|
appointmentReview,
|
||||||
vehicleReview,
|
parityDamageReview,
|
||||||
serviceLocationReview,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -163,6 +164,10 @@ export default {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
|
||||||
|
& > :first-child {
|
||||||
|
margin-top: -0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.service-location) {
|
:deep(.service-location) {
|
||||||
.review-block-content {
|
.review-block-content {
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
|
||||||
|
import appointmentReview from "@/layouts/payment-method/review-dropdown/review-sections/appointment-review/appointment-review";
|
||||||
|
|
||||||
|
const testConstants = {
|
||||||
|
cms: {
|
||||||
|
header: {
|
||||||
|
text: "Appointment Details",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
appointment: {
|
||||||
|
apptWordingText:
|
||||||
|
"September 10, 2025 arriving between 9:00 AM — 11:00 AM at 123 Main St, anytown, OH 43215",
|
||||||
|
},
|
||||||
|
displayContent: {
|
||||||
|
apptWordingText:
|
||||||
|
"September 10, 2025 arriving between 9:00 AM — 11:00 AM at 123 Main St, anytown, OH 43215",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let cmsContent;
|
||||||
|
|
||||||
|
describe("Appointment Review Block", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cmsContent = {
|
||||||
|
AppointmentWidget: {
|
||||||
|
HeaderText: testConstants.cms.header.text,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should display header text from cms", async () => {
|
||||||
|
// Arrange
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.headerText).toEqual(testConstants.cms.header.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should render correct display content", async () => {
|
||||||
|
// Arrange
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.displayContent).toEqual([testConstants.displayContent.apptWordingText]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should emit edit-clicked when editClicked method is called", async () => {
|
||||||
|
// Arrange
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
wrapper.vm.editClicked();
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.emitted("edit-clicked")).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function generateDefaultProps() {
|
||||||
|
return {
|
||||||
|
cmsWidgetName: "AppointmentWidget",
|
||||||
|
apptWordingText: testConstants.appointment.apptWordingText,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupMocks(customMountOptions) {
|
||||||
|
const mountOptions = getMountOptions(customMountOptions);
|
||||||
|
|
||||||
|
const mockMixin = {
|
||||||
|
methods: {
|
||||||
|
getCmsContent: jest.fn((widgetName, cmsFieldName) => {
|
||||||
|
return cmsContent?.[widgetName]?.[cmsFieldName] ?? "";
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
mountOptions.global.mixins = [mockMixin];
|
||||||
|
|
||||||
|
const wrapper = shallowMount(appointmentReview, mountOptions);
|
||||||
|
wrapper.vm.setCmsContent = jest.fn();
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
<template>
|
||||||
|
<reviewBlock
|
||||||
|
:customHeaderText="headerText"
|
||||||
|
:content="displayContent"
|
||||||
|
@edit-clicked="editClicked" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import reviewBlock from "@/layouts/payment-method/review-dropdown/review-block/review-block";
|
||||||
|
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "appointment-review",
|
||||||
|
props: {
|
||||||
|
cmsWidgetName: String,
|
||||||
|
apptWordingText: String,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
editClicked() {
|
||||||
|
this.$emit("edit-clicked");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
displayContent() {
|
||||||
|
return [this.apptWordingText];
|
||||||
|
},
|
||||||
|
headerText() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, "HeaderText");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
reviewBlock,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -13,17 +13,17 @@ const testConstants = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
customer: {
|
customer: {
|
||||||
firstName: "First",
|
// firstName: "First",
|
||||||
lastName: "Last",
|
// lastName: "Last",
|
||||||
phoneNumber: "111-111-1111",
|
phoneNumber: "111-111-1111",
|
||||||
emailAddress: "builddigitaltest@safelite.com",
|
emailAddress: "builddigitaltest@safelite.com",
|
||||||
isSmsOptIn: false,
|
// isSmsOptIn: false,
|
||||||
},
|
},
|
||||||
displayContent: {
|
displayContent: {
|
||||||
fullName: "First Last",
|
// fullName: "First Last",
|
||||||
phoneNumber: "111-111-1111",
|
phoneNumber: "111-111-1111",
|
||||||
emailAddress: "builddigitaltest@safelite.com",
|
emailAddress: "builddigitaltest@safelite.com",
|
||||||
smsOptIn: "Sms",
|
// smsOptIn: "Sms",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -54,20 +54,20 @@ describe("Customer Review Block", () => {
|
||||||
expect(wrapper.vm.header).toEqual(testConstants.cms.header.text);
|
expect(wrapper.vm.header).toEqual(testConstants.cms.header.text);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Should display sms text from cms", async () => {
|
// test("Should display sms text from cms", async () => {
|
||||||
// Arrange
|
// // Arrange
|
||||||
let props = generateDefaultProps();
|
// let props = generateDefaultProps();
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
// const { wrapper } = setupMocks({
|
||||||
propsData: props,
|
// propsData: props,
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Act
|
// // Act
|
||||||
await wrapper.vm.$nextTick();
|
// await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
// Assert
|
// // Assert
|
||||||
expect(wrapper.vm.smsOptIn).toEqual(testConstants.cms.sms.text);
|
// expect(wrapper.vm.smsOptIn).toEqual(testConstants.cms.sms.text);
|
||||||
});
|
// });
|
||||||
|
|
||||||
test("Should render correct display content", async () => {
|
test("Should render correct display content", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
|
|
@ -84,7 +84,7 @@ describe("Customer Review Block", () => {
|
||||||
expect(wrapper.vm.displayContent).toEqual([
|
expect(wrapper.vm.displayContent).toEqual([
|
||||||
testConstants.displayContent.emailAddress,
|
testConstants.displayContent.emailAddress,
|
||||||
testConstants.displayContent.phoneNumber,
|
testConstants.displayContent.phoneNumber,
|
||||||
testConstants.displayContent.smsOptIn,
|
// testConstants.displayContent.smsOptIn,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -93,11 +93,11 @@ function generateDefaultProps() {
|
||||||
return {
|
return {
|
||||||
cmsWidgetName: "CustomerWidget",
|
cmsWidgetName: "CustomerWidget",
|
||||||
customer: {
|
customer: {
|
||||||
firstName: testConstants.customer.firstName,
|
// firstName: testConstants.customer.firstName,
|
||||||
lastName: testConstants.customer.lastName,
|
// lastName: testConstants.customer.lastName,
|
||||||
phoneNumber: testConstants.customer.phoneNumber,
|
phoneNumber: testConstants.customer.phoneNumber,
|
||||||
emailAddress: testConstants.customer.emailAddress,
|
emailAddress: testConstants.customer.emailAddress,
|
||||||
isSmsOptIn: testConstants.customer.isSmsOptIn,
|
// isSmsOptIn: testConstants.customer.isSmsOptIn,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
displayContent() {
|
displayContent() {
|
||||||
return [this.email, this.phoneNumber, this.smsOptIn];
|
return [this.email, this.phoneNumber];
|
||||||
// return [this.fullName, this.email, this.phoneNumber, this.smsOptIn]; // prior to Heritage parity
|
// return [this.fullName, this.email, this.phoneNumber, this.smsOptIn]; // prior to Heritage parity
|
||||||
},
|
},
|
||||||
header() {
|
header() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
|
||||||
|
import optInReview from "@/layouts/payment-method/review-dropdown/review-sections/opt-in-review/opt-in-review";
|
||||||
|
|
||||||
|
const testConstants = {
|
||||||
|
cms: {
|
||||||
|
header: {
|
||||||
|
text: "Text Message Updates",
|
||||||
|
},
|
||||||
|
bodyText: {
|
||||||
|
text: "We'll send appointment updates to {custom:SMSNUMBER}",
|
||||||
|
},
|
||||||
|
processedBodyText: {
|
||||||
|
text: "We'll send appointment updates to 111-111-1111",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
customer: {
|
||||||
|
phoneNumber: "111-111-1111",
|
||||||
|
},
|
||||||
|
displayContent: {
|
||||||
|
processedBodyText: "We'll send appointment updates to 111-111-1111",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let cmsContent;
|
||||||
|
|
||||||
|
describe("Opt-In Review Block", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cmsContent = {
|
||||||
|
OptInWidget: {
|
||||||
|
HeaderText: testConstants.cms.header.text,
|
||||||
|
BodyText: testConstants.cms.bodyText.text,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should display header text from cms", async () => {
|
||||||
|
// Arrange
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.header).toEqual(testConstants.cms.header.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should render correct display content with phone number replacement", async () => {
|
||||||
|
// Arrange
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.displayContent).toEqual([testConstants.displayContent.processedBodyText]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should return customer phone number", async () => {
|
||||||
|
// Arrange
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.phoneNumber).toEqual(testConstants.customer.phoneNumber);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should emit edit-clicked when editClicked method is called", async () => {
|
||||||
|
// Arrange
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
wrapper.vm.editClicked();
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.emitted("edit-clicked")).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should handle missing customer gracefully", async () => {
|
||||||
|
// Arrange
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
props.customer = null;
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.phoneNumber).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function generateDefaultProps() {
|
||||||
|
return {
|
||||||
|
cmsWidgetName: "OptInWidget",
|
||||||
|
customer: {
|
||||||
|
phoneNumber: testConstants.customer.phoneNumber,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupMocks(customMountOptions) {
|
||||||
|
const mountOptions = getMountOptions(customMountOptions);
|
||||||
|
|
||||||
|
const mockMixin = {
|
||||||
|
methods: {
|
||||||
|
getCmsContent: jest.fn((widgetName, cmsFieldName) => {
|
||||||
|
return cmsContent?.[widgetName]?.[cmsFieldName] ?? "";
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
mountOptions.global.mixins = [mockMixin];
|
||||||
|
|
||||||
|
const wrapper = shallowMount(optInReview, mountOptions);
|
||||||
|
wrapper.vm.setCmsContent = jest.fn();
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
<template>
|
||||||
|
<reviewBlock :customHeaderText="header" :content="displayContent" @edit-clicked="editClicked" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import reviewBlock from "@/layouts/payment-method/review-dropdown/review-block/review-block";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "opt-in-review",
|
||||||
|
props: {
|
||||||
|
cmsWidgetName: String,
|
||||||
|
customer: Object,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
editClicked() {
|
||||||
|
this.$emit("edit-clicked");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
displayContent() {
|
||||||
|
return [
|
||||||
|
this.getCmsContent(this.cmsWidgetName, "BodyText")?.replaceAll(
|
||||||
|
"{custom:SMSNUMBER}",
|
||||||
|
this.phoneNumber
|
||||||
|
),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
header() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, "HeaderText");
|
||||||
|
},
|
||||||
|
phoneNumber() {
|
||||||
|
return this.customer?.phoneNumber;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
reviewBlock,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import { getDamageInfoWordingText } from "@/helpers/damage-helper";
|
||||||
|
|
||||||
|
import parityDamageReview from "@/layouts/payment-method/review-dropdown/review-sections/parity-damage-review/parity-damage-review";
|
||||||
|
|
||||||
|
// Mock the damage helper
|
||||||
|
jest.mock("@/helpers/damage-helper", () => ({
|
||||||
|
getDamageInfoWordingText: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const testConstants = {
|
||||||
|
cms: {
|
||||||
|
damageInfoHeader: {
|
||||||
|
text: "We'll replace your {custom:GLASSPARTS}",
|
||||||
|
},
|
||||||
|
processedHeader: {
|
||||||
|
text: "We'll replace your windshield and passenger side window",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
vehicle: {
|
||||||
|
year: "2020",
|
||||||
|
make: "Honda",
|
||||||
|
model: "Civic",
|
||||||
|
},
|
||||||
|
damage: {
|
||||||
|
glassType: "windshield",
|
||||||
|
location: "passenger",
|
||||||
|
},
|
||||||
|
damageInfoWordingText: "windshield and passenger side window",
|
||||||
|
displayContent: {
|
||||||
|
vehicleInfo: "2020 Honda Civic",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let cmsContent;
|
||||||
|
|
||||||
|
describe("Parity Damage Review Block", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cmsContent = {
|
||||||
|
DamageInfoHeaderWidget: {
|
||||||
|
Text: testConstants.cms.damageInfoHeader.text,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mock the damage helper function
|
||||||
|
getDamageInfoWordingText.mockReturnValue(testConstants.damageInfoWordingText);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should display processed damage info header text with custom replacement", async () => {
|
||||||
|
// Arrange
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.damageInfoHeader).toEqual(testConstants.cms.processedHeader.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should render correct display content with vehicle information", async () => {
|
||||||
|
// Arrange
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.displayContent).toEqual([testConstants.displayContent.vehicleInfo]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should call getDamageInfoWordingText with damage prop", async () => {
|
||||||
|
// Arrange
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
const result = wrapper.vm.damageInfoWordingText;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(getDamageInfoWordingText).toHaveBeenCalledWith(testConstants.damage);
|
||||||
|
expect(result).toEqual(testConstants.damageInfoWordingText);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should emit edit-clicked when editClicked method is called", async () => {
|
||||||
|
// Arrange
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
wrapper.vm.editClicked();
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.emitted("edit-clicked")).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function generateDefaultProps() {
|
||||||
|
return {
|
||||||
|
cmsWidgetName: "DamageReviewWidget",
|
||||||
|
vehicle: {
|
||||||
|
year: testConstants.vehicle.year,
|
||||||
|
make: testConstants.vehicle.make,
|
||||||
|
model: testConstants.vehicle.model,
|
||||||
|
},
|
||||||
|
damage: {
|
||||||
|
glassType: testConstants.damage.glassType,
|
||||||
|
location: testConstants.damage.location,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupMocks(customMountOptions) {
|
||||||
|
const mountOptions = getMountOptions(customMountOptions);
|
||||||
|
|
||||||
|
const mockMixin = {
|
||||||
|
methods: {
|
||||||
|
getCmsContent: jest.fn((widgetName, cmsFieldName) => {
|
||||||
|
return cmsContent?.[widgetName]?.[cmsFieldName] ?? "";
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
mountOptions.global.mixins = [mockMixin];
|
||||||
|
|
||||||
|
const wrapper = shallowMount(parityDamageReview, mountOptions);
|
||||||
|
wrapper.vm.setCmsContent = jest.fn();
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
<template>
|
||||||
|
<reviewBlock
|
||||||
|
:headerCmsWidgetName="cmsWidgetName"
|
||||||
|
:content="displayContent"
|
||||||
|
:customHeaderText="damageInfoHeader"
|
||||||
|
@edit-clicked="editClicked" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import reviewBlock from "@/layouts/payment-method/review-dropdown/review-block/review-block";
|
||||||
|
import { getDamageInfoWordingText } from "@/helpers/damage-helper";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "vehicle-review",
|
||||||
|
props: {
|
||||||
|
cmsWidgetName: String,
|
||||||
|
vehicle: Object,
|
||||||
|
damage: Object,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
editClicked() {
|
||||||
|
this.$emit("edit-clicked");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
displayContent() {
|
||||||
|
return [`${this.vehicle.year} ${this.vehicle.make} ${this.vehicle.model}`];
|
||||||
|
},
|
||||||
|
damageInfoWordingText() {
|
||||||
|
return getDamageInfoWordingText(this.damage);
|
||||||
|
},
|
||||||
|
damageInfoHeader() {
|
||||||
|
return this.getCmsContent("DamageInfoHeaderWidget", "Text")?.replaceAll(
|
||||||
|
"{custom:GLASSPARTS}",
|
||||||
|
this.damageInfoWordingText
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
reviewBlock,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -20,8 +20,8 @@
|
||||||
<span v-else>{{ getInlineAltText(token) }}</span>
|
<span v-else>{{ getInlineAltText(token) }}</span>
|
||||||
</span>
|
</span>
|
||||||
<span v-else v-html="token"></span>
|
<span v-else v-html="token"></span>
|
||||||
|
<span class="nbsp"> </span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
id="afterpay-learnmore"
|
id="afterpay-learnmore"
|
||||||
href="#"
|
href="#"
|
||||||
|
|
@ -139,7 +139,7 @@ export default {
|
||||||
line-height: 2rem;
|
line-height: 2rem;
|
||||||
@include media-breakpoint-down(md) {
|
@include media-breakpoint-down(md) {
|
||||||
border-bottom: 1px solid;
|
border-bottom: 1px solid;
|
||||||
padding-bottom: 1rem;
|
padding-bottom: 0.5rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
|
|
@ -170,4 +170,8 @@ export default {
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#afterpay-learnmore {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@
|
||||||
alertClass="alert-info" />
|
alertClass="alert-info" />
|
||||||
|
|
||||||
<promoModalQuestion
|
<promoModalQuestion
|
||||||
class="mt-6 d-flex"
|
class="mt-4 d-flex"
|
||||||
v-model="lineItems"
|
v-model="lineItems"
|
||||||
:addableVaps="addableVaps"
|
:addableVaps="addableVaps"
|
||||||
pageName="quote"
|
pageName="quote"
|
||||||
|
|
@ -904,9 +904,12 @@ export default {
|
||||||
|
|
||||||
:deep(.nav-bar) {
|
:deep(.nav-bar) {
|
||||||
position: initial;
|
position: initial;
|
||||||
button {
|
|
||||||
width: 100%;
|
@media only screen and (min-width: 340px) {
|
||||||
justify-content: center;
|
.col button {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
a.navigation-link {
|
a.navigation-link {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
||||||
|
|
@ -1790,7 +1790,7 @@ export default {
|
||||||
text-underline-offset: 4px;
|
text-underline-offset: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-block.duration-text-block b {
|
:deep(.text-block.duration-text-block b) {
|
||||||
font-family: UrbanistSemibold;
|
font-family: UrbanistSemibold;
|
||||||
}
|
}
|
||||||
:deep(.alert-warning.widget-name-AlertRecalNoMobileWidget .alert-heading),
|
:deep(.alert-warning.widget-name-AlertRecalNoMobileWidget .alert-heading),
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
<alert
|
<alert
|
||||||
v-if="shouldDisplayDropOffAlert"
|
v-if="shouldDisplayDropOffAlert"
|
||||||
ref="alertDropoffInformation"
|
ref="alertDropoffInformation"
|
||||||
class="mb-4 drop-off-alert"
|
class="mt-4 mb-4 drop-off-alert"
|
||||||
:cmsWidgetName="dropOffTimeSlotAlertCMSWidgetName"
|
:cmsWidgetName="dropOffTimeSlotAlertCMSWidgetName"
|
||||||
alertClass="alert-info"
|
alertClass="alert-info"
|
||||||
v-bind:isDismissible="false" />
|
v-bind:isDismissible="false" />
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ export default {
|
||||||
this.$store.getters.order.vehicle.carId,
|
this.$store.getters.order.vehicle.carId,
|
||||||
"service-location"
|
"service-location"
|
||||||
);
|
);
|
||||||
if (!closestShops || closestShops.providers?.length === 0) {
|
if (!closestShops || closestShops.inShopProviders?.length === 0) {
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.displayNoServiceAlert = true;
|
this.displayNoServiceAlert = true;
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -496,7 +496,10 @@ export default {
|
||||||
{ zip: this.serviceZipCode, carId: this.carId },
|
{ zip: this.serviceZipCode, carId: this.carId },
|
||||||
"vehicle"
|
"vehicle"
|
||||||
);
|
);
|
||||||
if (!closestShops?.data?.providers || closestShops.data.providers.length === 0) {
|
if (
|
||||||
|
!closestShops?.data?.inShopProviders ||
|
||||||
|
closestShops.data.inShopProviders.length === 0
|
||||||
|
) {
|
||||||
this.displayNoServiceAlert = true;
|
this.displayNoServiceAlert = true;
|
||||||
if (store.getters.externalParameterState?.isExternalParameter) {
|
if (store.getters.externalParameterState?.isExternalParameter) {
|
||||||
return baseMixin.methods.ResetExternalParamsAndHideModal();
|
return baseMixin.methods.ResetExternalParamsAndHideModal();
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ export default {
|
||||||
color: $black;
|
color: $black;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
background: $blue-100;
|
background: $blue-100;
|
||||||
box-shadow: 0 0 0 1px $blue;
|
border: 1px solid $blue;
|
||||||
}
|
}
|
||||||
&:checked:focus + .list-button-content {
|
&:checked:focus + .list-button-content {
|
||||||
box-shadow: 0 0 0 2.5px $blue;
|
box-shadow: 0 0 0 2.5px $blue;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue