Merge branch 'develop' into CASH-1193

This commit is contained in:
kpatel8hs4io 2025-07-21 15:39:00 -04:00
commit 3c8212c8d7
65 changed files with 740 additions and 667 deletions

View file

@ -1,3 +1,3 @@
registry=https://pkgs.dev.azure.com/Safelite/Digital/_packaging/DigitalQA/npm/registry/
always-auth=true
//pkgs.dev.azure.com/Safelite/Digital/_packaging/DigitalQA/npm/registry/:_authToken=${NPM_TOKEN}
registry=https://pkgs.dev.azure.com/Safelite/Digital/_packaging/DigitalQA/npm/registry/
always-auth=true

View file

@ -42,7 +42,7 @@ const cashRepairInShopAfterPayTests: ITestCase[] = [];
const tc = {
name: `CashRepairInShopAfterPay`,
tags: ['@E2E','@CashRepairInShopAfterPay', '@test_report', '@CASH', '@CASH-836'],
tags: ['@E2E','@CashRepairInShopAfterPay', '@test_report', '@CASH', '@CASH-1187'],
testData: cashRepairInShopAfterPayData
};
cashRepairInShopAfterPayTests.push(tc);

View file

@ -42,7 +42,7 @@ const cashRepairInShopPayPalTests: ITestCase[] = [];
const tc = {
name: `CashRepairInShopPayPal`,
tags: ['@E2E','@CashRepairInShopPayPal', '@test_report', '@CASH', '@CASH-836'],
tags: ['@E2E','@CashRepairInShopPayPal', '@test_report', '@CASH'],
testData: cashRepairInShopPayPalData
};
cashRepairInShopPayPalTests.push(tc);

View file

@ -55,7 +55,7 @@ const cashRepairMobileCCTests: ITestCase[] = [];
const tc = {
name: `CashRepairMobileCreditCard`,
tags: ['@E2E','@CashRepairMobileCreditCard', '@test_report', '@CASH', '@CASH-836'],
tags: ['@E2E','@CashRepairMobileCreditCard', '@test_report', '@CASH'],
testData: cashRepairMobileCCData
};
cashRepairMobileCCTests.push(tc);

View file

@ -90,7 +90,7 @@ const insuranceAcuityPaypalTests: ITestCase[] = [];
const tc = {
name: `InsuranceAcuityPaypal`,
tags: ['@E2E','@InsuranceAcuityPaypal', '@test_report', '@Insurance'],
tags: ['@E2E','@InsuranceAcuityPaypal', '@test_report', '@Insurance', '@CASH-1187'],
testData: insuranceAcuityPaypalData
};
insuranceAcuityPaypalTests.push(tc);

View file

@ -46,7 +46,7 @@ const heavyTruckTests: ITestCase[] = [];
const tc: ITestCase = {
name: `alert0001 Heavy Truck`,
tags: ['@Alert', '@HeavyTruck', '@test_report'],
tags: ['@Alert', '@HeavyTruck', '@test_report', '@CASH-1187'],
testData: heavyTruckData
};

View file

@ -64,7 +64,7 @@ vehiclesToTest.forEach((vehicle, index) => {
const tc = {
name: `alert0003_${vehicle.make.toLowerCase()}_${vehicle.model.toLowerCase()} Windshield selected, when vehicle has split windshield - ${vehicle.make} ${vehicle.model} ${vehicle.year}`,
tags: ['@Alert', '@SplitWindshield', '@test_report', `@${vehicle.make.toLowerCase()}`, '@CASH-836'],
tags: ['@Alert', '@SplitWindshield', '@test_report', `@${vehicle.make.toLowerCase()}`],
testData: testData
};

View file

@ -33,7 +33,7 @@ const repairOnlyTests: ITestCase[] = [];
const tc = {
name: `alert0004 Replace selected when not offered`,
tags: ['@Alert', '@RepairOnly', '@test_report', '@CASH-836'],
tags: ['@Alert', '@RepairOnly', '@test_report', '@CASH-1187'],
testData: repairOnlyData
};
repairOnlyTests.push(tc);

View file

@ -194,16 +194,6 @@ html .in-shop.vspacing .list-group.radio.vspacing .list-group-item {
margin-bottom: 2px;
}
@media (min-width: 500px) {
.form-group {
width: 80%;
}
}
@media (min-width: 800px) {
.form-group {
width: 60%;
}
}
.list-group {
margin-bottom: 20px;
padding-left: 0;

View file

@ -188,17 +188,6 @@
margin-bottom: 2px;
}
@media (min-width: 500px) {
.form-group {
width: 80%;
}
}
@media (min-width: 800px) {
.form-group {
width: 60%;
}
}
.list-group {
margin-bottom: 20px;
padding-left: 0;

View file

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8 6.3201e-10C6.01675 -2.49147e-05 4.1042 0.736615 2.63337 2.06701C1.16255 3.3974 0.238325 5.22669 0.04 7.2C0.0144 7.4624 0 7.7296 0 8C0 8.2704 0.0144 8.5376 0.04 8.8C0.194814 10.3404 0.793246 11.8027 1.76272 13.0097C2.73219 14.2167 4.03105 15.1165 5.50178 15.6C6.9725 16.0834 8.5519 16.1297 10.0484 15.7333C11.5449 15.3368 12.8943 14.5147 13.9328 13.3666C14.9714 12.2185 15.6544 10.7937 15.8992 9.26502C16.1441 7.73636 15.9401 6.16951 15.312 4.75449C14.6839 3.33948 13.6588 2.13709 12.3609 1.29316C11.063 0.449234 9.54814 1.94497e-05 8 6.32009e-10V6.3201e-10ZM8.3312 11.68C8.27055 11.737 8.19865 11.7807 8.12012 11.8082C8.04159 11.8358 7.95816 11.8466 7.8752 11.84C7.79544 11.8483 7.71483 11.8391 7.63899 11.8131C7.56316 11.787 7.49394 11.7446 7.43618 11.689C7.37842 11.6334 7.33351 11.5658 7.3046 11.491C7.27569 11.4162 7.26347 11.336 7.2688 11.256C7.26648 11.0995 7.32367 10.9479 7.4288 10.832C7.48751 10.7721 7.55859 10.7257 7.63708 10.6962C7.71556 10.6666 7.79956 10.6545 7.8832 10.6608C7.96706 10.6547 8.05124 10.6669 8.12996 10.6964C8.20867 10.726 8.28006 10.7722 8.3392 10.832C8.44547 10.9473 8.50283 11.0993 8.4992 11.256C8.50107 11.3343 8.48716 11.4122 8.4583 11.4851C8.42944 11.5579 8.38621 11.6242 8.3312 11.68ZM9.3552 8.1744L8.7488 8.7744C8.54248 9.01481 8.41218 9.31105 8.3744 9.6256C8.35965 9.74981 8.30021 9.86441 8.20718 9.94802C8.11415 10.0316 7.99387 10.0785 7.8688 10.08C7.79446 10.0802 7.72097 10.0643 7.65339 10.0333C7.58581 10.0024 7.52575 9.95709 7.47738 9.90065C7.429 9.8442 7.39345 9.77794 7.37318 9.70641C7.35292 9.63489 7.34842 9.55983 7.36 9.4864C7.38057 9.33018 7.41648 9.17637 7.4672 9.0272C7.60032 8.7102 7.79315 8.42177 8.0352 8.1776L8.7648 7.4272C9.05746 7.1218 9.22428 6.71732 9.232 6.2944C9.25213 5.96201 9.14193 5.63487 8.9248 5.3824C8.80862 5.26708 8.66916 5.17788 8.51575 5.12076C8.36234 5.06365 8.19851 5.03993 8.0352 5.0512C7.6576 5.0512 7.3392 5.136 7.1232 5.352C6.9072 5.568 6.8144 6.0128 6.7904 6.3744C6.78584 6.44174 6.76797 6.5075 6.73783 6.56789C6.70768 6.62828 6.66586 6.68208 6.61478 6.7262C6.5637 6.77032 6.50438 6.80386 6.44025 6.8249C6.37612 6.84593 6.30845 6.85404 6.24116 6.84875C6.17388 6.84346 6.10831 6.82488 6.04825 6.79408C5.9882 6.76328 5.93485 6.72088 5.89129 6.66932C5.84773 6.61777 5.81483 6.55808 5.79449 6.49373C5.77415 6.42937 5.76678 6.36162 5.7728 6.2944C5.8176 5.7584 5.9552 5.1408 6.392 4.704C6.7872 4.3088 7.352 4.1504 8.0352 4.1504C8.736 4.1504 9.28213 4.33867 9.6736 4.7152C10.0656 5.0896 10.2608 5.6064 10.2608 6.2608C10.2608 6.9152 9.9552 7.5472 9.3552 8.1776V8.1744Z" fill="#0070D1"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -1,28 +1,95 @@
const pagePercentageMapper = {
vehicle: 4,
"vehicle-damage": 16,
estimate: 28,
"service-zip": 32,
"vin-lookup": 32,
"license-plate-lookup": 32,
"address-lookup": 32,
"address-vehicles": 36,
"part-questions": 40,
"molding-questions": 40,
"vehicle-parts": 40,
"capability-questions": 40,
quote: 48,
"insurance-company": 52,
// TODO: REMOVE THIS COMMENT AND BELOW, ONCE CASH-803 (SERVICE-LOCATION AND SCHEDULE PAGE COMBINATION) HAS BEEN VETTED
// "service-location": 60,
schedule: 64,
"mobile-details": 76,
"customer-details": 84,
"payment-method": 92,
payment: 96,
confirmation: 100,
export const pageProgressMapper = {
//Combine progress bar slide percent and button steps
vehicle: {
percent: 7,
step: 1,
},
"vehicle-damage": {
percent: 10,
step: 1,
},
estimate: {
percent: 14,
step: 1,
},
"service-zip": {
percent: 18,
step: 1,
},
"vin-lookup": {
percent: 18,
step: 1,
},
"license-plate-lookup": {
percent: 18,
step: 1,
},
"address-lookup": {
percent: 18,
step: 1,
},
"address-vehicles": {
percent: 25,
step: 1,
},
"part-questions": {
percent: 30,
step: 1,
},
"molding-questions": {
percent: 30,
step: 1,
},
"vehicle-parts": {
percent: 30,
step: 1,
},
"capability-questions": {
percent: 30,
step: 1,
},
quote: {
percent: 39, //Must be 39
step: 2,
},
"insurance-company": {
percent: 52,
step: 2,
},
"service-location": {
percent: 60,
step: 2,
},
schedule: {
percent: 70.5, //Must be 70.5
step: 3,
},
"mobile-details": {
percent: 76,
step: 3,
},
"customer-details": {
percent: 84,
step: 3,
},
"payment-method": {
percent: 92, //Must be 92
step: 3,
},
payment: {
percent: 96,
step: 4,
},
confirmation: {
percent: 100,
step: 4,
},
};
export const getProgressBarPercentage = (page) => {
return pagePercentageMapper[page] || 0;
return pageProgressMapper[page]?.percent || 0;
};
export const getProgressBarStep = (page) => {
return pageProgressMapper[page]?.step || 1;
};

View file

@ -7,7 +7,7 @@ https://safelite.atlassian.net/wiki/spaces/DC/pages/76644418/Button+Question+Com
">
<div
v-if="questionText && answers && answers.length > 0"
class="question-text d-flex"
class="question-text"
:class="{ 'small-question-text': isSmallQuestionText }">
<span class="fw-bold w-100" :class="[labelBold ? 'span-bold' : '']">
{{ questionText }}
@ -83,10 +83,7 @@ https://safelite.atlassian.net/wiki/spaces/DC/pages/76644418/Button+Question+Com
</div>
</fieldset>
</div>
<div
id="form-test-error"
class="row form-test-error"
:class="isErrorCentered ? 'text-center' : ''">
<div id="form-test-error" class="row form-test-error">
<error-message
role="comment"
aria-atomic="true"
@ -261,12 +258,6 @@ export default {
return classes;
},
isErrorCentered() {
if (this.buttonTypeString == "listCard" && this.buttonsInfo.length <= 2) {
return true;
}
return false;
},
buttonsInfo() {
return (Array.isArray(this.answers) ? this.answers : [])?.map((answer) => ({
buttonLabel: answer.buttonLabel ?? answer.Text ?? answer,

View file

@ -152,6 +152,7 @@ export default {
border: 1px solid $gray-500;
border-radius: 0.5rem;
min-height: 3rem;
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
@include media-breakpoint-up(md) {
min-height: 3.5rem;
}

View file

@ -66,19 +66,18 @@ export default {
.btn {
&.btn-primary {
position: relative;
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
background: $red;
border: none;
border-radius: $border-radius-lg;
color: $white;
justify-content: center;
font-weight: 500;
@media (hover: hover) {
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
background: $red;
}
&:focus {
box-shadow:
0 0 0 3px,
0 0 0 5.5px $blue-700;
0 0 0 5.5px $red;
}
&:focus, // Mouse, touch, stylus focus
&:focus-visible {
@ -86,27 +85,26 @@ export default {
outline: none;
box-shadow:
0 0 0 3px,
0 0 0 5.5px $blue-700;
0 0 0 5.5px $red;
color: $white;
background: linear-gradient(270deg, rgba(6, 87, 124, 1) 0%, rgba(6, 87, 124, 1) 100%);
background: $red;
}
&:disabled {
background: $gray-200 !important;
background: linear-gradient(270deg, $gray-200 0%, $gray-200 100%) !important;
background: $red !important;
color: $gray-600 !important;
font-weight: 400;
height: 48px;
border: none;
border-radius: $border-radius-lg;
cursor: pointer;
pointer-events: all;
}
&.has-loader {
color: $white;
background: $blue-700;
background: $red;
box-shadow:
0 0 0 3px,
0 0 0 5.5px $blue-700;
0 0 0 5.5px $red;
pointer-events: none;
}
&.delay {
@ -117,8 +115,7 @@ export default {
&.btn-secondary {
position: relative;
background: transparent;
border: 1px solid $blue;
border-radius: $border-radius-lg;
border: 1px solid $red;
color: $blue;
font-weight: 500;
transition: all 150ms linear;
@ -133,7 +130,7 @@ export default {
outline: none;
box-shadow:
0 0 0 3px $white,
0 0 0 5.5px $blue-700;
0 0 0 5.5px $red;
color: $white;
@include blue-gradient;
}
@ -142,14 +139,12 @@ export default {
color: $gray-550 !important;
font-weight: 400;
height: 48px;
border: 1px solid $gray-550;
border-radius: $border-radius-lg;
border: 1px solid $red;
cursor: pointer;
pointer-events: all;
}
&.has-loader {
color: $white;
@include blue-gradient;
pointer-events: none;
}
&.delay {

View file

@ -44,21 +44,40 @@ 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?
: "";
let glassType = "";
for (let i = 0; i < glassDamage?.length; i++) {
if (i !== 0) {
glassType += "/";
}
glassType += glassDamage[i].glassLocation;
}
const damageType = store.getters.order?.damage?.isRepair ? "repair" : "replace";
const hasGlassDamage = glassDamage?.length > 0;
const hasRepairFlag = store.getters.order?.damage?.isRepair;
const paymentType = store.getters.oreder?.payment?.isInsurance ? "insurance" : "cash";
let damageType = "";
if (hasRepairFlag) {
damageType = "repair";
} else if (hasGlassDamage) {
damageType = "replace";
}
const isInsurance = store.getters.order?.payment?.isInsurance;
let paymentType = "";
if (isInsurance) {
paymentType = "insurance";
} else if (isInsurance !== null && isInsurance !== undefined) {
paymentType = "cash";
}
const glassParts = store.getters.order?.lineItems?.glassParts;
const partId = glassParts && glassParts.length > 0 ? glassParts[0].partId : "";
const partNumber = glassParts && glassParts.length > 0 ? glassParts[0].partNumber : "";
const packageData = deepClone(store.getters?.pageData(routeData.QUOTE.name));
const packageData = deepClone(store.getters?.pageData(routeData.QUOTE.name)?.packages);
const recalFlag = store.getters?.isRecalibrationOnOrder;
const displayRecalFlag = glassParts?.length > 0 ? recalFlag : "";
return {
current_page: this.pageName,
@ -66,13 +85,13 @@ export default {
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 ?? "",
service_zip: store.getters.order?.serviceLocation?.zipCode ?? "",
glass_type: glassType ?? "",
damage_type: damageType ?? "",
payment_type: paymentType ?? "",
quote: packageData ?? [],
part_id: partId ?? "",
recalibration: store.getters?.isRecalibrationOnOrder ?? "",
part_id: partNumber ?? "",
recalibration: displayRecalFlag ?? "",
};
},
launchSierraChat() {

View file

@ -337,6 +337,7 @@ export default {
border-radius: 0.5rem;
min-height: 3rem;
padding: 0.75rem 1rem;
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
@include media-breakpoint-up(md) {
padding: 1rem;
min-height: 3.5rem;

View file

@ -10,7 +10,7 @@
href="javascript:void(0)"
class="col d-flex justify-content-between py-0">
<span class="label">{{ OrderDetailsText }}</span>
<span class="label amount-due">
<span class="label amount-due larger">
{{ getLineItemAmount(amountDue, showCoverageAsPending) }}
</span>
</a>
@ -83,16 +83,13 @@
:text="removeLinkText"
href="javascript:void(0)"
@click-event="removeItem(cartItem.cartItemType, cartItem.category)" />
<textLink
v-else-if="
cartItem == recycleFeeCartItem && recyclingModalCmsWidgetName
"
linkType="text"
:text="recycleFeeCartItem.name"
href="javascript:void(0)"
@click-event="openModal(recyclingModalCmsWidgetName)" />
<span v-else-if="cartItem == recycleFeeCartItem">
{{ recycleFeeCartItem.name }}
<a
href="javascript:void(0)"
@click="openModal(recyclingModalCmsWidgetName)">
<img :src="infoIcon" alt="Info Icon" class="info-icon" />
</a>
</span>
<span
v-if="
@ -1150,6 +1147,9 @@ export default {
var amtPaid = +this.subTotal + +this.salesTax;
return amtPaid;
},
infoIcon() {
return require(`@/assets/img/icons/question-mark-icon-blue.svg`);
},
},
components: {
textBlock,
@ -1184,6 +1184,10 @@ export default {
}
.amount-due {
color: $green;
&.larger {
font-size: 1.25rem;
}
}
.cart-panel {
max-height: 0;
@ -1197,29 +1201,13 @@ export default {
display: flex;
justify-content: space-between;
padding: 0.5rem 1.5rem;
&:nth-last-child(-n + 3) {
background-color: $green-100;
}
&:last-child {
background-color: $green;
color: #ffffff;
background-color: $gray-100;
> span:last-of-type {
color: $green;
}
}
}
.deductible {
background-color: $gray-100;
}
.service-type {
background-color: $gray-100;
}
.deductible ~ .service-type {
background: $white;
}
.service-type ~ .packaged-cart-item {
background-color: $gray-100;
}
.deductible ~ .packaged-cart-item {
background: $white;
}
.struck-out-price {
text-decoration: line-through;
padding-left: 0.5rem;
@ -1247,28 +1235,11 @@ export default {
}
}
.non-packaged-cart-item {
&.odd {
background: $gray-100;
}
}
.deductible ~ .non-packaged-cart-item {
&.odd {
background: $white;
}
}
.non-packaged-cart-item {
&.even {
background-color: $white;
}
a {
line-height: 1.625;
}
}
.deductible ~ .non-packaged-cart-item {
&.even {
background-color: $gray-100;
}
}
// Custom order/wrap for removable nonpackaged Cart Items
.removable-cart-item {
flex-wrap: wrap;
@ -1296,8 +1267,7 @@ export default {
color: $black;
}
.sub-total {
border-top: 1px solid $green;
background-color: $green-100;
border-top: 1px solid $gray-600;
}
.service-type,
.deductible {
@ -1316,11 +1286,11 @@ export default {
&:after {
content: "";
transition: all 0.5s ease;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 8.9' xml:space='preserve'%3e%3cpath d='M8 8.9c-.2 0-.5-.1-.6-.3L.3 1.5C.1 1.4 0 1.1 0 .9 0 .7.1.4.3.3.4.1.7 0 .9 0c.2 0 .5.1.6.3L8 6.7 14.5.2c.1-.1.4-.2.6-.2.2 0 .5.1.6.3s.3.4.3.6c0 .2-.1.5-.3.6L8.6 8.6c-.1.2-.4.3-.6.3z' fill='%231474a2'/%3e%3c/svg%3e");
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'%3E%3Cpath fill='%230070D1' d='M12 0a12 12 0 1 0 0 24 12 12 0 0 0 0-24Zm6.113 11.28-5.52 5.52a.84.84 0 0 1-1.186 0l-5.52-5.52a.843.843 0 1 1 1.186-1.2L12 15.012l4.927-4.932a.843.843 0 1 1 1.186 1.2Z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right center;
width: 16px;
height: 9px;
width: 24px;
height: 24px;
display: inline-flex;
position: relative;
right: 0.75rem;

View file

@ -1,15 +1,5 @@
<template>
<div class="funnel-footer">
<div class="container-fluid">
<div class="row">
<div class="col d-flex justify-content-center justify-content-md-start">
<img class="skyline" src="~@/assets/img/skyline-van.svg" alt="" />
</div>
<div class="col d-none d-md-flex justify-content-end align-items-end">
<img class="neighborhood" src="~@/assets/img/neighborhood.svg" alt="" />
</div>
</div>
</div>
<div class="footer-inner-wrapper">
<textLink
linkType="newWindowLink"
@ -64,13 +54,6 @@ export default {
margin-top: auto;
padding: 0 0 2rem 0;
.skyline {
height: 96px;
}
.neighborhood {
height: 48px;
}
p {
font-size: 0.875rem;
margin-top: 0.25rem;
@ -93,12 +76,16 @@ export default {
:deep(a) {
text-decoration: none;
&.new-window-link {
font-family: Urbanist, Arial, Helvetica, sans-serif;
margin: 0 0.75rem;
color: $gray-600;
font-weight: 400;
}
&.navigation-link {
font-family: Urbanist, Arial, Helvetica, sans-serif;
margin: 0 0.75rem;
color: $gray-600;
font-weight: 400;
}
}

View file

@ -1,8 +1,16 @@
<template>
<div class="funnel-header" v-if="imageSrc">
<div class="d-flex justify-content-between align-items-center">
<div class="button-container">
<span class="webchat">
<div class="d-flex w-100">
<progress-bar :page="$route.name" />
</div>
<div class="container d-flex">
<div class="site-logo">
<a href="https://safelite.com">
<img class="logo-image img-fluid" :src="imageSrc" alt="Safelite logo" />
</a>
</div>
<div class="button-container webchat">
<span class="webchat d-flex">
<button
v-show="shouldShowWebchatButton"
v-on:click="webchatClicked"
@ -10,18 +18,10 @@
class="chat-button"></button>
</span>
</div>
<div class="site-logo">
<img class="logo-image img-fluid" :src="imageSrc" alt="Safelite logo" />
</div>
<div class="button-container">
<!-- // menu-modal temporarily not in use until the hamburger menu is re-implemented for use with the progress bar. See display: none below. -->
<menuModal />
<!-- // menu-modal temporarily not in use until the hamburger menu is re-implemented for use with the progress bar. See display: none below. -->
</div>
</div>
<div class="d-flex w-100">
<progress-bar :page="$route.name" />
</div>
</div>
<template v-for="globalAlert in globalAlertMessages" :key="globalAlert.id">
<transition name="fade" mode="out-in">
@ -197,23 +197,39 @@ export default {
<style lang="scss" scoped>
.funnel-header {
.container {
padding: 1rem 0.75rem;
display: flex;
align-items: center;
@include media-breakpoint-up(md) {
padding: 2rem 0.75rem;
}
}
position: relative;
padding: 1rem 0;
padding: 0 0 1rem 0;
.button-container {
width: 1.5rem;
height: 1.625rem;
&.webchat {
margin-right: 1rem;
@include media-breakpoint-up(md) {
margin-right: 2rem;
}
}
}
.site-logo {
margin-right: auto;
}
.logo-image {
width: auto;
height: 1.1875rem;
width: 100px;
height: auto;
margin: 0 auto;
@include media-breakpoint-up(md) {
width: 165px;
}
}
:deep(.menu-modal-container) {
display: none; // This is temporary until the hamburger menu is re-implemented for use with the progress bar
}
.webchat {
.chat-button {
width: 1.5rem;

View file

@ -6,9 +6,13 @@
:class="[isActive ? 'active' : '']"
@click="toggleModal"
aria-label="Hamburger Menu (modal window)">
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
<span v-if="isActive">Close</span>
<span v-else>Step {{ currentStepNumber }} of 4</span>
<div class="bars ms-2">
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
</div>
</button>
</div>
<div
@ -18,47 +22,45 @@
tabindex="-1"
aria-labelledby="footerModalLabel"
aria-hidden="true"
v-on="{ 'show.bs.modal': show, 'hide.bs.modal': hide }">
v-on="{ 'show.bs.modal': show, 'hide.bs.modal': hide }"
@click.self="closeModal">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<div class="modal-header visually-hidden">
<h5 class="modal-title" id="footerModalLabel">Footer Navigation</h5>
</div>
<div class="modal-body d-flex flex-column">
<textLink
linkType="newWindowLink"
text="Terms of service"
href="//www.safelite.com/terms-of-service"
target="_blank" />
<textLink
linkType="newWindowLink"
text="Your privacy choices"
href="//www.safelite.com/privacy-center"
target="_blank">
<template v-slot:after-text>
<img
class="ccpa-icon"
src="~@/assets/img/icons/ccpa-icon.svg"
alt="Your privacy choices" />
</template>
</textLink>
<textLink
linkType="navigation"
text="Cookie preferences"
href="javascript:OneTrust.ToggleInfoDisplay();" />
<textLink
linkType="newWindowLink"
text="Warranty"
href="//www.safelite.com/national-lifetime-warranty"
target="_blank" />
<textLink
linkType="newWindowLink"
text="Notice at collection"
href="https://www.safelite.com/ccpa-privacy-policy"
target="_blank" />
</div>
<div class="modal-footer d-flex justify-content-start">
&copy; {{ new Date().getFullYear() }} Safelite Group
<div class="step-grid">
<div class="bar-container">
<progress-bar class="bar-dots" :page="$route.name" :vertical="true" />
<span class="dot1"></span>
<span class="dot2"></span>
<span class="dot3"></span>
<span class="dot4"></span>
</div>
<div class="d-flex flex-column justify-content-between">
<div class="step-containers">
<span class="step-number">Step 1 of 4</span>
<br />
<span class="step-name">Vehicle</span>
</div>
<div class="step-containers">
<span class="step-number">Step 2 of 4</span>
<br />
<span class="step-name">Quote</span>
</div>
<div class="step-containers">
<span class="step-number">Step 3 of 4</span>
<br />
<span class="step-name">Schedule</span>
</div>
<div class="step-containers">
<span class="step-number">Step 4 of 4</span>
<br />
<span class="step-name">Review</span>
</div>
</div>
</div>
</div>
</div>
</div>
@ -66,8 +68,9 @@
</template>
<script>
import textLink from "@/ux-components/text-link/text-link";
import { Modal } from "bootstrap";
import { getProgressBarStep } from "@/constants/progress-bar-mapper";
import progressBar from "@/fmg-components/funnel-header/progress-bar/progress-bar";
import baseMixin from "@/mixins/base-mixin.js";
export default {
@ -100,8 +103,13 @@ export default {
self.isActive = false;
},
},
computed: {
currentStepNumber() {
return getProgressBarStep(this.$route.name);
},
},
components: {
textLink,
progressBar,
},
};
</script>
@ -111,49 +119,92 @@ export default {
button {
border: none;
&.menu-button {
width: 1.5rem;
height: 1.5rem;
border-radius: 50%;
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2);
width: auto;
height: auto;
border-radius: 1.5rem;
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
background-color: $white;
position: relative;
display: flex;
flex-direction: column;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 0; //Required to prevent 'squish' on iPhone
padding: 0.15rem 0.5rem; //Required to prevent 'squish' on iPhone
z-index: 1050;
.bar1,
.bar2,
.bar3 {
width: 14px;
height: 2px;
background-color: $blue;
margin: 1px 0;
transition: 0.25s;
@include media-breakpoint-up(md) {
padding: 0.25rem 1rem;
}
&.active .bar1 {
transform: rotate(-45deg) translate(-3px, 3px);
transform: rotate(-45deg) translate(-3px, 8px);
}
&.active .bar2 {
opacity: 0;
}
&.active .bar3 {
transform: rotate(45deg) translate(-3px, -3px);
transform: rotate(45deg) translate(-3px, -8px);
}
.bars {
width: 1.5rem;
height: 1.5rem;
display: flex;
justify-content: space-around;
flex-direction: column;
scale: 0.75;
.bar1,
.bar2,
.bar3 {
width: 1.5rem;
height: 2px;
background-color: $blue;
margin: 1px 0;
transition: 0.25s;
}
}
.step-numbers {
font-size: 0.875rem;
margin-right: 0.5rem;
@include media-breakpoint-up(md) {
font-size: 1rem;
}
}
}
}
}
.modal {
&.menu-modal {
//left: auto;
height: calc(100% - 56px);
top: 56px;
.modal-dialog {
position: fixed;
bottom: 0;
right: 0;
height: calc(100% - 68px);
width: 100vw; // or set a max-width if you want a drawer effect
max-width: 294px;
margin: 0;
transform: translateX(100%);
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 1050;
@include media-breakpoint-up(md) {
height: calc(100% - 102px);
top: 102px;
}
}
&.show .modal-dialog {
transform: translateX(0);
}
background-color: rgba(0, 0, 0, 0.5);
height: calc(100% - 68px);
top: 68px;
border-top: 1px solid $gray-300;
overflow-x: visible;
overflow-y: visible;
@include media-breakpoint-up(md) {
height: calc(100% - 102px);
top: 102px;
}
.modal-body {
padding: 2rem;
display: flex;
align-items: center;
.ccpa-icon {
width: 2.0625rem;
height: 1rem;
@ -162,6 +213,48 @@ export default {
:deep(.navigation-link) {
margin-bottom: 1.5rem;
}
.step-grid {
display: grid;
max-width: 140px;
grid-template-columns: 1fr 1fr;
.step-containers {
line-height: 1;
}
.bar-container {
width: 24px;
position: relative;
.dot1,
.dot2,
.dot3,
.dot4 {
position: absolute;
width: 22px;
height: 22px;
background-color: $white;
border-radius: 50rem;
border: 1px solid $gray;
left: 1px;
}
.dot1 {
top: 1px;
}
.dot2 {
top: 114px;
}
.dot3 {
top: 227px;
}
.dot4 {
top: 332px;
}
}
.step-number {
font-size: 0.75rem;
}
.step-name {
font-size: 1.25rem;
}
}
}
.modal-fullscreen {
width: 100vw;
@ -190,23 +283,30 @@ export default {
align-items: center;
padding: 0; //Required to prevent 'squish' on iPhone
z-index: 1056;
.bar1,
.bar2,
.bar3 {
width: 14px;
height: 2px;
background-color: $blue;
margin: 1px 0;
transition: 0.25s;
}
&.active .bar1 {
transform: rotate(-45deg) translate(-3px, 3px);
}
&.active .bar2 {
opacity: 0;
}
&.active .bar3 {
transform: rotate(45deg) translate(-3px, -3px);
.bars {
width: 1.5rem;
height: 1.5rem;
display: flex;
justify-content: space-around;
flex-direction: column;
.bar1,
.bar2,
.bar3 {
width: 1.5rem;
height: 2px;
background-color: $blue;
margin: 1px 0;
transition: 0.25s;
}
&.active .bar1 {
transform: rotate(-45deg) translate(-3px, 8px);
}
&.active .bar2 {
opacity: 0;
}
&.active .bar3 {
transform: rotate(45deg) translate(-3px, -8px);
}
}
}
}

View file

@ -1,5 +1,5 @@
<template>
<div class="progress-bar-outer">
<div :class="barClass">
<div class="progress-bar-inner" :style="progressStyle"></div>
</div>
</template>
@ -18,6 +18,10 @@ export default {
type: String,
required: true,
},
vertical: {
type: Boolean,
default: false,
},
},
data() {
return {
@ -45,9 +49,20 @@ export default {
},
computed: {
progressStyle() {
return {
width: this.displayedProgress + "%",
};
if (this.vertical) {
return {
height: this.displayedProgress + "%",
width: "100%",
};
} else {
return {
width: this.displayedProgress + "%",
height: "100%",
};
}
},
barClass() {
return this.vertical ? "progress-bar-outer-vertical" : "progress-bar-outer";
},
},
};
@ -55,50 +70,43 @@ export default {
<style lang="scss">
.progress-bar-outer {
background: $blue-100;
height: 10px;
height: 5px;
position: relative;
border-radius: 10px;
border-radius: 0;
width: 100%;
margin-top: 1rem;
margin-top: 0;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075);
.progress-bar-inner {
transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1); /* Smooth width transition */
transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1);
will-change: width;
height: 10px;
background-color: $blue;
height: 100%;
background-color: $red;
position: absolute;
top: 0;
left: 0;
border-radius: 10px;
border-radius: 0;
}
}
progress {
height: 10px;
.progress-bar-outer-vertical {
background: $blue-100;
width: 24px;
height: 356px;
position: relative;
border-radius: 0;
margin-top: 0;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075);
overflow: hidden;
border-radius: 50rem;
.progress-bar-inner {
transition: height 0.5s cubic-bezier(0.4, 0, 0.2, 1) !important;
will-change: height !important;
width: 100%;
/* Firefox */
appearance: none;
background-color: $blue-100;
border: 0;
border-radius: $border-radius-pill;
box-shadow: $box-shadow-inset;
&::-moz-progress-bar {
background-color: $blue;
border-radius: $border-radius-pill;
}
/* Webkit */
-webkit-appearance: none;
&::-webkit-progress-bar {
background-color: $blue-100;
border-radius: $border-radius-pill;
box-shadow: $box-shadow-inset;
}
&::-webkit-progress-value {
background-color: $blue;
border-radius: $border-radius-pill;
}
background-color: $red;
position: absolute;
left: 0;
top: 0;
border-radius: 50rem;
}
}
</style>

View file

@ -1,9 +1,7 @@
<template>
<div class="funnel-sub-header">
<div
class="d-flex align-items-center container-fluid overflow-hidden"
:class="[textAlignment]">
<h5 class="text-center fw-normal mb-0" :class="headerColor">
<div class="d-flex align-items-center overflow-hidden">
<h5 class="fw-normal mb-0" :class="headerColor">
<span>
{{ text }}
</span>
@ -13,13 +11,9 @@
@click-event="clickEvent" />
</h5>
</div>
<div
v-if="subText"
class="d-flex align-items-center justify-content-center container-fluid overflow-hidden mt-1">
<p class="text-center small fw-normal sub-text">
<span>
{{ subText }}
</span>
<div v-if="subText" class="d-flex align-self-center overflow-hidden mt-1">
<p class="small fw-normal sub-text">
<span v-html="boldedSubHeaderText"></span>
</p>
</div>
</div>
@ -37,21 +31,17 @@ export default {
type: String,
default: "dark-header",
},
leftAlignHeader: {
type: Boolean,
default: false,
},
},
components: {
buttonBack,
},
computed: {
boldedSubHeaderText() {
return this.getCmsContent(this.cmsWidgetName, "HeaderSubText");
},
text() {
return this.getCmsContent(this.cmsWidgetName, "HeaderText");
},
textAlignment() {
return this.leftAlignHeader ? "justify-content-start" : "justify-content-center";
},
subText() {
return this.getCmsContent(this.cmsWidgetName, "HeaderSubText");
},
@ -68,8 +58,12 @@ export default {
</script>
<style lang="scss" scoped>
:deep(.bolded-words) {
font-family: UrbanistSemibold, Arial, Helvetica, sans-serif;
}
h5 {
line-height: 32px;
font-size: 1.25rem;
button {
color: inherit;

View file

@ -1,31 +1,15 @@
<template>
<div :class="`questions-page`">
<loadingModal ref="loadingModal" />
<div class="container-fluid page-container-grouped-styles">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4 mt-4">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container page-container-grouped-styles">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<alert
ref="alertFewMoreQuestions"
cmsWidgetName="alertWidget"
class="my-5"
alertClass="alert-warning"
:manualHeadline="alertFewMoreQuestionsHeader"
:manualCopy="alertFewMoreQuestionsCopy"
v-bind:isDismissible="false" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4 question-chain-wrapper">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7 question-chain-wrapper">
<div v-for="(questionsDatum, i) in questionsData" :key="questionsDatum.key">
<questionChain
ref="questionChain"
@ -54,7 +38,6 @@
<script>
// Components
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
import alert from "@/ux-components/alert/alert";
import questionChain from "@/digital-components/question-chain/question-chain";
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
import navbar from "@/fmg-components/nav-bar/nav-bar";
@ -96,7 +79,6 @@ export default {
},
components: {
funnelHeader,
alert,
questionChain,
funnelSubHeader,
navbar,
@ -108,7 +90,7 @@ export default {
<style lang="scss">
.questions-page {
.question-text {
margin-bottom: 0.5rem;
margin-bottom: 1.5rem;
span {
text-align: left;

View file

@ -118,13 +118,14 @@ export default {
margin-bottom: 1.5rem;
order: 2;
text-align: center;
background: $blue-100;
background: $gray-100;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 3rem;
border-radius: 0.5rem;
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
&.progress-saved {
background: none;
@ -135,14 +136,13 @@ export default {
position: relative;
color: $blue;
border: none;
font-weight: 900;
font-family: UrbanistSemibold;
font-size: 0.875rem;
text-align: center;
text-align: left;
display: inline-block;
width: auto;
height: auto;
text-decoration: underline;
text-underline-offset: 0.25rem;
text-decoration: none;
line-height: 1rem;
padding: 1rem;
margin: 0 auto;
@ -154,7 +154,6 @@ export default {
&.btn {
&.btn-secondary {
font-weight: 900;
border: none;
&:hover,
&:active,
@ -183,6 +182,17 @@ export default {
// fixes flicker while transitioning between states
transition: background 0s 0s ease-in-out;
}
&.open-save-progress-button {
span {
color: $gray-600;
font-family: UrbanistRegular;
.highlighted-words {
font-family: UrbanistSemibold;
color: $blue;
}
}
}
}
.modal.modal-component .modal-dialog .modal-content {

View file

@ -5,15 +5,14 @@
ref="theForm"
v-slot="{ meta }"
autocomplete="off">
<div class="container-fluid page-container-grouped-styles" id="address-lookup">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4 mt-4">
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" ref="funnelSubHeader" />
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container page-container-grouped-styles">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader
cmsWidgetName="FunnelSubHeaderWidget"
ref="funnelSubHeader"
class="mb-7" />
<customerQuestions
ref="customerQuestions"

View file

@ -17,6 +17,9 @@
<img :src="ScheduleConfirmationImage" />
<span v-html="ScheduleConfirmationText"></span>
</div>
<div class="emailtext" v-html="ConfirmationEmailText"></div>
<div class="main">
<div></div>
@ -48,6 +51,17 @@
class="duration-text-block" />
</div>
<div class="mt-3" v-if="shouldDisplayFosterLove">
<donationBlock
cmsWidgetName="DonationWidget"
v-model="donationAmount"
:donationValues="donationValues"
:showDonationSuccess="showDonationSuccess"
:showDonationError="showDonationError"
@DonationAddedEvent="addDonationToOrder"
ref="donationBlock" />
</div>
<hr class="mt-4 mb-0" />
<cart
@ -69,27 +83,7 @@
:isNoComp="isNoComp"
:isMSRFeeApplicable="isMSRFeeApplicable" />
<div class="mt-3" v-if="shouldDisplayFosterLove">
<donationBlock
cmsWidgetName="DonationWidget"
v-model="donationAmount"
:donationValues="donationValues"
:showDonationSuccess="showDonationSuccess"
:showDonationError="showDonationError"
@DonationAddedEvent="addDonationToOrder"
ref="donationBlock" />
</div>
<hr class="mb-5" />
<div class="emailtext" v-html="ConfirmationEmailText"></div>
<navbar
cmsWidgetName="FunnelFooterWidget"
ref="navbar"
isBackButtonHidden="true"
@ForwardClicked="forwardButtonAction"
:buttonSize="true" />
</div>
</div>
</div>
@ -591,7 +585,6 @@ export default {
components: {
funnelHeader,
Form,
navbar,
addToCalendar,
cart,
textBlock,
@ -627,8 +620,7 @@ export default {
.header-container {
display: flex;
align-items: center;
justify-content: center;
padding: 1.5rem 0;
padding: 1rem 0;
p {
display: inline-block;
@ -653,7 +645,7 @@ export default {
}
.emailtext {
padding: 0.5rem 0 0;
padding: 0 0 1.5em;
p {
font-size: 0.875rem;

View file

@ -1,13 +1,9 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container page-container-grouped-styles">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" class="mt-4 mb-5" />
<textboxQuestion
isRequired
@ -47,8 +43,6 @@
cmsWidgetName="TextMeQuestionWidget"
v-model="isSmsOptIn" />
<techNotes v-model="techNotes" :textAreaLabelCopy="textAreaLabelCopy" />
<navbar
cmsWidgetName="FunnelFooterWidget"
ref="navbar"
@ -74,7 +68,6 @@ import textboxQuestion from "@/digital-components/textbox-question/textbox-quest
import phoneNumberQuestion from "@/digital-components/phone-number-question/phone-number-question";
import textBlock from "@/digital-components/text-block/text-block";
import checkboxQuestion from "@/digital-components/checkbox-question/checkbox-question";
import techNotes from "@/layouts/customer-details/tech-notes/tech-notes";
//Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
@ -219,7 +212,6 @@ export default {
textBlock,
phoneNumberQuestion,
checkboxQuestion,
techNotes,
},
};
</script>

View file

@ -1,17 +1,16 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<loadingModal ref="loadingModal" />
<div class="container-fluid page-container-grouped-styles">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4 mt-4">
<funnelSubHeader class="pb-4" cmsWidgetName="FunnelSubHeaderWidget" />
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container page-container-grouped-styles estimate">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<div>
<div class="vinlookupquestion" v-html="this.VinLookupQuestionText"></div>
<div v-html="this.VinLookupQuestionBodyText2"></div>
<div
class="select-an-option"
v-html="this.VinLookupQuestionFooterText"></div>
<buttonQuestion
cmsWidgetName="VinLookupMethod"
:answers="answersFromCms"
@ -29,6 +28,8 @@
:isForwardActionDisabled="!meta.valid"
@back-clicked="backButtonAction"
@ForwardClicked="forwardButtonAction" />
<div class="text-center" v-html="this.VinLookupQuestionFooterText2"></div>
</div>
</div>
</div>
@ -39,7 +40,6 @@
// Components
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
import navbar from "@/fmg-components/nav-bar/nav-bar";
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
import buttonQuestion from "@/digital-components/button-question/button-question";
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
@ -229,10 +229,18 @@ export default {
VinLookupQuestionText() {
return this.getCmsContent("VinLookupQuestion", "BodyText");
},
VinLookupQuestionBodyText2() {
return this.getCmsContent("VinLookupQuestion", "BodyText2");
},
VinLookupQuestionFooterText() {
return this.getCmsContent("VinLookupQuestion", "FooterText");
},
VinLookupQuestionFooterText2() {
return this.getCmsContent("VinLookupQuestion", "FooterText2");
},
},
components: {
funnelHeader,
funnelSubHeader,
navbar,
buttonQuestion,
Form,
@ -243,14 +251,12 @@ export default {
<style lang="scss">
.vinlookupquestion p {
margin-bottom: 0;
font-size: 1.25rem;
}
.vinlookupquestion strong {
font-weight: 500;
color: $black;
}
.vinlookupquestion p:nth-child(2) {
font-size: 0.875rem;
.select-an-option {
font-family: UrbanistSemibold;
font-weight: 600;
margin-bottom: 1rem;
}
</style>

View file

@ -1,14 +1,10 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<loadingModal ref="loadingModal" />
<div class="container-fluid page-container-grouped-styles">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container page-container-grouped-styles">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" class="mt-4" />
<div v-if="originalList.length > 0">

View file

@ -1,13 +1,9 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<div class="container-fluid page-container-grouped-styles">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4 mt-4">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container page-container-grouped-styles">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
<textboxQuestion

View file

@ -112,6 +112,7 @@ export default {
border: 1px solid $gray-500;
width: 100%;
outline: none;
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
span {
&.small {

View file

@ -1,14 +1,10 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<loadingModal notFullScreen ref="loadingModal" />
<div class="container-fluid payment-method">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4 mt-4">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container payment-method">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader class="mb-5" cmsWidgetName="FunnelSubHeaderWidget" />
<hr class="my-0" />
@ -57,7 +53,7 @@
<div
v-if="isRecalibrationOnOrder && shouldHideRecalibration"
class="questions-about-service my-5">
class="questions-about-service mt-5">
<textBlock
cmsWidgetName="QuestionsAboutYourServiceWidget"
justifyText="left"
@ -67,7 +63,7 @@
<div class="d-flex flex-row checkbox-group">
<checkboxQuestion
cmsWidgetName="RecalConfirmWidget"
class="mb-5"
class="mb-3"
isRequired="true"
v-model="isRecalAckOptIn"
validationRules="recal-ack-required"
@ -82,13 +78,6 @@
:isInsurance="isInsurance"
validationRules="payment-method-required" />
<alert
v-if="showHavePaymentReadyAlert"
:isDismissible="false"
alertClass="alert-info"
cmsWidgetName="NoPiaDisclaimerWidget"
shouldScrollToOnMount="false" />
<navbar
cmsWidgetName="FunnelFooterWidget"
ref="navbar"
@ -770,11 +759,6 @@ export default {
return false;
},
showHavePaymentReadyAlert() {
return (
!this.showPaymentMethodQuestions && !this.forwardClicked && this.totalAmountDue > 0
);
},
totalAmountDue() {
return getAmountDue(this.lineItems);
},
@ -907,6 +891,12 @@ export default {
margin: 0;
}
.payment-method {
:deep(.almost-done) {
font-family: UrbanistSemibold;
}
:deep(h5) {
margin-bottom: 1rem;
}
.recal-modal {
:deep(.modal-body) {
display: flex;

View file

@ -157,11 +157,11 @@ export default {
&:after {
content: "";
transition: all 0.5s ease;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 8.9' xml:space='preserve'%3e%3cpath d='M8 8.9c-.2 0-.5-.1-.6-.3L.3 1.5C.1 1.4 0 1.1 0 .9 0 .7.1.4.3.3.4.1.7 0 .9 0c.2 0 .5.1.6.3L8 6.7 14.5.2c.1-.1.4-.2.6-.2.2 0 .5.1.6.3s.3.4.3.6c0 .2-.1.5-.3.6L8.6 8.6c-.1.2-.4.3-.6.3z' fill='%231474a2'/%3e%3c/svg%3e");
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'%3E%3Cpath fill='%230070D1' d='M12 0a12 12 0 1 0 0 24 12 12 0 0 0 0-24Zm6.113 11.28-5.52 5.52a.84.84 0 0 1-1.186 0l-5.52-5.52a.843.843 0 1 1 1.186-1.2L12 15.012l4.927-4.932a.843.843 0 1 1 1.186 1.2Z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right center;
width: 16px;
height: 9px;
width: 24px;
height: 24px;
display: inline-flex;
position: relative;
right: 0.75rem;

View file

@ -577,7 +577,7 @@ describe("payment.vue", () => {
// Arrange
const wrapper = setupMocks({});
const outerDiv = wrapper.find(".container-fluid");
const outerDiv = wrapper.find(".container");
const clickFn = jest.fn();
outerDiv.element.addEventListener("click", clickFn);

View file

@ -1,15 +1,10 @@
<template>
<Form>
<loadingModal notFullScreen ref="loadingModal" />
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4 p-0">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<div>
<alert
ref="piaCCErrorAlert"

View file

@ -173,9 +173,8 @@ export default {
max-width: 26rem;
}
}
#afterpay-learnmore {
white-space: nowrap;
& .alert-heading {
font-size: 0.875rem;
}
}
</style>

View file

@ -1,17 +1,15 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<loadingModal ref="loadingModal" />
<div
class="container-fluid page-container-grouped-styles quote-page"
:class="showSaveProgressPopup ? 'show-save-progress-popup' : ''">
<div class="row justify-content-center funnel-header-wrapper">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container quote position-relative">
<div class="row justify-content-center">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader class="mb-5" cmsWidgetName="FunnelSubHeaderWidget" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4 mt-4">
<funnelSubHeader class="mb-5" cmsWidgetName="FunnelSubHeaderWidget" />
<div class="col-md-6">
<cashOrInsuranceQuestion
ref="cashOrInsurance"
cmsWidgetName="CashOrInsuranceQuestionWidget"
@ -69,7 +67,7 @@
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<div class="col-md-8 col-xl-6">
<contentGroupModal ref="RainDefenseModal" cmsWidgetName="RainDefenseModal" />
<contentGroupModal ref="FrontWiperModal" cmsWidgetName="FrontWiperModal" />
<contentGroupModal ref="RearWiperModal" cmsWidgetName="RearWiperModal" />
@ -90,9 +88,8 @@
<textBlock
cmsWidgetName="quoteDisclaimer"
justifyText="center"
typeStyle="caption"
class="mb-5 quote-disclaimer" />
class="mb-5 quote-disclaimer text-left text-md-center" />
</div>
</div>
@ -172,6 +169,7 @@ import { routeData } from "@/router/constants/routes";
import { consumeQueryFromStash } from "@/router/methods/helpers/querystring-stash";
import { storeMutations } from "@/constants/store-mutations";
import { debugLog } from "@/helpers/debug-log-helper";
import { savePageData } from "@/router/methods/helpers/save-page-data";
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
@ -669,14 +667,7 @@ export default {
async closeSaveProgressPopup() {
this.showSaveProgressPopup = false;
await this.dispatchStoreAction(
storeActions.SAVE_PAGE_DATA,
{
page: routeData.QUOTE.name,
data: { saveProgressPopupSkipped: true },
},
false
);
savePageData(this.pageName, { saveProgressPopupSkipped: true }, true);
if (this.skipToInsurance) {
// skip ahead now if in IGQ skip experiment
@ -901,6 +892,31 @@ export default {
</script>
<style lang="scss" scoped>
// Unique to quote page for 2.0/Heritage parity
.quote {
padding-bottom: 2rem;
:deep(.nav-bar) {
position: initial;
button {
width: 100%;
justify-content: center;
}
a.navigation-link {
position: absolute;
left: 1rem;
bottom: 1rem;
@include media-breakpoint-up(lg) {
left: 6rem;
}
}
.col-auto {
width: -webkit-fill-available;
}
.col-auto {
width: -moz-available;
}
}
}
.quote-page.show-save-progress-popup .row.justify-content-center {
display: none;
@ -918,6 +934,11 @@ export default {
.text-block {
display: block;
}
:deep(.container .funnel-sub-header) {
display: flex;
align-items: center;
flex-direction: column;
}
:deep(.promo-modal-question a) {
@include responsive-font-size-md(0.875rem, 1rem);
}

View file

@ -442,7 +442,7 @@ export default {
price: ans.buttonAuxillaryCopy,
}));
await savePageData(this.pageName, { packages: toLog });
await savePageData(this.pageName, { packages: toLog }, true);
},
},
components: {

View file

@ -2,15 +2,12 @@
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm">
<div class="return-user small-question-text">
<loadingModal ref="loadingModal" />
<div class="container-fluid page-container-grouped-styles">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container page-container-grouped-styles">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center return-user-spacing">
<div class="col-md-6 col-xl-4 mt-4">
<div class="col-12 col-md-10 col-lg-8 col-xl-7 return-user-spacing">
<funnelSubHeader
class="justify-content-center d-flex"
ref="funnelSubHeader"
cmsWidgetName="FunnelSubHeaderWidget" />
</div>

View file

@ -1,14 +1,10 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<loadingModal ref="loadingModal" />
<div class="container-fluid page-container-grouped-styles page-schedule">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container page-container-grouped-styles">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" class="mt-4" />
<serviceZipModalQuestion
editScreenReaderTextCmsWidgetName="ScreenReaderZipEditWidget"

View file

@ -94,6 +94,7 @@ export default {
border: 1px solid $gray-500;
width: 100%;
outline: none;
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
span.premium-appointment-price {
position: absolute;

View file

@ -1,14 +1,10 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<loadingModal ref="loadingModal" />
<div class="container-fluid page-container-grouped-styles">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4 mt-4">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container page-container-grouped-styles">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
<serviceZipModalQuestion
@ -69,8 +65,8 @@
alertClass="alert-success" />
</div>
</div>
<div class="row justify-content-center appointment-type">
<div class="col-md-6">
<div class="row appointment-type">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<appointmentTypeQuestion
v-model="selectedAppointmentType"
v-show="isAppointmentTypeDisplayed"
@ -87,21 +83,8 @@
labelBold="true" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<button-question
v-if="selectedAppointmentType == appointmentTypeStrings.IN_SHOP"
class="shop-question-button"
ref="buttonQuestion"
:answers="selectedShopAnswer"
:modelValue="selectedProvider?.providerNumber"
:isMultiSelect="false"
:readonly="true"
:questionText="questionText"
buttonTypeString="shopListButton"
:buttonTypeObject="shopListButton"
groupName="chooseShop"
textPosition="text-start" />
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<div class="text-center">
<textBlock
v-if="mobileFeeApplies && isMobileSelected"
@ -150,7 +133,6 @@ import serviceZipModalQuestion from "@/layouts/service-location/service-zip-moda
import appointmentTypeQuestion from "@/layouts/service-location/appointment-type-question/appointment-type-question";
import shopQuestion from "@/layouts/service-location/shop-question/shop-question";
import shopQuestionPopup from "@/layouts/service-location/shop-question/shop-question-popup";
import buttonQuestion from "@/digital-components/button-question/button-question.vue";
import shopListButton from "@/layouts/service-location/shop-question/shop-list-button/shop-list-button";
import { getAvailabilityRating } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
@ -913,7 +895,6 @@ export default {
loadingModal,
contentGroupModal,
shopQuestionPopup,
buttonQuestion,
textBlock,
},
};
@ -926,10 +907,6 @@ export default {
@include media-breakpoint-up(md) {
padding: 0 0.75rem;
}
@include media-breakpoint-up(xl) {
width: 33.3333333%;
flex: 0 0 auto;
}
}
}
}

View file

@ -1,5 +1,5 @@
<template>
<div class="text-center">
<div class="text-left">
<div class="update-zip-text-link">
<textLink
id="serviceZipLinkPromptId"

View file

@ -2,11 +2,11 @@
<transition name="fade" mode="out-in">
<baseInputButton
v-bind="$props"
buttonWrapperClasses="list-group base-input-button list-button rounded-3 d-flex flex-column w-100 mb-2"
buttonWrapperClasses="list-group base-input-button rounded-pill list-button d-flex flex-column w-100 mb-2"
v-model="selectedValue">
<div
:aria-label="buttonLabel"
class="button-content list-button-content d-flex flex-column justify-content-center py-3 px-4 p-md-4">
class="button-content list-button-content rounded-pill d-flex flex-column justify-content-center py-3 px-4 p-md-4">
<div class="row-one">
<span class="m-0 button-label-copy text-truncate" :class="textPosition">
{{ buttonLabel }}
@ -144,10 +144,10 @@ export default {
position: relative;
background: $white;
transition: all 150ms linear;
border-radius: $border-radius-lg;
border: 1px solid $gray-500;
width: 100%;
outline: none;
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
span {
&.small {
@ -163,6 +163,7 @@ export default {
display: flex;
align-items: center;
line-height: 1.5rem;
justify-content: center;
.button-label-copy {
font-weight: 500;
@ -232,7 +233,7 @@ export default {
}
.row-two {
text-align: left;
text-align: center;
}
}
</style>

View file

@ -20,18 +20,20 @@
displayInvalidZipAlert || displayNoShopsAlert || !selectedProviderNumber
"
@footer-button-event="setZipCodeAndShop">
<serviceZipQuestion
ref="serviceZipQuestion"
class="shop-question-zipcode"
customInputId="serviceZipCode"
v-model="internalModel.zipCode"
v-on="{ 'textboxQuestionEvent.inputIdAssigned': onInputIdAssigned }"
cmsWidgetName="ServiceZipQuestionWidget"
@search-icon-click="onSearchZip"
@keydown.enter="onSearchZip"
includeSearchIcon
:isRequired="false"
:validationRules="''" />
<form @submit.prevent>
<serviceZipQuestion
ref="serviceZipQuestion"
class="shop-question-zipcode"
customInputId="serviceZipCode"
v-model="internalModel.zipCode"
v-on="{ 'textboxQuestionEvent.inputIdAssigned': onInputIdAssigned }"
cmsWidgetName="ServiceZipQuestionWidget"
@search-icon-click="onSearchZip"
@keydown.enter="onSearchZip"
includeSearchIcon
:isRequired="false"
:validationRules="''" />
</form>
<alert
ref="alertInvalidZip"
v-if="displayInvalidZipAlert"

View file

@ -16,7 +16,7 @@
:questionText="questionText"
:answers="answers"
groupName="chooseShop"
textPosition="text-start"
textPosition="text-center"
v-model="selectedProviderNumber"
isRequired
validationRules="option-required" />

View file

@ -1,14 +1,10 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<loadingModal ref="loadingModal" />
<div class="container-fluid page-container-grouped-styles">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4 mt-4">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader class="pb-4" cmsWidgetName="FunnelSubHeaderWidget" />
<div>
<textboxQuestion
@ -359,9 +355,6 @@ export default {
</script>
<style lang="scss">
.vinlookupquestion p {
margin-bottom: 0;
}
.vinlookupquestion strong {
font-weight: 500;
color: $black;

View file

@ -1,14 +1,10 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm">
<div class="container-fluid page-container-grouped-styles vehicle-damage">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4 mt-4">
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" class="mb-7" />
<alert
ref="vehicleChangeAlert"
v-if="shouldDisplayVehicleChangeAlert"
@ -18,7 +14,7 @@
:isDismissible="false" />
</div>
</div>
<div class="row justify-content-center">
<div class="row">
<div class="col-md-6">
<damageLocationQuestion
ref="damageLocation"
@ -27,8 +23,8 @@
groupName="DamageLocationQuestion" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<div class="row">
<div class="col-md-6">
<windshieldOptions
class="windshield-options"
ref="windshieldOptions"
@ -61,8 +57,8 @@
validationRules="replace-options-required" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<div class="row">
<div class="col-md-6">
<navbar
cmsWidgetName="FunnelFooterWidget"
:isForwardActionDisabled="!isContinueEnabled"

View file

@ -2,30 +2,18 @@
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm">
<div class="vehicle-parts small-question-text">
<loadingModal ref="loadingModal" />
<div class="container-fluid page-container-grouped-styles">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4 mt-4">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container page-container-grouped-styles">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader
ref="funnelSubHeader"
cmsWidgetName="FunnelSubHeaderWidget" />
cmsWidgetName="FunnelSubHeaderWidget"
class="mb-7" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4 my-5">
<alert
class="rounded border-0 shadow-sm"
alertClass="alert-warning"
cmsWidgetName="AlertWidget"
:isDismissible="false" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<div v-for="(item, i) in PartsOrQuestions" :key="i">
<!-- Render horizontal lines if there is multi-glass (aka if i > 0) -->
<hr v-if="i > 0" />
@ -63,7 +51,6 @@ import glassPartQuestion from "@/layouts/vehicle-parts/glass-part-question/glass
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
import navbar from "@/fmg-components/nav-bar/nav-bar";
import alert from "@/ux-components/alert/alert";
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
import saveProgressModalQuestion from "@/fmg-components/save-progress-modal-question/save-progress-modal-question";
// Supporting Files
@ -244,7 +231,6 @@ export default {
funnelHeader,
funnelSubHeader,
navbar,
alert,
loadingModal,
saveProgressModalQuestion,
},

View file

@ -1,13 +1,9 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" class="siteSubHeader" />
<vehicleQuestion
ref="vehicleYearQuestion"

View file

@ -60,12 +60,12 @@ export default {
&:after {
content: "";
transition: all 0.5s ease;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 8.9' xml:space='preserve'%3e%3cpath d='M8 8.9c-.2 0-.5-.1-.6-.3L.3 1.5C.1 1.4 0 1.1 0 .9 0 .7.1.4.3.3.4.1.7 0 .9 0c.2 0 .5.1.6.3L8 6.7 14.5.2c.1-.1.4-.2.6-.2.2 0 .5.1.6.3s.3.4.3.6c0 .2-.1.5-.3.6L8.6 8.6c-.1.2-.4.3-.6.3z' fill='%231474a2'/%3e%3c/svg%3e");
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'%3E%3Cpath fill='%230070D1' d='M12 0a12 12 0 1 0 0 24 12 12 0 0 0 0-24Zm6.113 11.28-5.52 5.52a.84.84 0 0 1-1.186 0l-5.52-5.52a.843.843 0 1 1 1.186-1.2L12 15.012l4.927-4.932a.843.843 0 1 1 1.186 1.2Z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right center;
margin-left: 0.5rem;
width: 16px;
height: 9px;
width: 24px;
height: 24px;
display: inline-flex;
}
&.active:after {

View file

@ -1,14 +1,10 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<loadingModal ref="loadingModal" />
<div class="container-fluid page-container-grouped-styles">
<div class="row justify-content-center">
<div class="col-md-6">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-6 col-xl-4 mt-4">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<div class="container page-container-grouped-styles">
<div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
<textboxQuestion
class="mb-2 mt-5"

View file

@ -1,10 +1,15 @@
import store from "@/store";
import { storeMutations } from "@/constants/store-mutations";
export async function savePageData(page, data) {
export async function savePageData(page, data, merge = false) {
const existingPageData = store.getters.pageData(page);
const dataToSave = Object.keys(data).length > 0 ? data : (existingPageData ?? {});
let dataToSave;
if (merge) {
dataToSave = Object.assign(existingPageData ?? {}, data ?? {});
} else {
dataToSave = Object.keys(data).length > 0 ? data : (existingPageData ?? {});
}
// Save data if non-null
store.commit(storeMutations.UPDATE_PAGE_DATA, { page: page, data: dataToSave });

View file

@ -3311,16 +3311,17 @@ export const actions = {
}
//Optional for specific YMMSs
switch (context.state.order.vehicle.make.toLowerCase()) {
case "mercedes benz":
case "volkswagen":
case "audi":
case "porsche":
return true;
default:
}
if (
context.state.order.vehicle.make.toLowerCase() === "bmw" &&
context.state.order.vehicle.year <= 2017
(context.state.order.vehicle.make.toLowerCase() === "bmw" &&
context.state.order.vehicle.year < 2010) ||
(context.state.order.vehicle.make.toLowerCase() === "volkswagen" &&
context.state.order.vehicle.year < 2010) ||
(context.state.order.vehicle.make.toLowerCase() === "audi" &&
context.state.order.vehicle.year < 2010)
)
return true;

View file

@ -4242,12 +4242,13 @@ describe("isVinOptionalVehicle", () => {
const testVehicles = [
["2017", "acura", false],
["2018", "bmw", false],
["2017", "bmw", true],
["2016", "bmw", true],
["2016", "mercedes benz", true],
["2016", "volkswagen", true],
["2016", "audi", true],
["2009", "bmw", true],
["2016", "bmw", false],
["2016", "mercedes benz", false],
["2016", "volkswagen", false],
["2016", "audi", false],
["2016", "porsche", true],
["2009", "audi", true],
];
test.each(testVehicles)(
"%s %s should skip vin lookup is %s",

View file

@ -202,21 +202,21 @@ html {
.form-test-invalid {
&.btn.btn-primary {
color: $gray-600;
background: $gray-200;
color: $white;
background: $red;
cursor: pointer;
pointer-events: all;
font-weight: $font-weight-normal;
}
&.btn.btn-primary:hover,
&.btn.btn-primary:focus {
background: $gray-200;
background: $red;
box-shadow: none;
}
&.btn.btn-primary:focus-visible {
box-shadow:
0 0 0 3px $white,
0 0 0 5.5px $gray-700;
0 0 0 5.5px $red;
}
}
}

View file

@ -8,13 +8,10 @@ body {
display: flex;
flex-direction: column;
min-height: 100dvh;
form {
> .container-fluid {
margin-bottom: -1rem;
@media screen and (min-width: 1090px) {
margin-bottom: -5rem;
}
}
}
.container {
@include media-breakpoint-up(xl) {
max-width: 1020px;
}
}
.container-fluid {
@ -90,7 +87,7 @@ body {
}
}
.modal-open:not(.prevent-modal-scroll) {
.container-fluid {
.container {
&.page-container-grouped-styles {
overflow: hidden;
height: auto;

View file

@ -1,3 +1,22 @@
.base-input-button {
&.rounded-pill {
&:not(.has-error):hover {
cursor: pointer;
&.list-button,
&.list-button-horizontal,
&.list-card {
&:not(.selected) {
position: relative;
z-index: 5;
@include box-shadow-hover($blue-300);
border-radius: 50rem;
}
}
}
}
}
.base-input-button {
&:not(.has-error):hover {
cursor: pointer;

View file

@ -204,6 +204,7 @@ $enable-important-utilities: false;
$grid-breakpoints: (
xs: 0,
md: 768px,
lg: 992px,
xl: 1200px,
xxl: 1440px,
);

View file

@ -1,14 +1,14 @@
<template>
<button
:aria-disabled="isDisabled"
class="btn d-flex align-items-center justify-content-center py-3 px-4 delay"
class="btn rounded-pill d-flex align-items-center justify-content-center py-3 px-6 delay"
:class="[
isPrimary ? 'btn-primary' : 'btn-secondary',
isFloat ? 'float-end' : '',
isLoaderDisplayed && !suppressLoader ? 'has-loader' : '',
]"
@click="clicked">
<span class="m-0">{{ this.buttonText }}</span>
<span class="m-0" v-html="buttonText"></span>
<loader
class="ms-2"
v-if="isLoaderDisplayed && !suppressLoader"
@ -63,21 +63,23 @@ export default {
<style lang="scss">
.btn {
&:first-child:active {
background-color: $red;
}
&.btn-primary {
position: relative;
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
background: $red;
border: none;
border-radius: $border-radius-lg;
color: $white;
justify-content: center;
font-weight: 500;
@media (hover: hover) {
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
background: $red;
}
&:focus {
box-shadow:
0 0 0 3px,
0 0 0 5.5px $blue-700;
0 0 0 5.5px $red;
}
&:focus, // Mouse, touch, stylus focus
&:focus-visible {
@ -85,27 +87,26 @@ export default {
outline: none;
box-shadow:
0 0 0 3px,
0 0 0 5.5px $blue-700;
0 0 0 5.5px $red;
color: $white;
background: linear-gradient(270deg, rgba(6, 87, 124, 1) 0%, rgba(6, 87, 124, 1) 100%);
background: $red;
}
&:disabled {
background: $gray-200 !important;
background: linear-gradient(270deg, $gray-200 0%, $gray-200 100%) !important;
color: $gray-600 !important;
background: $red !important;
color: $white !important;
font-weight: 400;
height: 48px;
border: none;
border-radius: $border-radius-lg;
cursor: pointer;
pointer-events: all;
}
&.has-loader {
color: $white;
background: $blue-700;
background: $red;
box-shadow:
0 0 0 3px,
0 0 0 5.5px $blue-700;
0 0 0 5.5px $red;
pointer-events: auto;
}
&.delay {
@ -116,15 +117,13 @@ export default {
&.btn-secondary {
position: relative;
background: transparent;
border: 1px solid $blue;
border-radius: $border-radius-lg;
color: $blue;
border: 1px solid $red;
color: $red;
font-weight: 500;
transition: all 150ms linear;
height: 3rem;
&:hover {
color: $white;
@include blue-gradient;
}
&:focus, // Mouse, touch, stylus focus
&:focus-visible {
@ -132,23 +131,20 @@ export default {
outline: none;
box-shadow:
0 0 0 3px $white,
0 0 0 5.5px $blue-700;
0 0 0 5.5px $red;
color: $white;
@include blue-gradient;
}
&:disabled {
background: transparent;
color: $gray-550 !important;
color: $red !important;
font-weight: 400;
height: 48px;
border: 1px solid $gray-550;
border-radius: $border-radius-lg;
border: 1px solid $red;
cursor: pointer;
pointer-events: all;
}
&.has-loader {
color: $white;
@include blue-gradient;
pointer-events: none;
}
&.delay {
@ -160,7 +156,6 @@ export default {
position: relative;
background: $green-100;
border: 1px solid $green-400;
border-radius: $border-radius-lg;
color: $black;
font-weight: 500;
transition: all 150ms linear;
@ -185,13 +180,11 @@ export default {
font-weight: 400;
height: 48px;
border: 1px solid $gray-550;
border-radius: $border-radius-lg;
cursor: pointer;
pointer-events: all;
}
&.has-loader {
color: $white;
@include blue-gradient;
pointer-events: none;
}
&.delay {

View file

@ -43,6 +43,7 @@ export default {
<style lang="scss">
.list-button-horizontal {
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
input[type="radio"],
input[type="checkbox"] {
position: absolute;

View file

@ -1,7 +1,7 @@
<template>
<baseInputButton
v-bind="$props"
buttonWrapperClasses="list-group base-input-button list-button rounded-3 d-flex flex-column w-100 mb-2"
buttonWrapperClasses="list-group base-input-button list-button rounded-pill d-flex flex-column w-100 mb-2"
v-model="selectedValue">
<div
:aria-label="buttonLabel"
@ -102,10 +102,11 @@ export default {
position: relative;
background: $white;
transition: all 150ms linear;
border-radius: $border-radius-lg;
border: 1px solid $gray-500;
width: 100%;
outline: none;
border-radius: 50rem;
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
span {
&.small {

View file

@ -76,6 +76,7 @@ export default {
}
.list-card {
border: 1px solid $gray-500;
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
&.has-error {
input[type="checkbox"],

View file

@ -64,10 +64,9 @@ export default {
<style lang="scss">
a {
color: $blue;
text-underline-offset: 4px; //Per Devyn. This can't be documented in Figma so there is a comment with the Prototype mocks on the Quote page in Figma
text-decoration: none;
line-height: 2;
padding: 0 0 4px 0;
font-weight: 500;
max-width: fit-content;
&:hover {
color: $blue-700;
@ -81,10 +80,13 @@ a {
&.navigation-link,
&.new-window-link {
font-size: 0.875rem;
color: $black;
color: $blue;
line-height: 26px;
white-space: nowrap;
align-items: center;
font-family: UrbanistSemibold;
font-weight: 600;
text-decoration: none;
@include media-breakpoint-up(md) {
font-size: 1rem;
}