From 831d4f8ecd859957b31f10180fbc22410fc54d1b Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 4 Mar 2025 09:38:04 -0500 Subject: [PATCH 001/110] CASH-276 CASH-276 initial changes to add heavy truck --- src/constants/store-mutations.js | 1 + src/constants/vehicle-categories.js | 6 +++ src/layouts/vehicle/vehicle.vue | 73 +++++++++++++++++++++++++++-- src/store/index.js | 19 +++++++- 4 files changed, 93 insertions(+), 6 deletions(-) diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index dceeac63e..a88f5dddb 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -9,6 +9,7 @@ const storeMutations = { UPDATE_MAKE: "updateMake", UPDATE_MODEL: "updateModel", UPDATE_STYLE: "updateStyle", + UPDATE_VEHICLE_SUBTYPE: "updateVehicleSubType", UPDATE_CAR_ID: "updateCarId", UPDATE_VEHICLE_CATEGORY: "updateVehicleCategory", UPDATE_VEHICLE_IMAGE_URL: "updateVehicleImageUrl", diff --git a/src/constants/vehicle-categories.js b/src/constants/vehicle-categories.js index 37ffcf5e1..9300f47e2 100644 --- a/src/constants/vehicle-categories.js +++ b/src/constants/vehicle-categories.js @@ -9,3 +9,9 @@ const vehicleCategories = { }; export { vehicleCategories }; + +const vehicleSubTypes = { + HEAVY_TRUCK: "HEAVY TRUCK", +}; + +export { vehicleSubTypes }; diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index 12e7268fa..4edccc675 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -48,6 +48,19 @@ validationRules="style-required" placeHolderText="Select style" customDropdownId="styleQuestionField" /> + +
+
+ +
+ @@ -557,4 +615,9 @@ export default { margin-top: 1.5rem; margin-bottom: 0; } +.separator-line { + grid-area: 2/1/2/8; + border-top: 1px solid $gray-500; + margin: 0.5rem 0; +} diff --git a/src/store/index.js b/src/store/index.js index 3408c0b26..2f3772255 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -61,6 +61,7 @@ const getDefaultState = () => { make: null, model: null, style: null, + vehicleSubType: null, carId: null, category: null, vin: null, @@ -210,6 +211,9 @@ export const mutations = { updateStyle(state, style) { state.order.vehicle.style = style; }, + updateVehicleSubType(state, vehicleSubType) { + state.order.vehicle.vehicleSubType = vehicleSubType; + }, updateCarId(state, carId) { state.order.vehicle.carId = carId; }, @@ -2121,6 +2125,7 @@ export const actions = { model: vehicle.model, style: vehicle.style, vin: vehicle.vin, + vehicleSubType: vehicle.vehicleSubType, registration: { firstName: vehicle.registration.firstName, lastName: vehicle.registration.lastName, @@ -2330,7 +2335,18 @@ export const actions = { // Vehicle saveVehicle( context, - { year, make, model, style, carId, category, imageUrl, imageVifNumber, imageVifColor } + { + year, + make, + model, + style, + vehicleSubType, + carId, + category, + imageUrl, + imageVifNumber, + imageVifColor, + } ) { if ( context.state.order.vehicle.year != year || @@ -2346,6 +2362,7 @@ export const actions = { context.commit(storeMutations.UPDATE_MAKE, make); context.commit(storeMutations.UPDATE_MODEL, model); context.commit(storeMutations.UPDATE_STYLE, style); + context.commit(storeMutations.UPDATE_VEHICLE_SUBTYPE, vehicleSubType); context.commit(storeMutations.UPDATE_CAR_ID, carId); context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, category); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, imageUrl); From eb33bd46ffb0905e186268f0a3ab30a50b593163 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 4 Mar 2025 10:23:22 -0500 Subject: [PATCH 002/110] prettier --- src/layouts/vehicle/vehicle.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index 4edccc675..fafa4c079 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -426,7 +426,9 @@ export default { ); }, showHeavyTruck() { - return this.vehicleSubType === vehicleSubTypes.HEAVY_TRUCK && !this.displayNoServiceAlert; + return ( + this.vehicleSubType === vehicleSubTypes.HEAVY_TRUCK && !this.displayNoServiceAlert + ); }, }, methods: { From e1c5fc83c446ee1aacbb27688807c23d3a6d6351 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Mon, 17 Mar 2025 13:34:40 -0400 Subject: [PATCH 003/110] CASH-276 CASH-276 add call to location service to determine if a zip code has a provider that can service heavy truck --- src/constants/endpoints.js | 4 ++++ src/constants/store-actions.js | 1 + src/layouts/vehicle/vehicle.vue | 26 ++++++++++++++++++-------- src/store/index.js | 9 +++++++++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 29d36d091..976696976 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -188,6 +188,10 @@ const endpoints = { url: "/account/api/v1/account/bill-to-account-number", method: "GET", }, + ClosestApplicableShops: { + url: "/location/api/v1/location/closest-applicable-shops", + method: "GET", + }, }; export { endpoints }; diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 6c6ba62b7..4a5e713f4 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -53,6 +53,7 @@ const storeActions = { GET_INSURANCE_COMPANY_LIST: "getInsuranceCompanyList", GET_BILL_TO_ACCOUNT_NUMBER: "getBillToAccountNumber", GET_RECAL_PARTS_AND_SAVE_TO_LINE_ITEMS: "getRecalPartsAndSaveToLineItems", + GET_CLOSEST_APPLICABLE_SHOPS: "getClosestApplicableShops", // Analytics LOG_EXPERIMENT_EXPOSURE_AND_UPDATE_STORE: "logExperimentExposureAndUpdateStore", diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index fafa4c079..521793adc 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -49,7 +49,7 @@ placeHolderText="Select style" customDropdownId="styleQuestionField" /> -
+
Date: Mon, 17 Mar 2025 13:43:49 -0400 Subject: [PATCH 004/110] prettier prettier --- src/layouts/vehicle/vehicle.vue | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index 521793adc..bab3a92e8 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -427,9 +427,7 @@ export default { ); }, isHeavyTruck() { - return ( - this.vehicleSubType === vehicleSubTypes.HEAVY_TRUCK && this.canSafeliteService - ); + return this.vehicleSubType === vehicleSubTypes.HEAVY_TRUCK && this.canSafeliteService; }, }, methods: { From b9f14fdb2d270836c241dc0f8f41c4def2caf5c9 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 18 Mar 2025 03:55:00 -0400 Subject: [PATCH 005/110] CASH-276 CASH-276 persist canSafeliteService field --- src/constants/store-mutations.js | 1 + src/layouts/vehicle/vehicle.vue | 10 +++++++++- src/store/index.js | 6 ++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 6a5873e83..509988c6e 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -17,6 +17,7 @@ const storeMutations = { UPDATE_VEHICLE_IMAGE_COLOR: "updateVehicleImageColor", UPDATE_VEHICLE_VIN: "updateVehicleVin", UPDATE_VEHICLE: "updateVehicle", + UPDATE_VEHICLE_CAN_SAFELITE_SERVICE: "updateVehicleCanSafeliteService", UPDATE_IS_REPAIR: "updateIsRepair", UPDATE_NUMBER_OF_CHIPS: "updateNumberOfChips", diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index bab3a92e8..da4ee6689 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -140,7 +140,7 @@ export default { modelOptions: [], styleOptions: [], displayNoServiceAlert: false, - canSafeliteService: false, + canSafeliteService: this.canSafeliteServiceFromStore(), }; }, @@ -316,6 +316,9 @@ export default { }, watch: { + serviceZipCode(newValue, oldValue) { + this.resetAlert(); + }, async selectedYear(year) { this.resetAlert(); this.makeOptions = []; @@ -323,6 +326,7 @@ export default { this.selectedModel = null; this.selectedStyle = null; this.vehicleSubType = null; + this.canSafeliteService = false; this.carId = null; if (year) { const result = await this.getMakeOptions(year); @@ -496,6 +500,7 @@ export default { vehicleSubType: this.vehicleSubType, carId: this.carId, category: this.category, + canSafeliteService: this.canSafeliteService, imageUrl: this.imageUrl, imageVifNumber: this.imageVifNumber, imageVifColor: this.imageVifColor, @@ -553,6 +558,9 @@ export default { selectedStylefromStore() { return store.getters.externalParameterVehicle.style ?? store.getters.vehicle.style; }, + canSafeliteServiceFromStore() { + return store.getters.vehicle.canSafeliteService ?? false; + }, async getMakeOptions(year) { return await baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_VEHICLE_MAKES, diff --git a/src/store/index.js b/src/store/index.js index aaee4c996..08307ec12 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -65,6 +65,7 @@ const getDefaultState = () => { carId: null, category: null, vin: null, + canSafeliteService: null, imageUrl: null, imageVifNumber: null, imageColor: null, @@ -221,6 +222,9 @@ export const mutations = { updateVehicleCategory(state, category) { state.order.vehicle.category = category; }, + updateVehicleCanSafeliteService(state, canSafeliteService) { + state.order.vehicle.canSafeliteService = canSafeliteService; + }, updateVehicleImageUrl(state, imageUrl) { state.order.vehicle.imageUrl = imageUrl; }, @@ -2357,6 +2361,7 @@ export const actions = { vehicleSubType, carId, category, + canSafeliteService, imageUrl, imageVifNumber, imageVifColor, @@ -2379,6 +2384,7 @@ export const actions = { context.commit(storeMutations.UPDATE_VEHICLE_SUBTYPE, vehicleSubType); context.commit(storeMutations.UPDATE_CAR_ID, carId); context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, category); + context.commit(storeMutations.UPDATE_VEHICLE_CAN_SAFELITE_SERVICE, canSafeliteService); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, imageUrl); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, imageVifNumber); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, imageVifColor); From 0becaee2030c8c3ed92a787c367c0c26a9ed5246 Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Wed, 19 Mar 2025 17:08:58 +0530 Subject: [PATCH 006/110] CASH-278 pass additional param isHeavyTruckVehicle to provider endpoint to filter heavy truck shops --- src/store/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/store/index.js b/src/store/index.js index 08307ec12..02677051b 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -51,6 +51,7 @@ import { import { externalParameterStatus } from "@/constants/external-parameters"; import { experimentSettings } from "@/constants/experiments"; import experimentMixin from "@/mixins/experiment-mixin.js"; +import { vehicleSubTypes } from "@/constants/vehicle-categories.js"; // Export State const getDefaultState = () => { @@ -845,6 +846,9 @@ export const getters = { return false; }, + isHeavyTruckVehicle: (state) => { + return state.order.vehicle.vehicleSubType === vehicleSubTypes.HEAVY_TRUCK; + }, isMobileAppointment: (state) => { return state.order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE; }, @@ -1858,6 +1862,8 @@ export const actions = { if (windshieldPartWithRecal) { url += `/${windshieldPartWithRecal.partNumber}`; } + //heavy truck vehicle + url += `/${context.getters.isHeavyTruckVehicle}`; return globalMethods.callHttpClient({ method: endpoints.GetProviders.method, From acb64c788fc87cecae15675cf38482754abd5e2c Mon Sep 17 00:00:00 2001 From: CarlNation Date: Wed, 19 Mar 2025 14:01:21 -0400 Subject: [PATCH 007/110] CASH-320 CASH-320 pass isHeavyTruck flag to serviceability endpoint to determine mobile availability --- src/store/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/store/index.js b/src/store/index.js index 02677051b..19fb5316a 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1836,6 +1836,8 @@ export const actions = { endPoint += `&${glassPieces}`; } + endPoint += `&isHeavyTruckVehicle=${context.getters.isHeavyTruckVehicle}`; + return globalMethods.callHttpClient({ method: endpoints.GetServiceabilityDetails.method, endpoint: endPoint, From 29d183bc708c335760bcd6b1b8e29c492b3d23bd Mon Sep 17 00:00:00 2001 From: CarlNation Date: Thu, 20 Mar 2025 14:46:29 -0400 Subject: [PATCH 008/110] CASH-320 CASH-320 isInsurance=false from the load session should be allowed to update vuex --- src/store/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/index.js b/src/store/index.js index da849c127..bc978304a 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -720,7 +720,7 @@ export const mutations = { // if we're loading a session and we do not have a provider number yet, then set isInsurance to null so that // a service package is not selected by default on the quote page. if ( - !sessionInformation.order.payment.isInsurance && + (sessionInformation.order.payment.isInsurance === null || sessionInformation.order.payment.isInsurance === undefined) && !sessionInformation.order.serviceLocation.provider?.providerNumber ) { state.order.payment.isInsurance = null; From 6be76bad881a88a74c07af8916c3fb99a3786273 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Thu, 20 Mar 2025 14:51:12 -0400 Subject: [PATCH 009/110] prettier --- src/store/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/store/index.js b/src/store/index.js index bc978304a..bdf6c48a7 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -720,7 +720,8 @@ export const mutations = { // if we're loading a session and we do not have a provider number yet, then set isInsurance to null so that // a service package is not selected by default on the quote page. if ( - (sessionInformation.order.payment.isInsurance === null || sessionInformation.order.payment.isInsurance === undefined) && + (sessionInformation.order.payment.isInsurance === null || + sessionInformation.order.payment.isInsurance === undefined) && !sessionInformation.order.serviceLocation.provider?.providerNumber ) { state.order.payment.isInsurance = null; From 87e59177ecc50506c5b1c0a5bd361b0f125a543a Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Thu, 20 Mar 2025 16:25:11 -0400 Subject: [PATCH 010/110] CASH-405 for CASH-152: more font tweaks to fix bold issue --- src/experiment-components/date-picker-for-pricing-by-day.vue | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/experiment-components/date-picker-for-pricing-by-day.vue b/src/experiment-components/date-picker-for-pricing-by-day.vue index bfdc30470..b61649ad4 100644 --- a/src/experiment-components/date-picker-for-pricing-by-day.vue +++ b/src/experiment-components/date-picker-for-pricing-by-day.vue @@ -1175,7 +1175,9 @@ export default { &.selectable-day label span { text-decoration: none; color: $gray-600; - font-weight: 600; + font-weight: 400; + font-family: 'AvertaSemibold'; + &.price { color: $green; } @@ -1183,6 +1185,7 @@ export default { &.upch-day label span.price { color: $gray-600; font-weight: 400; + font-family: $font-family-sans-serif; } input[type="radio"] { &:focus + label, From 7e7b4d70635038e69f5e196e0fdfa25a973bf747 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Thu, 20 Mar 2025 16:38:41 -0400 Subject: [PATCH 011/110] CASH-405 for CASH-152: stupid prettier pickiness --- src/experiment-components/date-picker-for-pricing-by-day.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/experiment-components/date-picker-for-pricing-by-day.vue b/src/experiment-components/date-picker-for-pricing-by-day.vue index b61649ad4..cad976cf7 100644 --- a/src/experiment-components/date-picker-for-pricing-by-day.vue +++ b/src/experiment-components/date-picker-for-pricing-by-day.vue @@ -1176,7 +1176,7 @@ export default { text-decoration: none; color: $gray-600; font-weight: 400; - font-family: 'AvertaSemibold'; + font-family: "AvertaSemibold"; &.price { color: $green; From e7a8013ca4b9109eaae5fcc39a4dceff0d396be4 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Fri, 21 Mar 2025 07:41:11 -0400 Subject: [PATCH 012/110] CASH-414 for CASH-152: Fix to ensure upcharge is excluded from base price --- src/constants/part-number-strings.js | 1 + src/layouts/schedule/schedule.vue | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/constants/part-number-strings.js b/src/constants/part-number-strings.js index d373ba016..488bf0742 100644 --- a/src/constants/part-number-strings.js +++ b/src/constants/part-number-strings.js @@ -5,6 +5,7 @@ const partNumberStrings = { DONATION: "DONATION", // Fees RECYCLE_FEE: "RECYCLE FEE", + PRICING_BY_DAY_UPCHARGE: "PREMAPPT GEN", }; export { partNumberStrings }; diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index 48876d5e8..da3b3a69b 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -250,9 +250,15 @@ export default { isRecalibrationOnOrder && shouldHideRecalibration ? getItemsWithoutRecalParts(lineItems.glassParts) : (lineItems.glassParts ?? []); + const supportingItemsFromStore = lineItems?.supportingItems; const supportingItemsWithoutFees = baseMixin.methods.filterOutCertainPartTypesOrNumbers( lineItems.supportingItems, - { partNumbersToRemove: [partNumberStrings.RECYCLE_FEE] } + { + partNumbersToRemove: [ + partNumberStrings.RECYCLE_FEE, + partNumberStrings.PRICING_BY_DAY_UPCHARGE, + ], + } ); const lineItemsToBePriced = { glassParts: glassParts, @@ -266,8 +272,8 @@ export default { // Check to see if includePricingByDayUpcharge should already be set (based on order lineItems) let includePricingByDayUpcharge = false; - if (supportingItemsWithoutFees) { - const pricingByDayUpchargeFeeIndex = supportingItemsWithoutFees.findIndex( + if (supportingItemsFromStore) { + const pricingByDayUpchargeFeeIndex = supportingItemsFromStore?.findIndex( (item) => item.partType == PRICING_BY_DAY_PART_TYPE ); if (pricingByDayUpchargeFeeIndex > -1) { From 9f3b901ce2fb58bcc7408c495de18274cf9fb164 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 21 Mar 2025 10:06:14 -0400 Subject: [PATCH 013/110] CASH-415 CASH-415 do not get the pricing by day part or price it when insurance or in the control variation of the experiment --- src/layouts/schedule/schedule.vue | 53 ++++++++++++++++--------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index da3b3a69b..5c9708eac 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -306,7 +306,7 @@ export default { }); // Get pricingByDayUpcharge needed for Pricing By Day - const pricingByDayUpchargePartPromise = getPricingByDayPartWithPrice(); + const pricingByDayUpchargePartPromise = showPricingByDay ? getPricingByDayPartWithPrice() : null; const premiumFeePromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_MOBILE_PREMIUM_FEE, @@ -354,10 +354,7 @@ export default { const resultMap = await settleAllPromises(promiseResultMap); - const pricingByDayUpcharge = await baseMixin.methods.getTotalLineItemPrice( - resultMap.pricingByDayUpchargePart, - false - ); + const pricingByDayUpcharge = showPricingByDay ? await baseMixin.methods.getTotalLineItemPrice(resultMap.pricingByDayUpchargePart,false) : null; const datePickerInitialData = resultMap.datePickerInitialData; datePickerInitialData.pricingByDayBasePrice = pricingByDayBasePrice; @@ -626,24 +623,26 @@ export default { const supportingItems = this.getSupportingItems(); // if we have a pricing by day upcharge, then save/update supporting items with it - const pricingByDayUpchargeFeeIndex = supportingItems?.findIndex( - (item) => item.partType == PRICING_BY_DAY_PART_TYPE - ); + if (this.showPricingByDay) { + const pricingByDayUpchargeFeeIndex = supportingItems?.findIndex( + (item) => item.partType == PRICING_BY_DAY_PART_TYPE + ); - if (this.includePricingByDayUpcharge) { - if (pricingByDayUpchargeFeeIndex > -1) { - supportingItems[pricingByDayUpchargeFeeIndex].laborAmount = - this.pricingByDayUpchargeLineItem.laborAmount; - supportingItems[pricingByDayUpchargeFeeIndex].sellingPrice = - this.pricingByDayUpchargeLineItem.sellingPrice; - supportingItems[pricingByDayUpchargeFeeIndex].kitPrice = - this.pricingByDayUpchargeLineItem.kitPrice; + if (this.includePricingByDayUpcharge) { + if (pricingByDayUpchargeFeeIndex > -1) { + supportingItems[pricingByDayUpchargeFeeIndex].laborAmount = + this.pricingByDayUpchargeLineItem.laborAmount; + supportingItems[pricingByDayUpchargeFeeIndex].sellingPrice = + this.pricingByDayUpchargeLineItem.sellingPrice; + supportingItems[pricingByDayUpchargeFeeIndex].kitPrice = + this.pricingByDayUpchargeLineItem.kitPrice; + } else { + supportingItems.push(this.pricingByDayUpchargeLineItem); + } } else { - supportingItems.push(this.pricingByDayUpchargeLineItem); - } - } else { - if (pricingByDayUpchargeFeeIndex >= 0) { - supportingItems.splice(pricingByDayUpchargeFeeIndex, 1); + if (pricingByDayUpchargeFeeIndex >= 0) { + supportingItems.splice(pricingByDayUpchargeFeeIndex, 1); + } } } @@ -672,12 +671,14 @@ export default { } // if it's not a mobile and/or premium early bird, then make sure we remove any that may have been added - const removePremiumFeeIndex = supportingItems.findIndex( - (item) => item.partType == PREMIUM_FEE_PART_TYPE - ); + if (this.showPricingByDay) { + const removePremiumFeeIndex = supportingItems.findIndex( + (item) => item.partType == PREMIUM_FEE_PART_TYPE + ); - if (removePremiumFeeIndex >= 0) { - supportingItems.splice(removePremiumFeeIndex, 1); + if (removePremiumFeeIndex >= 0) { + supportingItems.splice(removePremiumFeeIndex, 1); + } } } From 73152239eed0e0c559e4894278803ff046e62b3e Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 21 Mar 2025 10:11:49 -0400 Subject: [PATCH 014/110] prettier --- src/layouts/schedule/schedule.vue | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index 5c9708eac..5ecf88ac0 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -306,7 +306,9 @@ export default { }); // Get pricingByDayUpcharge needed for Pricing By Day - const pricingByDayUpchargePartPromise = showPricingByDay ? getPricingByDayPartWithPrice() : null; + const pricingByDayUpchargePartPromise = showPricingByDay + ? getPricingByDayPartWithPrice() + : null; const premiumFeePromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_MOBILE_PREMIUM_FEE, @@ -354,7 +356,12 @@ export default { const resultMap = await settleAllPromises(promiseResultMap); - const pricingByDayUpcharge = showPricingByDay ? await baseMixin.methods.getTotalLineItemPrice(resultMap.pricingByDayUpchargePart,false) : null; + const pricingByDayUpcharge = showPricingByDay + ? await baseMixin.methods.getTotalLineItemPrice( + resultMap.pricingByDayUpchargePart, + false + ) + : null; const datePickerInitialData = resultMap.datePickerInitialData; datePickerInitialData.pricingByDayBasePrice = pricingByDayBasePrice; From aee40ae184070286a73efc5ab0c62c760df795f5 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 21 Mar 2025 10:55:20 -0400 Subject: [PATCH 015/110] CASH-415 CASH-415 wrong block check --- src/layouts/schedule/schedule.vue | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index 5ecf88ac0..63e4a3775 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -678,14 +678,12 @@ export default { } // if it's not a mobile and/or premium early bird, then make sure we remove any that may have been added - if (this.showPricingByDay) { - const removePremiumFeeIndex = supportingItems.findIndex( - (item) => item.partType == PREMIUM_FEE_PART_TYPE - ); + const removePremiumFeeIndex = supportingItems.findIndex( + (item) => item.partType == PREMIUM_FEE_PART_TYPE + ); - if (removePremiumFeeIndex >= 0) { - supportingItems.splice(removePremiumFeeIndex, 1); - } + if (removePremiumFeeIndex >= 0) { + supportingItems.splice(removePremiumFeeIndex, 1); } } From 6e2970ad8609ff5c516f78e5253681c1d849fcd3 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Fri, 21 Mar 2025 12:04:52 -0400 Subject: [PATCH 016/110] CASH-404 desktop updates. --- .../dropdown-question/dropdown-question.vue | 3 +++ src/experiment-components/service-package-radio.vue | 4 ++-- .../funnel-sub-header/funnel-sub-header.vue | 1 + .../save-progress-modal-question.vue | 3 +++ .../save-progress-popup-question.vue | 8 +++++++- src/layouts/quote/quote.vue | 9 ++++++--- src/layouts/schedule/schedule.vue | 3 +++ .../service-location/shop-question/shop-question.vue | 4 ++++ src/styles/common-typography-styles.scss | 2 ++ src/styles/mixins/customMixins.scss | 9 +++++++++ src/styles/ux-variables.scss | 2 +- src/ux-components/list-button/list-button.vue | 2 +- src/ux-components/text-link/text-link.vue | 4 ++++ 13 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/digital-components/dropdown-question/dropdown-question.vue b/src/digital-components/dropdown-question/dropdown-question.vue index 70bf6c90c..8b3cf023f 100644 --- a/src/digital-components/dropdown-question/dropdown-question.vue +++ b/src/digital-components/dropdown-question/dropdown-question.vue @@ -142,6 +142,9 @@ export default { border: 1px solid $gray-500; border-radius: 0.5rem; min-height: 3rem; + @include media-breakpoint-up(md) { + min-height: 3.5rem; + } &:focus, &:focus-visible { box-shadow: 0 0 0 2.5px $blue; diff --git a/src/experiment-components/service-package-radio.vue b/src/experiment-components/service-package-radio.vue index f0eb991c6..440bcbb58 100644 --- a/src/experiment-components/service-package-radio.vue +++ b/src/experiment-components/service-package-radio.vue @@ -169,10 +169,10 @@ export default { display: flex; flex-direction: column; &:first-child { - margin: 1rem 0.5rem 0 0; + margin: 1rem 1rem 0 0; } &:last-child { - margin: 1rem 0 0 0.5rem; + margin: 1rem 0 0 1rem; } } diff --git a/src/fmg-components/funnel-sub-header/funnel-sub-header.vue b/src/fmg-components/funnel-sub-header/funnel-sub-header.vue index fa8aea13f..e296206ac 100644 --- a/src/fmg-components/funnel-sub-header/funnel-sub-header.vue +++ b/src/fmg-components/funnel-sub-header/funnel-sub-header.vue @@ -89,6 +89,7 @@ p.small { } .sub-text { margin: 0; + @include responsive-heading-md(0.875rem, 1rem); } .justify-content-start { diff --git a/src/fmg-components/save-progress-modal-question/save-progress-modal-question.vue b/src/fmg-components/save-progress-modal-question/save-progress-modal-question.vue index 76ee7c6a2..ef4677371 100644 --- a/src/fmg-components/save-progress-modal-question/save-progress-modal-question.vue +++ b/src/fmg-components/save-progress-modal-question/save-progress-modal-question.vue @@ -148,6 +148,9 @@ export default { margin: 0 auto; transition: all 150ms linear; background: none; + @include media-breakpoint-up(md) { + font-size: 1rem; + } &.btn { &.btn-secondary { diff --git a/src/fmg-components/save-progress-popup-question/save-progress-popup-question.vue b/src/fmg-components/save-progress-popup-question/save-progress-popup-question.vue index 34ef44e71..ce6b45118 100644 --- a/src/fmg-components/save-progress-popup-question/save-progress-popup-question.vue +++ b/src/fmg-components/save-progress-popup-question/save-progress-popup-question.vue @@ -164,6 +164,9 @@ export default { margin: 0 auto 1.5rem auto; transition: all 150ms linear; background: none; + @include media-breakpoint-up(md) { + font-size: 1rem; + } &:hover, &:active, @@ -241,7 +244,10 @@ export default { button.btn.skip-button { padding: 0; order: 2; - font-size: 1rem; + font-size: 0.875rem; + @include media-breakpoint-up(md) { + font-size: 1rem; + } } .modal-disclaimer { font-size: 0.75rem; diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 615662013..49d116946 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -57,7 +57,7 @@ alertClass="alert-info" /> 2) { - return "col-xl-8"; + return "col-xl-10"; } else { return "col-xl-6"; } @@ -775,7 +775,7 @@ export default { }; - diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index 2704cdaf6..90bd3d727 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -744,6 +744,9 @@ export default { &:focus { outline: 1px solid $blue; } + @include media-breakpoint-up(md) { + font-size: 1rem; + } } } .funnel-sub-header { diff --git a/src/layouts/service-location/shop-question/shop-question.vue b/src/layouts/service-location/shop-question/shop-question.vue index a15d8bb0b..98d7e537e 100644 --- a/src/layouts/service-location/shop-question/shop-question.vue +++ b/src/layouts/service-location/shop-question/shop-question.vue @@ -271,6 +271,10 @@ export default { margin-top: 1rem; text-align: center; + a { + @include responsive-heading-md(0.875rem, 1rem); + } + .button-question { .question-text { margin-top: 0.5rem; diff --git a/src/styles/common-typography-styles.scss b/src/styles/common-typography-styles.scss index 6a9c4f893..fc3e87896 100644 --- a/src/styles/common-typography-styles.scss +++ b/src/styles/common-typography-styles.scss @@ -8,6 +8,7 @@ body { //Headings //add helper fw-bold to any element to get bold style (500) + h1, .h1 { line-height: 1.325; @@ -36,6 +37,7 @@ h5, .h5 { line-height: 1.325; font-weight: 400; + @include responsive-heading-md(1.25rem, 1.625rem); } h6, diff --git a/src/styles/mixins/customMixins.scss b/src/styles/mixins/customMixins.scss index d0670ad6c..33649319f 100644 --- a/src/styles/mixins/customMixins.scss +++ b/src/styles/mixins/customMixins.scss @@ -8,3 +8,12 @@ @mixin box-shadow-hover($color) { box-shadow: 0 0 0 4px $color; } + +//Define heading sizes for medium breakpoints +@mixin responsive-heading-md($font-size, $md-font-size) { + font-size: $font-size; + + @include media-breakpoint-up(md) { + font-size: $md-font-size; + } +} \ No newline at end of file diff --git a/src/styles/ux-variables.scss b/src/styles/ux-variables.scss index df984b224..5c4045fd7 100644 --- a/src/styles/ux-variables.scss +++ b/src/styles/ux-variables.scss @@ -141,7 +141,7 @@ $h1-font-size: $font-size-base * 3; $h2-font-size: $font-size-base * 2.625; $h3-font-size: $font-size-base * 2; $h4-font-size: $font-size-base * 1.625; -$h5-font-size: $font-size-base * 1.25; +//$h5-font-size: $font-size-base * 1.25;// Font size set in customMixins.scss $h6-font-size: $font-size-base * 0.875; //Border Radius diff --git a/src/ux-components/list-button/list-button.vue b/src/ux-components/list-button/list-button.vue index 1ebc46cc7..d31f20e5d 100644 --- a/src/ux-components/list-button/list-button.vue +++ b/src/ux-components/list-button/list-button.vue @@ -5,7 +5,7 @@ v-model="selectedValue">
+ class="button-content list-button-content d-flex flex-column justify-content-center py-3 px-4 p-md-4"> {{ buttonLabel }} diff --git a/src/ux-components/text-link/text-link.vue b/src/ux-components/text-link/text-link.vue index 30cd2d7e5..7c19d7911 100644 --- a/src/ux-components/text-link/text-link.vue +++ b/src/ux-components/text-link/text-link.vue @@ -80,10 +80,14 @@ a { } &.navigation-link, &.new-window-link { + font-size: .875rem; color: $black; line-height: 26px; white-space: nowrap; align-items: center; + @include media-breakpoint-up(md) { + font-size: 1rem; + } } &.new-window-link { margin-bottom: 1.5rem; From 9b336d3c4feafcacd08ff97e6b4a6d4cca59b8d3 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Mon, 24 Mar 2025 09:25:29 -0400 Subject: [PATCH 017/110] Format code. --- src/styles/mixins/customMixins.scss | 2 +- src/ux-components/text-link/text-link.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/styles/mixins/customMixins.scss b/src/styles/mixins/customMixins.scss index 33649319f..e5f0caa86 100644 --- a/src/styles/mixins/customMixins.scss +++ b/src/styles/mixins/customMixins.scss @@ -16,4 +16,4 @@ @include media-breakpoint-up(md) { font-size: $md-font-size; } -} \ No newline at end of file +} diff --git a/src/ux-components/text-link/text-link.vue b/src/ux-components/text-link/text-link.vue index 7c19d7911..9283c08e7 100644 --- a/src/ux-components/text-link/text-link.vue +++ b/src/ux-components/text-link/text-link.vue @@ -80,7 +80,7 @@ a { } &.navigation-link, &.new-window-link { - font-size: .875rem; + font-size: 0.875rem; color: $black; line-height: 26px; white-space: nowrap; From c9c5d29b3d3c7cc0c959336274c1b4b0b86e1f43 Mon Sep 17 00:00:00 2001 From: Chris Redelinghuys Date: Mon, 24 Mar 2025 11:49:33 -0400 Subject: [PATCH 018/110] CASH-413: Update recycle fee on location change --- .../service-location-helper.js | 45 +++++++++++++++++++ .../mobile-location-modal-questions.spec.js | 20 +++++++++ .../mobile-location-modal-questions.vue | 8 ++++ .../service-location/service-location.vue | 43 +++++++++++++----- .../service-zip-modal-question.spec.js | 20 +++++++++ .../service-zip-modal-question.vue | 8 ++++ 6 files changed, 134 insertions(+), 10 deletions(-) diff --git a/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js index 99b200037..7a9ac00d0 100644 --- a/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js +++ b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js @@ -1,5 +1,6 @@ import { storeActions } from "@/constants/store-actions"; import baseMixin from "@/mixins/base-mixin.js"; +import { partNumberStrings } from "@/constants/part-number-strings"; export async function getPricedMobileFeePart(serviceZipCode, pageNameToLog) { if (!serviceZipCode) { @@ -42,6 +43,50 @@ export async function getPricedMobileFeePart(serviceZipCode, pageNameToLog) { return pricingResults[0]; } +export async function getPricedRecycleFeePart(serviceZipCode, pageNameToLog) { + if (!serviceZipCode) { + return null; + } + + const zipCodeData = await getZipCodeData(serviceZipCode); + + // Get supporting items + const supportingItems = await baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.GET_SUPPORTING_ITEMS, + null, + pageNameToLog, + false + ); + + if ( + supportingItems.data === null || + supportingItems.data === undefined || + supportingItems.data === "" + ) { + return null; + } + + const recycleFeePart = supportingItems.data.find( + (item) => item.partNumber === partNumberStrings.RECYCLE_FEE + ); + + if (recycleFeePart) { + // Get the Recycle Fee Part Price + const pricingResults = await baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA, + { + availableLineItems: [recycleFeePart], + serviceZipCode: serviceZipCode, + serviceZipCodeCtu: zipCodeData.zipCodeCtu, + }, + pageNameToLog, + false + ); + + return pricingResults[0]; + } +} + export async function getServiceabilityDetails(serviceZipCode, lineItems, pageNameToLog) { // Get the Mobile Fee Part return await baseMixin.methods.dispatchStoreActionWithLogging( diff --git a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.spec.js b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.spec.js index f38262005..3e2873fa1 100644 --- a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.spec.js +++ b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.spec.js @@ -106,6 +106,23 @@ const mockGetPricedMobileFeePart = (mockServiceZipCode) => { return Promise.resolve(mobileFeePart); }; +const mockGetPricedRecycleFeePart = (mockServiceZipCode) => { + let recycleFeePart = {}; + + if (mockServiceZipCode === "43235") { + recycleFeePart = { + partNumber: "RECYCLE FEE", + description: "RECYCLE FEE", + partType: "FEE", + laborAmount: 39.99, + sellingPrice: 0, + kitPrice: 0, + }; + } + + return Promise.resolve(recycleFeePart); +}; + const mockGetServiceabilityDetails = (mockServiceZipCode) => { const serviceabilityDetails = { isGlassServiceableInshop: true, @@ -123,6 +140,9 @@ jest.mock( getPricedMobileFeePart: jest.fn((mockServiceZipCode) => { return mockGetPricedMobileFeePart(mockServiceZipCode); }), + getPricedRecycleFeePart: jest.fn((mockServiceZipCode) => { + return mockGetPricedRecycleFeePart(mockServiceZipCode); + }), getServiceabilityDetails: jest.fn((mockServiceZipCode) => { return mockGetServiceabilityDetails(mockServiceZipCode); }), diff --git a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue index 4672cca7f..0d7a82248 100644 --- a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue +++ b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue @@ -82,6 +82,7 @@ import vehicleProtectedQuestion from "@/layouts/service-location/mobile-location import { deepClone } from "@/helpers/object-helper"; import { getPricedMobileFeePart, + getPricedRecycleFeePart, getServiceabilityDetails, getBillToAccountNumber, } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper"; @@ -267,6 +268,12 @@ export default { "service-location" ); + // retrieve recycle fee part + const recycleFeePart = await getPricedRecycleFeePart( + serviceZipCode, + "service-location" + ); + // retrieve serviceability details const serviceabilityDetails = await getServiceabilityDetails( serviceZipCode, @@ -280,6 +287,7 @@ export default { // update content related to service zip code this.$emit("updated-mobile-fee-part", mobileFeePart); + this.$emit("updated-recycle-fee-part", recycleFeePart); this.$emit("updated-serviceability", serviceabilityDetails.data); this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase); this.$emit("updated-mobile-ctu", zipCodeData.zipCodeCtu); diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index ddb765da3..56c76bb2d 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -17,6 +17,7 @@ ref="serviceZipCodeQuestion" :mobileFeePart="mobileFeePart" @updated-mobile-fee-part="setMobileFeePart" + @updated-recycle-fee-part="setRecycleFeePart" @updated-serviceability="setServiceabilityDetails" @updated-contains-military-base="setContainsMilitaryBase" @updated-bill-to-account-number="setBillToAccountNumber" @@ -90,6 +91,7 @@ :mobileFeePart="mobileFeePart" :mobileFeeApplies="mobileFeeApplies" @updated-mobile-fee-part="setMobileFeePart" + @updated-recycle-fee-part="setRecycleFeePart" @updated-serviceability="setServiceabilityDetails" @updated-contains-military-base="setContainsMilitaryBase" @updated-mobile-ctu="setCtuForMobile" @@ -195,6 +197,7 @@ export default { selectedAppointmentType: this.getSelectedAppointmentType(), selectedProvider: this.getSelectedProvider(), mobileFeePart: null, + recycleFeePart: null, zipContainsMilitaryBase: false, zipCodeCtu: null, billToAccountNumber: null, @@ -480,6 +483,9 @@ export default { setMobileFeePart(mobileFeePart) { this.mobileFeePart = mobileFeePart; }, + setRecycleFeePart(recycleFeePart) { + this.recycleFeePart = recycleFeePart; + }, //creating async function as the computed property can not directly handle asynchronous operations or promises. async setMobileLocationQuestions(newValue) { var newZipCode = newValue.addressQuestions.zipCode; @@ -592,6 +598,7 @@ export default { }, updateAndSaveSupportingItems() { let supportingItems = store.getters.lineItems.supportingItems; + let shouldSaveSupportingItems = false; supportingItems = !supportingItems && this.isMobileStaticRecalibrationApplicable @@ -603,6 +610,21 @@ export default { return; } + // update recyle fee price + if (this.recycleFeePart) { + const recycleFeeIndex = supportingItems.findIndex( + (item) => item.partNumber == partNumberStrings.RECYCLE_FEE + ); + if (recycleFeeIndex >= 0) { + supportingItems[recycleFeeIndex].laborAmount = this.recycleFeePart.laborAmount; + supportingItems[recycleFeeIndex].sellingPrice = + this.recycleFeePart.sellingPrice; + supportingItems[recycleFeeIndex].kitPrice = this.recycleFeePart.kitPrice; + + shouldSaveSupportingItems = true; + } + } + // if we have a mobile fee, then save/update supporting items if (this.selectedAppointmentType == "Mobile") { const mobileFeeIndex = supportingItems.findIndex( @@ -617,11 +639,7 @@ export default { if (this.mobileFeePart !== null) supportingItems.push(this.mobileFeePart); } - this.dispatchStoreAction( - this.storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING, - supportingItems, - false - ); + shouldSaveSupportingItems = true; } else { // if it's not a mobile, then make sure we remove any that may have been added const removeMobileFeeIndex = supportingItems?.findIndex( @@ -630,13 +648,18 @@ export default { if (removeMobileFeeIndex >= 0) { supportingItems.splice(removeMobileFeeIndex, 1); - this.dispatchStoreAction( - this.storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING, - supportingItems, - false - ); + shouldSaveSupportingItems = true; } } + + // Use shouldSaveSupportingItems flag to determine if we need to save supporting items. Prevents unnecessary/multiple saves + if (shouldSaveSupportingItems) { + this.dispatchStoreAction( + this.storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING, + supportingItems, + false + ); + } }, async forwardButtonAction() { this.navigatingForward = true; diff --git a/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.spec.js b/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.spec.js index ed8a811ed..b1231991b 100644 --- a/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.spec.js +++ b/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.spec.js @@ -32,6 +32,23 @@ const mockGetPricedMobileFeePart = (mockServiceZipCode) => { return Promise.resolve(mobileFeePart); }; +const mockGetPricedRecycleFeePart = (mockServiceZipCode) => { + let recycleFeePart = {}; + + if (mockServiceZipCode === "43235") { + recycleFeePart = { + partNumber: "RECYCLE FEE", + description: "RECYCLE FEE", + partType: "FEE", + laborAmount: 39.99, + sellingPrice: 0, + kitPrice: 0, + }; + } + + return Promise.resolve(recycleFeePart); +}; + const mockGetServiceabilityDetails = (mockServiceZipCode) => { const serviceabilityDetails = { isGlassServiceableInshop: true, @@ -49,6 +66,9 @@ jest.mock( getPricedMobileFeePart: jest.fn((mockServiceZipCode) => { return mockGetPricedMobileFeePart(mockServiceZipCode); }), + getPricedRecycleFeePart: jest.fn((mockServiceZipCode) => { + return mockGetPricedRecycleFeePart(mockServiceZipCode); + }), getServiceabilityDetails: jest.fn((mockServiceZipCode) => { return mockGetServiceabilityDetails(mockServiceZipCode); }), diff --git a/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue b/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue index 24d063e5e..a2ab4134e 100644 --- a/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue +++ b/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue @@ -45,6 +45,7 @@ import alert from "@/ux-components/alert/alert"; import { getPricedMobileFeePart, + getPricedRecycleFeePart, getServiceabilityDetails, getBillToAccountNumber, } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper"; @@ -164,6 +165,12 @@ export default { "service-location" ); + // retrieve recycle fee part + const recycleFeePart = await getPricedRecycleFeePart( + serviceZipCode, + "service-location" + ); + // retrieve serviceability details const serviceabilityDetails = await getServiceabilityDetails( serviceZipCode, @@ -177,6 +184,7 @@ export default { // update content related to service zip code this.$emit("updated-mobile-fee-part", mobileFeePart); + this.$emit("updated-recycle-fee-part", recycleFeePart); this.$emit("updated-serviceability", serviceabilityDetails.data); this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase); this.$emit("updated-bill-to-account-number", billToAccountNumber); From c539fc6a0b86235f1fde923932daa88e8c09b618 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Mon, 24 Mar 2025 13:24:59 -0400 Subject: [PATCH 019/110] CASH-404 desktop updates. --- .../textbox-question/textbox-question.vue | 7 +++++-- src/fmg-components/funnel-sub-header/funnel-sub-header.vue | 2 +- src/layouts/quote/quote.vue | 2 +- .../shop-question/shop-list-button/shop-list-button.vue | 2 +- .../service-location/shop-question/shop-question.vue | 2 +- src/styles/common-typography-styles.scss | 2 +- src/styles/mixins/customMixins.scss | 7 +++++-- 7 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/digital-components/textbox-question/textbox-question.vue b/src/digital-components/textbox-question/textbox-question.vue index 4eb81ab0b..e6d75fee1 100644 --- a/src/digital-components/textbox-question/textbox-question.vue +++ b/src/digital-components/textbox-question/textbox-question.vue @@ -325,8 +325,11 @@ export default { border: 1px solid $gray-500; border-radius: 0.5rem; min-height: 3rem; - max-height: 48px; - padding: 12px 16px; + padding: 0.75rem 1rem; + @include media-breakpoint-up(md) { + padding: 1rem; + min-height: 3.5rem; + } &::placeholder { color: $gray-500; } diff --git a/src/fmg-components/funnel-sub-header/funnel-sub-header.vue b/src/fmg-components/funnel-sub-header/funnel-sub-header.vue index e296206ac..f42a90972 100644 --- a/src/fmg-components/funnel-sub-header/funnel-sub-header.vue +++ b/src/fmg-components/funnel-sub-header/funnel-sub-header.vue @@ -89,7 +89,7 @@ p.small { } .sub-text { margin: 0; - @include responsive-heading-md(0.875rem, 1rem); + @include responsive-font-size-md(0.875rem, 1rem); } .justify-content-start { diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 49d116946..c062069af 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -794,6 +794,6 @@ export default { display: block; } :deep(.promo-modal-question a) { - @include responsive-heading-md(0.875rem, 1rem); + @include responsive-font-size-md(0.875rem, 1rem); } diff --git a/src/layouts/service-location/shop-question/shop-list-button/shop-list-button.vue b/src/layouts/service-location/shop-question/shop-list-button/shop-list-button.vue index e46b02a96..20accf43b 100644 --- a/src/layouts/service-location/shop-question/shop-list-button/shop-list-button.vue +++ b/src/layouts/service-location/shop-question/shop-list-button/shop-list-button.vue @@ -6,7 +6,7 @@ v-model="selectedValue">
+ class="button-content list-button-content d-flex flex-column justify-content-center py-3 px-4 p-md-4">
{{ buttonLabel }} diff --git a/src/layouts/service-location/shop-question/shop-question.vue b/src/layouts/service-location/shop-question/shop-question.vue index 98d7e537e..4a7818834 100644 --- a/src/layouts/service-location/shop-question/shop-question.vue +++ b/src/layouts/service-location/shop-question/shop-question.vue @@ -272,7 +272,7 @@ export default { text-align: center; a { - @include responsive-heading-md(0.875rem, 1rem); + @include responsive-font-size-md(0.875rem, 1rem); } .button-question { diff --git a/src/styles/common-typography-styles.scss b/src/styles/common-typography-styles.scss index fc3e87896..a6ab8289f 100644 --- a/src/styles/common-typography-styles.scss +++ b/src/styles/common-typography-styles.scss @@ -37,7 +37,7 @@ h5, .h5 { line-height: 1.325; font-weight: 400; - @include responsive-heading-md(1.25rem, 1.625rem); + @include responsive-font-size-md(1.25rem, 1.625rem); } h6, diff --git a/src/styles/mixins/customMixins.scss b/src/styles/mixins/customMixins.scss index e5f0caa86..9e058e6ee 100644 --- a/src/styles/mixins/customMixins.scss +++ b/src/styles/mixins/customMixins.scss @@ -9,11 +9,14 @@ box-shadow: 0 0 0 4px $color; } -//Define heading sizes for medium breakpoints -@mixin responsive-heading-md($font-size, $md-font-size) { +// Typography size mixin for medium breakpoints +// Use this to adjust font size for medium breakpoint +@mixin responsive-font-size-md($font-size, $md-font-size) { font-size: $font-size; @include media-breakpoint-up(md) { font-size: $md-font-size; } } +// Usage: @include responsive-font-size-md(mobile-font-size-in-rem, desktop-font-size-in-rem); +// Example: @include responsive-font-size-md(0.875rem, 1rem); \ No newline at end of file From 6fbe62a9ac8e33e94828988ec6ecae952a4f6f3d Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Mon, 24 Mar 2025 13:34:10 -0400 Subject: [PATCH 020/110] Format code. --- src/styles/mixins/customMixins.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/styles/mixins/customMixins.scss b/src/styles/mixins/customMixins.scss index 9e058e6ee..62abcc82d 100644 --- a/src/styles/mixins/customMixins.scss +++ b/src/styles/mixins/customMixins.scss @@ -19,4 +19,4 @@ } } // Usage: @include responsive-font-size-md(mobile-font-size-in-rem, desktop-font-size-in-rem); -// Example: @include responsive-font-size-md(0.875rem, 1rem); \ No newline at end of file +// Example: @include responsive-font-size-md(0.875rem, 1rem); From 3e551bc7a095ae7565c0767f9bdd421ad02ca527 Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Wed, 26 Mar 2025 19:52:00 +0530 Subject: [PATCH 021/110] CASH-134 Adding mocked response for the api call to display error and success message. --- src/layouts/confirmation/confirmation.vue | 32 ++++++++++++++++------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 8c4d6cf1a..1a6a4d99e 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -526,17 +526,9 @@ export default { // try to call API to add donation to order // TEMP DUMMY CALL TO SIMULATE SUCCESS OR ERROR FROM API CALL - // TO BE REPLACED BY REAL CALL LATER - const donationResponse = await this.dispatchStoreActionWithLogging( - storeActions.LOOKUP_VIN_BY_PLATE, - { licensePlate: plateTemp, licenseState: "OH" }, - "test", - false - ).catch((error) => { - return error; - }); + const donationResponse = this.createMockedResponse(amount); - if (donationResponse?.status == "200") { + if (donationResponse?.wasSuccessful) { this.showDonationSuccess = true; this.showDonationError = false; const donationResponse = await baseMixin.methods.dispatchStoreAction( @@ -554,6 +546,26 @@ export default { ); } }, + //mocked response. should be removed once integrate with actual api call. + createMockedResponse(amount) { + let result; + + switch (amount) { + case 1: + result = { wasSuccessful: true, wasLocked: false }; + break; + case 3: + result = { wasSuccessful: false, wasLocked: true }; + break; + case 5: + result = { wasSuccessful: false, wasLocked: false }; + break; + default: + result = { wasSuccessful: null, wasLocked: null }; // Default case if amount doesn't match + } + + return result; + }, }, watch: { donationAmount(newValue) { From 02591b39ce6af67c4b44ab47408e5c6ed13e4589 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Thu, 27 Mar 2025 11:31:22 -0400 Subject: [PATCH 022/110] CASH-403 WIP --- src/App.vue | 4 + .../funnel-footer/funnel-footer.spec.js | 0 .../funnel-footer/funnel-footer.vue | 83 +++++++++++++++++++ .../funnel-header/funnel-header.vue | 5 +- src/styles/common-styles.scss | 6 +- 5 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 src/fmg-components/funnel-footer/funnel-footer.spec.js create mode 100644 src/fmg-components/funnel-footer/funnel-footer.vue diff --git a/src/App.vue b/src/App.vue index b5be4ec86..a0d5cad86 100644 --- a/src/App.vue +++ b/src/App.vue @@ -5,6 +5,7 @@ + @@ -12,6 +13,7 @@ import { handleAnyComponentFocus } from "@/helpers/button-question-focus-helper"; import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue"; import { showFmgLoadingModal } from "@/helpers/loading-modal-helper"; +import funnelFooter from "@/fmg-components/funnel-footer/funnel-footer.vue"; export default { name: "app", @@ -32,6 +34,8 @@ export default { }, components: { loadingModal, + funnelFooter, + }, }; diff --git a/src/fmg-components/funnel-footer/funnel-footer.spec.js b/src/fmg-components/funnel-footer/funnel-footer.spec.js new file mode 100644 index 000000000..e69de29bb diff --git a/src/fmg-components/funnel-footer/funnel-footer.vue b/src/fmg-components/funnel-footer/funnel-footer.vue new file mode 100644 index 000000000..5a1a76bc1 --- /dev/null +++ b/src/fmg-components/funnel-footer/funnel-footer.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/src/fmg-components/funnel-header/funnel-header.vue b/src/fmg-components/funnel-header/funnel-header.vue index 22d9e77fa..30c326178 100644 --- a/src/fmg-components/funnel-header/funnel-header.vue +++ b/src/fmg-components/funnel-header/funnel-header.vue @@ -3,7 +3,7 @@ class="funnel-header d-flex justify-content-center align-items-center flex-column" v-if="imageSrc"> Safelite logo - +
+ Cookie preferences Date: Mon, 31 Mar 2025 13:36:24 -0400 Subject: [PATCH 031/110] Formatting --- src/store/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index 13c12cd94..317eab88c 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1967,8 +1967,6 @@ export const actions = { */ let result; - - switch (donationAmount) { case 1: result = { wasSuccessful: true, wasLocked: false }; From 1f1890566ac0df11127e1dd64d8d88983caeb6d9 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Mon, 31 Mar 2025 14:08:01 -0400 Subject: [PATCH 032/110] Format code. --- src/fmg-components/funnel-header/menu-modal/menu-modal.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/fmg-components/funnel-header/menu-modal/menu-modal.vue b/src/fmg-components/funnel-header/menu-modal/menu-modal.vue index 8e5c21708..9b5ebb536 100644 --- a/src/fmg-components/funnel-header/menu-modal/menu-modal.vue +++ b/src/fmg-components/funnel-header/menu-modal/menu-modal.vue @@ -57,7 +57,9 @@ alt="Your privacy choices" /> - Cookie preferences + + Cookie preferences + Date: Mon, 31 Mar 2025 14:50:53 -0400 Subject: [PATCH 033/110] CASH-442 update cookie link. Test. --- .../funnel-header/menu-modal/menu-modal.vue | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/fmg-components/funnel-header/menu-modal/menu-modal.vue b/src/fmg-components/funnel-header/menu-modal/menu-modal.vue index 9b5ebb536..9c77cec35 100644 --- a/src/fmg-components/funnel-header/menu-modal/menu-modal.vue +++ b/src/fmg-components/funnel-header/menu-modal/menu-modal.vue @@ -56,26 +56,22 @@ src="~@/assets/img/icons/ccpa-icon.svg" alt="Your privacy choices" /> - - - Cookie preferences - - - - -
+ + + + +
@@ -181,6 +177,9 @@ export default { height: 1rem; margin-left: 0.5rem; } + :deep(.navigation-link) { + margin-bottom: 1.5rem; + } } .modal-fullscreen { width: 100vw; From ed00b2fc60e1f503f127752133698943462f8bf3 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Mon, 31 Mar 2025 14:52:23 -0400 Subject: [PATCH 034/110] Format code. --- .../funnel-header/menu-modal/menu-modal.vue | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/fmg-components/funnel-header/menu-modal/menu-modal.vue b/src/fmg-components/funnel-header/menu-modal/menu-modal.vue index 9c77cec35..4dc07f3a5 100644 --- a/src/fmg-components/funnel-header/menu-modal/menu-modal.vue +++ b/src/fmg-components/funnel-header/menu-modal/menu-modal.vue @@ -56,22 +56,22 @@ src="~@/assets/img/icons/ccpa-icon.svg" alt="Your privacy choices" /> - - - - -
+ + + + +
From 2e3af146e6506bad8fd55327eb079ec89d69eb60 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Mon, 31 Mar 2025 15:32:02 -0400 Subject: [PATCH 035/110] Add page-skipping logic to quote --- src/constants/experiments.js | 2 + src/constants/package-names.js | 6 ++ src/helpers/service-package-helper.js | 8 +- src/layouts/quote/quote.vue | 84 ++++++++++++++++--- .../service-package-question.vue | 5 ++ 5 files changed, 88 insertions(+), 17 deletions(-) diff --git a/src/constants/experiments.js b/src/constants/experiments.js index 09dfc4140..d64849466 100644 --- a/src/constants/experiments.js +++ b/src/constants/experiments.js @@ -2,6 +2,7 @@ const experimentUniverses = { CONCEPT_FUNNEL: "ConceptFunnel", RECAL_PRICE_REMOVAL: "NextGen_RecalPriceRemoval", MSR: "MSR", + IGQ_SkipQuote: "NextGen_IGQSkipToInsurance", }; const experimentSettings = { @@ -22,6 +23,7 @@ const experimentSettings = { WAITLIST_THRESHOLD_DAYS: "Waitlist_Threshold_Days", PRICING_BY_DAY: "DisplayPricingByDay", FOSTER_LOVE: "DisplayFosterLove", + SKIP_TO_INSURANCE: "SkipToInsurance", }; const experimentTriggers = { diff --git a/src/constants/package-names.js b/src/constants/package-names.js index 221a75a49..0115daa61 100644 --- a/src/constants/package-names.js +++ b/src/constants/package-names.js @@ -3,3 +3,9 @@ export const packageNames = { TIER_TWO: "TierTwo", TIER_THREE: "TierThree", }; + +export const externalParamPackageLabels = { + GLASS_ONLY: "glassonly", + STANDARD: "standard", + PREMIUM: "premium", +}; diff --git a/src/helpers/service-package-helper.js b/src/helpers/service-package-helper.js index fcbe4aee3..6e0a6743a 100644 --- a/src/helpers/service-package-helper.js +++ b/src/helpers/service-package-helper.js @@ -1,6 +1,6 @@ import { partTypeStrings } from "@/constants/part-type-strings"; import { damageLocationsSelected as glassLocations } from "@/constants/damage-locations-selected"; -import { packageNames } from "@/constants/package-names"; +import { packageNames, externalParamPackageLabels } from "@/constants/package-names"; import baseMixin from "@/mixins/base-mixin.js"; import { getItemsWithoutRecalParts } from "@/helpers/recal-helper"; import { @@ -238,9 +238,9 @@ export function getHighestFullySatisfiedTier(glassToReplace, availableLineItems, export function getPackageNameByType(packageType) { const package_names = { - glassonly: packageNames.TIER_ONE, - standard: packageNames.TIER_TWO, - premium: packageNames.TIER_THREE, + [externalParamPackageLabels.GLASS_ONLY]: packageNames.TIER_ONE, + [externalParamPackageLabels.STANDARD]: packageNames.TIER_TWO, + [externalParamPackageLabels.PREMIUM]: packageNames.TIER_THREE, }; return package_names[packageType] || null; } diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 615662013..0ff86494d 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -134,7 +134,7 @@ import { storeActions } from "@/constants/store-actions"; import { deepClone } from "@/helpers/object-helper"; import store from "@/store"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; -import { experimentSettings } from "@/constants/experiments"; +import { experimentSettings, experimentUniverses } from "@/constants/experiments"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; import { Form, defineRule } from "vee-validate"; @@ -154,12 +154,18 @@ import { findLineItemsWithPartType, } from "@/helpers/service-package-helper"; import { nextTick } from "vue"; -import { packageNames } from "@/constants/package-names"; +import { packageNames, externalParamPackageLabels } from "@/constants/package-names"; import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; import { containsRecalParts } from "@/helpers/recal-helper"; import { externalParameterStatus } from "@/constants/external-parameters"; import { saveQuote } from "@/helpers/heritage-integration/order-helper.js"; import { getBoolFromString } from "@/helpers/boolean-helper"; +import { + getSessionKeyValue, + getUserIdValue, + getDeviceIdValue, +} from "@/helpers/heritage-integration/cookie-helper"; +import { showFmgLoadingModal } from "@/helpers/loading-modal-helper"; defineRule("option-required", required(errorMessages.OPTION_REQUIRED)); @@ -189,6 +195,31 @@ export default { "quote" ); + const shouldExposeSkipQuote = store.getters.isRecalibrationOnOrder; + const skipQuoteExperiment = store.getters.applicationUser.experiments.find( + (e) => e.universeName === experimentUniverses.IGQ_SkipQuote + ); + const hasExposedSkipQuote = skipQuoteExperiment?.isExposed; + + const shouldSendExposeRequest = + shouldExposeSkipQuote && !hasExposedSkipQuote && skipQuoteExperiment; + + if (shouldSendExposeRequest) { + // Don't await -- response is not needed so can fire fully asynchronously. + baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.LOG_EXPERIMENT_EXPOSURE_AND_UPDATE_STORE, + { + userId: getUserIdValue(), + deviceId: getDeviceIdValue(), + sessionKey: getSessionKeyValue(), + pageName: to.query.fmgPage, + experiment: skipQuoteExperiment, + }, + "quote", + false + ); + } + const promiseResultMap = [ { resultKey: "cmsContent", @@ -213,6 +244,12 @@ export default { const isEmailInStoreOnPageLoad = emailFromStore?.length > 0; const showSaveProgressPopup = isEmailInStoreOnPageLoad ? false : true; const showSaveProgressModal = isEmailInStoreOnPageLoad ? false : true; + const shouldSkipToInsurance = + getBoolFromString( + experimentMixin.methods.getSettingValue(experimentSettings.SKIP_TO_INSURANCE) + ) && + shouldExposeSkipQuote && + !hasExposedSkipQuote; const lineItems = deepClone(store.getters.order.lineItems); lineItems.vaps = lineItems.vaps ?? []; @@ -302,6 +339,7 @@ export default { vm.availableLineItems = pricingResults; vm.holdParentAccountNumber = holdParentAccountNumber; vm.holdBillToAccountNumber = holdBillToAccountNumber; + vm.skipToInsurance = shouldSkipToInsurance; if (revalidatePromoResponse) { const revalidateAlerts = buildToastMessagesFromRevalidateOrValidatePromoResponse( @@ -434,21 +472,16 @@ export default { } } - // did user intentionally select insurance? - vm.isInsuranceSelected = true; - vm.servicePackage = store.getters.externalParameterQuote.servicePackage; - await nextTick(); + const insuranceSelection = true; + const servicePackage = store.getters.externalParameterQuote.servicePackage; if ( - vm.servicePackage != null && + servicePackage != null && isExternalParameter === externalParameterStatus.ACTIVE ) { - const isValid = await baseMixin.methods.isFormValid(vm.$refs.theForm); - if (isValid) { - baseMixin.methods.ResetExternalParamsAndHideModal(); - vm.forwardButtonAction(); - } + await vm.skip(insuranceSelection, servicePackage); } + baseMixin.methods.ResetExternalParamsAndHideModal(); } else { if (externalThreshold) thresholdToUse = externalThreshold; @@ -467,6 +500,11 @@ export default { baseMixin.methods.ResetExternalParamsAndHideModal(); } } + + if (vm.skipToInsurance && !vm.showSaveProgressPopup) { + // skip ahead only if no email popup. + await vm.skip(true, externalParamPackageLabels.GLASS_ONLY); + } }); }, data() { @@ -482,6 +520,7 @@ export default { showSaveProgressModal: null, isSaveProgressComplete: null, packageNumber: null, + skipToInsurance: null, }; }, mounted() { @@ -584,8 +623,13 @@ export default { updateSaveProgressAsSaved() { this.showSaveProgressModal = false; }, - closeSaveProgressPopup() { + async closeSaveProgressPopup() { this.showSaveProgressPopup = false; + + if (this.skipToInsurance) { + // skip ahead now if in IGQ skip experiment + await this.skip(true, externalParamPackageLabels.GLASS_ONLY); + } }, forwardButtonAction() { this.dispatchStoreAction( @@ -729,6 +773,20 @@ export default { this.pushEventToGA("quote", this.GaActions.SERVICE_PACKAGE_PRICE, eventLabel, true); }); }, + async skip(insuranceSelection, packageSelection) { + this.isInsuranceSelected = insuranceSelection; + this.servicePackage = packageSelection; + + // Allow selections to filter through sub-logic + await nextTick(); + await nextTick(); + + const isValid = await baseMixin.methods.isFormValid(this.$refs.theForm); + if (isValid) { + showFmgLoadingModal(true); + await this.forwardButtonAction(); + } + }, }, watch: { lineItemsCloneForWatcher: { diff --git a/src/layouts/quote/service-package-question/service-package-question.vue b/src/layouts/quote/service-package-question/service-package-question.vue index ab4772107..68f031768 100644 --- a/src/layouts/quote/service-package-question/service-package-question.vue +++ b/src/layouts/quote/service-package-question/service-package-question.vue @@ -102,6 +102,11 @@ export default { this.$emit("servicePackageDiscountSelected", supportingItems); }, + servicePackage(newValue) { + if (newValue !== null) { + this.selectDefaultPackage(); + } + }, }, computed: { nullSafeAvailableLineItems() { From 8f0c5ada0433551924006466ab407ffa1f49aeab Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Mon, 31 Mar 2025 15:32:24 -0400 Subject: [PATCH 036/110] Loading modal refactor --- src/mixins/base-mixin.js | 6 ++++++ src/router/index.js | 3 --- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 6fd6075ab..151d17dd9 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -230,6 +230,12 @@ export default { return "widget-name-" + this.cmsWidgetName; }, }, + + mounted() { + if (!store.getters.externalParameterState?.isExternalParameter) { + showFmgLoadingModal(false); + } + }, }; function encodeUriData(payload) { diff --git a/src/router/index.js b/src/router/index.js index 2230a652d..345790734 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -433,9 +433,6 @@ router.afterEach(async (to, from) => { await saveSession({ pageNameToLog: to.query.fmgPage }); } } - if (!store.getters.externalParameterState?.isExternalParameter) { - showFmgLoadingModal(false); - } // Push page view to GA analyticsMixin.methods.pushPageViewToGA(); From 6e0f9d8a20b986a94f4d84b9799dc53ea83b0615 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Mon, 31 Mar 2025 15:38:03 -0400 Subject: [PATCH 037/110] Unit test quirk --- src/layouts/quote/quote.spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/layouts/quote/quote.spec.js b/src/layouts/quote/quote.spec.js index a87d6b0a6..49b90cfb3 100644 --- a/src/layouts/quote/quote.spec.js +++ b/src/layouts/quote/quote.spec.js @@ -836,6 +836,7 @@ describe("quote.vue", () => { nextFunction ); await nextTick(); + await nextTick(); expect(nextFunction).toHaveBeenCalled(); expect(baseMixin.methods.isFormValid).toHaveBeenCalled(); expect(baseMixin.methods.isFormValid()).toBe(true); From 383eb001df9dc30bdf8de9f365b2e2ea6795c7c0 Mon Sep 17 00:00:00 2001 From: Johnny shultz Date: Tue, 1 Apr 2025 10:21:21 -0400 Subject: [PATCH 038/110] CASH-133 CASH-133 successfully added a donation to cart on confirmation using mock api call --- src/constants/cart-item-types.js | 1 + src/constants/part-type-strings.js | 1 + src/fmg-components/cart/cart.vue | 46 ++++++++++++++++++++++- src/layouts/confirmation/confirmation.vue | 7 +++- src/store/index.js | 10 ++--- 5 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/constants/cart-item-types.js b/src/constants/cart-item-types.js index d8ab9f66f..2f84d22c2 100644 --- a/src/constants/cart-item-types.js +++ b/src/constants/cart-item-types.js @@ -11,6 +11,7 @@ const cartItemTypes = { EARLY_BIRD: "EARLY BIRD", SUPPLIES_REPAIR: "SUPPLIES-REPAIR", SERVICE_PACKAGE_DISCOUNT: "SERVICE PACKAGE DISCOUNT", + DONATION: "DONATION", }; export { cartItemTypes }; diff --git a/src/constants/part-type-strings.js b/src/constants/part-type-strings.js index 4681e2776..94e8598bd 100644 --- a/src/constants/part-type-strings.js +++ b/src/constants/part-type-strings.js @@ -10,6 +10,7 @@ const partTypeStrings = { REPAIR_FEE: "REPAIR FEE", EARLY_BIRD: "EARLY BIRD", SERVICE_PACKAGE_DISCOUNT: "SERVICE PACKAGE DISCOUNT", + DONATION: "DONATION", }; export { partTypeStrings }; diff --git a/src/fmg-components/cart/cart.vue b/src/fmg-components/cart/cart.vue index f569c11d4..e5d0a8645 100644 --- a/src/fmg-components/cart/cart.vue +++ b/src/fmg-components/cart/cart.vue @@ -207,6 +207,7 @@ export default { isNoComp: Boolean, isExpandedOnLoad: Boolean, isMSRFeeApplicable: Boolean, + donationAmount: Number, }, data() { return { @@ -403,7 +404,9 @@ export default { } return [ ...(this.lineItems.glassParts ?? []), - ...(this.lineItems.supportingItems ?? []), + ...(this.lineItems.supportingItems.filter( + (item) => item.partType !== partTypeStrings.DONATION + ) ?? []), ...(this.availableVaps ?? []), ]; }, @@ -466,6 +469,10 @@ export default { }); } + if (this.donationCartItem) { + cartItems.push(this.donationCartItem); + } + return cartItems; }, }, @@ -1064,6 +1071,43 @@ export default { return promoCartItems; }, + showDonationCartItem() { + if (this.donationAmount !== 0) { + return true; + } else { + return false; + } + }, + donationCartItemName() { + return this.getCmsContent("DonationCartTextWidget", "Text"); + }, + donationCartItem() { + if (!this.lineItems || !this.lineItems.supportingItems) { + return null; + } + + const donationLineItem = this.lineItems.supportingItems.find( + (item) => item.partType === partTypeStrings.DONATION + ); + + if (donationLineItem && donationLineItem.sellingPrice > 0) { + return { + name: this.donationCartItemName, + category: cartItemCategories.SUPPORTING_ITEMS, + cartItemType: cartItemTypes.DONATION, + isDisplayed: true, + isRemovable: false, + subTotal: donationLineItem.sellingPrice, + salesTax: 0, + lineItems: [], + isCoveredByInsurance: cartItemTypesCoveredByInsurance.includes( + cartItemTypes.DONATION + ), + }; + } + + return null; + }, removeLinkText() { return this.getCmsContent("RemoveCartItemTextWidget", "Text"); }, diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index f6810f726..12415226b 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -63,7 +63,9 @@ :isExpandedOnLoad="false" :isItac="isItac" :isNoComp="isNoComp" - :isMSRFeeApplicable="isMSRFeeApplicable" /> + :isMSRFeeApplicable="isMSRFeeApplicable" + :donationAmount="donationAmount" + @update-donation-amount="updateDonationAmount" />
Date: Tue, 1 Apr 2025 10:28:18 -0400 Subject: [PATCH 039/110] CASH-403 WIP footer updates. --- src/fmg-components/funnel-footer/funnel-footer.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fmg-components/funnel-footer/funnel-footer.vue b/src/fmg-components/funnel-footer/funnel-footer.vue index 677bb1f81..a980a5682 100644 --- a/src/fmg-components/funnel-footer/funnel-footer.vue +++ b/src/fmg-components/funnel-footer/funnel-footer.vue @@ -1,14 +1,14 @@ + Date: Wed, 2 Apr 2025 09:54:34 -0400 Subject: [PATCH 042/110] More cleanup --- src/fmg-components/cart/cart.vue | 18 +++++++++--------- src/layouts/confirmation/confirmation.vue | 4 +--- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/fmg-components/cart/cart.vue b/src/fmg-components/cart/cart.vue index 1cc1bb484..a4a0e0243 100644 --- a/src/fmg-components/cart/cart.vue +++ b/src/fmg-components/cart/cart.vue @@ -401,11 +401,15 @@ export default { if (!this.lineItems || this.lineItems.length < 1) { return []; } + let supportingItemsToAdd = []; + if (this.lineItems.supportingItems) { + supportingItemsToAdd = this.lineItems.supportingItems.filter( + (item) => item.partType !== partTypeStrings.DONATION + ) + } return [ ...(this.lineItems.glassParts ?? []), - ...(this.lineItems.supportingItems.filter( - (item) => item.partType !== partTypeStrings.DONATION - ) ?? []), + ...supportingItemsToAdd, ...(this.availableVaps ?? []), ]; }, @@ -1074,11 +1078,7 @@ export default { const donationLineItem = this.lineItems.supportingItems.find( (item) => item.partType === partTypeStrings.DONATION ); - if (donationLineItem?.sellingPrice !== 0) { - return true; - } else { - return false; - } + return !!donationLineItem; }, donationCartItemName() { return this.getCmsContent("DonationCartTextWidget", "Text"); @@ -1092,7 +1092,7 @@ export default { (item) => item.partType === partTypeStrings.DONATION ); - if (donationLineItem?.sellingPrice > 0) { + if (donationLineItem) { return { name: this.donationCartItemName, category: cartItemCategories.SUPPORTING_ITEMS, diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 12415226b..8e49f298d 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -63,9 +63,7 @@ :isExpandedOnLoad="false" :isItac="isItac" :isNoComp="isNoComp" - :isMSRFeeApplicable="isMSRFeeApplicable" - :donationAmount="donationAmount" - @update-donation-amount="updateDonationAmount" /> + :isMSRFeeApplicable="isMSRFeeApplicable" />
Date: Wed, 2 Apr 2025 10:04:44 -0400 Subject: [PATCH 043/110] Formatting --- src/fmg-components/cart/cart.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fmg-components/cart/cart.vue b/src/fmg-components/cart/cart.vue index a4a0e0243..2a715bc93 100644 --- a/src/fmg-components/cart/cart.vue +++ b/src/fmg-components/cart/cart.vue @@ -405,7 +405,7 @@ export default { if (this.lineItems.supportingItems) { supportingItemsToAdd = this.lineItems.supportingItems.filter( (item) => item.partType !== partTypeStrings.DONATION - ) + ); } return [ ...(this.lineItems.glassParts ?? []), From 958c6cc6ece2b344cdc266447b866c95dc5de667 Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Thu, 3 Apr 2025 14:43:52 +0530 Subject: [PATCH 044/110] CASH-134 spacing before footer text --- src/experiment-components/donation-block.vue | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/experiment-components/donation-block.vue b/src/experiment-components/donation-block.vue index c90e6af14..1710440d6 100644 --- a/src/experiment-components/donation-block.vue +++ b/src/experiment-components/donation-block.vue @@ -62,11 +62,11 @@
-
+
-

+

@@ -261,6 +261,8 @@ export default { } .alert { border: 1px solid $red; + margin-top: 0.5rem; + margin-bottom: 0.5rem; } .btn-success { background: $green-100; From e894522acbdd29d1e032b7940da54a1b1e653ad0 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Thu, 3 Apr 2025 10:12:02 -0400 Subject: [PATCH 045/110] CASH-462 | First look at order changes --- src/global-methods.js | 2 +- src/helpers/pricing-helper.js | 2 +- src/layouts/confirmation/confirmation.vue | 92 +++++++++++------------ src/store/index.js | 6 +- 4 files changed, 53 insertions(+), 49 deletions(-) diff --git a/src/global-methods.js b/src/global-methods.js index ba6cec1ec..01d0c9488 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -61,7 +61,7 @@ export default { const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO; const submittedOrder = baseMixin.methods.getSubmittedOrder(); const hasSubmittedOrder = baseMixin.methods.hasSubmittedOrder(); - const order = hasSubmittedOrder ? submittedOrder : store.getters.order; + const order = hasSubmittedOrder ? submittedOrder.order : store.getters.order; const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "FixMyGlass" }); const headers = { [headerKeys.EXPERIMENT]: JSON.stringify(store.getters.experimentSettings), diff --git a/src/helpers/pricing-helper.js b/src/helpers/pricing-helper.js index fda5b3b9c..4c87b8cf4 100644 --- a/src/helpers/pricing-helper.js +++ b/src/helpers/pricing-helper.js @@ -12,7 +12,7 @@ export function getDisplayAmountDue(lineItemsObject, includeTax = true) { export function getAmountDue(lineItemsObject, includeTax = true) { let amountDue = 0; const order = baseMixin?.methods?.hasSubmittedOrder() - ? baseMixin?.methods?.getSubmittedOrder() + ? baseMixin?.methods?.getSubmittedOrder().order : store.getters.order; if (lineItemsObject?.glassParts) { diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 8e49f298d..0aadfdf5c 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -173,8 +173,8 @@ export default { const wipersPromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_WIPERS, { - serviceZipCode: submittedOrder.serviceLocation.zipCode, - carId: submittedOrder.vehicle.carId, + serviceZipCode: submittedOrder.order.serviceLocation.zipCode, + carId: submittedOrder.order.vehicle.carId, }, "confirmation" ); @@ -203,10 +203,10 @@ export default { const resultMap = await settleAllPromises(promiseResultMap); const availableVaps = [resultMap.rainDefense, ...resultMap.wipers]; - const lineItemsFromSubmittedOrder = deepClone(submittedOrder.lineItems); + const lineItemsFromSubmittedOrder = deepClone(submittedOrder.order.lineItems); - const isNoComp = submittedOrder?.policy?.isNoComp; - const isItac = submittedOrder?.policy?.isItac; + const isNoComp = submittedOrder?.order?.policy?.isNoComp; + const isItac = submittedOrder?.order?.policy?.isItac; const isRecalibrationOnOrder = containsRecalParts(lineItemsFromSubmittedOrder); const shouldHideRecalibration = () => { @@ -254,7 +254,7 @@ export default { return containsRecalParts(this?.lineItems); }, ShowCart() { - if (this.isPia && this.submittedOrder?.settledTenderAmount == 0) { + if (this.isPia && this.submittedOrder?.order?.settledTenderAmount == 0) { // settleTenderAmount always shows 0 via localhost or dev. // Temporarily set return true to see cart in localhost or dev environment return false; @@ -269,13 +269,13 @@ export default { return this.getCmsContent("ScheduleConfirmationWidget", "Image"); }, CustomerPortalLoginToken() { - return this.submittedOrder?.customerPortalLoginToken; + return this.submittedOrder?.order.customerPortalLoginToken; }, ConfirmationEmailText() { return this.getCmsContent("ConfirmationEmailWidget", "BodyText") ?.replaceAll( "{custom:submittedOrder.customer.emailAddress}", - this.submittedOrder?.customer?.emailAddress + this.submittedOrder?.order.customer?.emailAddress ) ?.replaceAll("{custom:MY_ACCOUNT_URL}", applicationConfig.MY_ACCOUNT) ?.replaceAll("{custom:CUSTOMER_PORTAL_LOGIN_TOKEN}", this.CustomerPortalLoginToken) @@ -283,88 +283,88 @@ export default { ?.replaceAll(">", ">"); }, ScheduleDate() { - return this.submittedOrder?.schedule?.date; + return this.submittedOrder?.order.schedule?.date; }, AppointmentType() { - return this.submittedOrder?.serviceLocation?.appointmentType; + return this.submittedOrder?.order.serviceLocation?.appointmentType; }, ScheduleStartTime() { - return this.submittedOrder?.schedule?.startTime; + return this.submittedOrder?.order.schedule?.startTime; }, ScheduleEndTime() { - return this.submittedOrder?.schedule?.endTime; + return this.submittedOrder?.order.schedule?.endTime; }, InShopWordingText() { return this.getCmsContent("InShopWordingWidget", "BodyText") ?.replaceAll( "{custom:submittedOrder.vehicle.year}", - this.submittedOrder?.vehicle?.year + this.submittedOrder?.order?.vehicle?.year ) ?.replaceAll( "{custom:submittedOrder.vehicle.make}", - this.submittedOrder?.vehicle?.make + this.submittedOrder?.order?.vehicle?.make ) ?.replaceAll( "{custom:submittedOrder.vehicle.model}", - this.submittedOrder?.vehicle?.model + this.submittedOrder?.order?.vehicle?.model ); }, MobileWordingText() { return this.getCmsContent("MobileWordingWidget", "BodyText") ?.replaceAll( "{custom:submittedOrder.vehicle.year}", - this.submittedOrder?.vehicle?.year + this.submittedOrder?.order?.vehicle?.year ) ?.replaceAll( "{custom:submittedOrder.vehicle.make}", - this.submittedOrder?.vehicle?.make + this.submittedOrder?.order?.vehicle?.make ) ?.replaceAll( "{custom:submittedOrder.vehicle.model}", - this.submittedOrder?.vehicle?.model + this.submittedOrder?.order?.vehicle?.model ); }, DropOffWordingText() { return this.getCmsContent("DropOffWordingWidget", "BodyText") ?.replaceAll( "{custom:submittedOrder.vehicle.year}", - this.submittedOrder?.vehicle?.year + this.submittedOrder?.order?.vehicle?.year ) ?.replaceAll( "{custom:submittedOrder.vehicle.make}", - this.submittedOrder?.vehicle?.make + this.submittedOrder?.order?.vehicle?.make ) ?.replaceAll( "{custom:submittedOrder.vehicle.model}", - this.submittedOrder?.vehicle?.model + this.submittedOrder?.order?.vehicle?.model ); }, ServiceLocationAddress() { - return this.submittedOrder?.serviceLocation?.address; + return this.submittedOrder?.order?.serviceLocation?.address; }, ServiceLocationAddress2() { - return this.submittedOrder?.serviceLocation?.address2; + return this.submittedOrder?.order?.serviceLocation?.address2; }, ServiceLocationCity() { - return this.submittedOrder?.serviceLocation?.city; + return this.submittedOrder?.order?.serviceLocation?.city; }, ServiceLocationState() { - return this.submittedOrder?.serviceLocation?.state; + return this.submittedOrder?.order?.serviceLocation?.state; }, ServiceLocationZipCode() { - return this.submittedOrder?.serviceLocation?.zipCode; + return this.submittedOrder?.order?.serviceLocation?.zipCode; }, ProviderAddress() { - return this.submittedOrder?.serviceLocation?.provider?.address?.streetAddress; + return this.submittedOrder?.order?.serviceLocation?.provider?.address?.streetAddress; }, ProviderCity() { - return this.submittedOrder?.serviceLocation?.provider?.address?.city; + return this.submittedOrder?.order?.serviceLocation?.provider?.address?.city; }, ProviderState() { - return this.submittedOrder?.serviceLocation?.provider?.address?.state; + return this.submittedOrder?.order?.serviceLocation?.provider?.address?.state; }, ProviderZipCode() { - return this.submittedOrder?.serviceLocation?.provider?.address?.zipCode; + return this.submittedOrder?.order?.serviceLocation?.provider?.address?.zipCode; }, AppointmentWordingText() { if (this.AppointmentType == AppointmentTypeStrings.MOBILE) { @@ -408,7 +408,7 @@ export default { } if (this.AppointmentType == AppointmentTypeStrings.DROP_OFF) { if ( - this.submittedOrder?.schedule?.routeCode.includes( + this.submittedOrder?.order?.schedule?.routeCode.includes( RouteCodeFlags.OVERNIGHT_DROP_OFF ) ) { @@ -420,22 +420,22 @@ export default { return `at ${get12HourTimeFormat(this.ScheduleStartTime)}`; }, vehicleBannerImageUrl() { - return this.submittedOrder?.vehicle.imageUrl; + return this.submittedOrder?.order?.vehicle.imageUrl; }, damageInfo() { - return this.submittedOrder?.damage; + return this.submittedOrder?.order?.damage; }, isMSRFeeApplicable() { - return this.submittedOrder?.isMSRFeeApplicable; + return this.submittedOrder?.order?.isMSRFeeApplicable; }, isInsurance() { - return this.submittedOrder?.payment?.isInsurance; + return this.submittedOrder?.order?.payment?.isInsurance; }, isNoComp() { - return this.submittedOrder?.policy?.isNoComp; + return this.submittedOrder?.order?.policy?.isNoComp; }, isItac() { - return this.submittedOrder?.policy?.isItac; + return this.submittedOrder?.order?.policy?.isItac; }, hasVapsInCart() { if (this.lineItems?.vaps?.length > 0) { @@ -448,28 +448,28 @@ export default { if (this.isNoComp || this.isItac) { return coverageStatus.NOCOMP; } else { - return this.submittedOrder?.payment?.insuranceCoverage?.coverageStatus; + return this.submittedOrder?.order?.payment?.insuranceCoverage?.coverageStatus; } }, currentDeductible() { - return this.submittedOrder?.policy?.currentDeductible; + return this.submittedOrder?.order?.policy?.currentDeductible; }, insuranceCompanyName() { - return this.submittedOrder?.policy?.insuranceCompanyName; + return this.submittedOrder?.order?.policy?.insuranceCompanyName; }, isPia() { - return this.submittedOrder?.payment?.isPia; + return this.submittedOrder?.order?.payment?.isPia; }, AppointmentDuration() { - const durationMaximum = this.submittedOrder?.schedule?.jobMaxMinutes; - const durationMinimum = this.submittedOrder?.schedule?.jobMinMinutes; + const durationMaximum = this.submittedOrder?.order?.schedule?.jobMaxMinutes; + const durationMinimum = this.submittedOrder?.order?.schedule?.jobMinMinutes; const durationLengthString = "Duration: "; if ( - this.submittedOrder?.schedule?.routeCode.includes(RouteCodeFlags.ALL_DAY_DROP_OFF) + this.submittedOrder?.order?.schedule?.routeCode.includes(RouteCodeFlags.ALL_DAY_DROP_OFF) ) { return durationLengthString.concat("All Day"); } else if ( - this.submittedOrder?.schedule?.routeCode.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF) + this.submittedOrder?.order?.schedule?.routeCode.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF) ) { return durationLengthString.concat("Overnight"); } else { @@ -541,7 +541,7 @@ export default { parseInt(this.donationAmount), false ); - this.lineItems = deepClone(this.getSubmittedOrder().lineItems); + this.lineItems = deepClone(this.getSubmittedOrder().order.lineItems); } else { this.showDonationError = true; this.showDonationSuccess = false; diff --git a/src/store/index.js b/src/store/index.js index 032660c6f..05cb572e1 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1854,6 +1854,7 @@ export const actions = { if (windshieldPartWithRecal) { url += `/${windshieldPartWithRecal.partNumber}`; } + url += "/false"; return globalMethods.callHttpClient({ method: endpoints.GetProviders.method, @@ -3263,7 +3264,10 @@ export const actions = { } // create a submitted order object from vuex. - const submittedOrder = context.state.order; + const submittedOrder = { + order: context.state.order, + applicationUser: context.state.applicationUser, + }; const experiments = context.state.applicationUser.experiments; const affiliateCookies = context.state.applicationUser.affiliateCookies; From d38cc5f2e65f298120af51c53778ca74176fc77d Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Thu, 3 Apr 2025 10:31:52 -0400 Subject: [PATCH 046/110] Revert "CASH-462 | First look at order changes" This reverts commit e894522acbdd29d1e032b7940da54a1b1e653ad0. --- src/global-methods.js | 2 +- src/helpers/pricing-helper.js | 2 +- src/layouts/confirmation/confirmation.vue | 92 +++++++++++------------ src/store/index.js | 6 +- 4 files changed, 49 insertions(+), 53 deletions(-) diff --git a/src/global-methods.js b/src/global-methods.js index 01d0c9488..ba6cec1ec 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -61,7 +61,7 @@ export default { const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO; const submittedOrder = baseMixin.methods.getSubmittedOrder(); const hasSubmittedOrder = baseMixin.methods.hasSubmittedOrder(); - const order = hasSubmittedOrder ? submittedOrder.order : store.getters.order; + const order = hasSubmittedOrder ? submittedOrder : store.getters.order; const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "FixMyGlass" }); const headers = { [headerKeys.EXPERIMENT]: JSON.stringify(store.getters.experimentSettings), diff --git a/src/helpers/pricing-helper.js b/src/helpers/pricing-helper.js index 4c87b8cf4..fda5b3b9c 100644 --- a/src/helpers/pricing-helper.js +++ b/src/helpers/pricing-helper.js @@ -12,7 +12,7 @@ export function getDisplayAmountDue(lineItemsObject, includeTax = true) { export function getAmountDue(lineItemsObject, includeTax = true) { let amountDue = 0; const order = baseMixin?.methods?.hasSubmittedOrder() - ? baseMixin?.methods?.getSubmittedOrder().order + ? baseMixin?.methods?.getSubmittedOrder() : store.getters.order; if (lineItemsObject?.glassParts) { diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 0aadfdf5c..8e49f298d 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -173,8 +173,8 @@ export default { const wipersPromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_WIPERS, { - serviceZipCode: submittedOrder.order.serviceLocation.zipCode, - carId: submittedOrder.order.vehicle.carId, + serviceZipCode: submittedOrder.serviceLocation.zipCode, + carId: submittedOrder.vehicle.carId, }, "confirmation" ); @@ -203,10 +203,10 @@ export default { const resultMap = await settleAllPromises(promiseResultMap); const availableVaps = [resultMap.rainDefense, ...resultMap.wipers]; - const lineItemsFromSubmittedOrder = deepClone(submittedOrder.order.lineItems); + const lineItemsFromSubmittedOrder = deepClone(submittedOrder.lineItems); - const isNoComp = submittedOrder?.order?.policy?.isNoComp; - const isItac = submittedOrder?.order?.policy?.isItac; + const isNoComp = submittedOrder?.policy?.isNoComp; + const isItac = submittedOrder?.policy?.isItac; const isRecalibrationOnOrder = containsRecalParts(lineItemsFromSubmittedOrder); const shouldHideRecalibration = () => { @@ -254,7 +254,7 @@ export default { return containsRecalParts(this?.lineItems); }, ShowCart() { - if (this.isPia && this.submittedOrder?.order?.settledTenderAmount == 0) { + if (this.isPia && this.submittedOrder?.settledTenderAmount == 0) { // settleTenderAmount always shows 0 via localhost or dev. // Temporarily set return true to see cart in localhost or dev environment return false; @@ -269,13 +269,13 @@ export default { return this.getCmsContent("ScheduleConfirmationWidget", "Image"); }, CustomerPortalLoginToken() { - return this.submittedOrder?.order.customerPortalLoginToken; + return this.submittedOrder?.customerPortalLoginToken; }, ConfirmationEmailText() { return this.getCmsContent("ConfirmationEmailWidget", "BodyText") ?.replaceAll( "{custom:submittedOrder.customer.emailAddress}", - this.submittedOrder?.order.customer?.emailAddress + this.submittedOrder?.customer?.emailAddress ) ?.replaceAll("{custom:MY_ACCOUNT_URL}", applicationConfig.MY_ACCOUNT) ?.replaceAll("{custom:CUSTOMER_PORTAL_LOGIN_TOKEN}", this.CustomerPortalLoginToken) @@ -283,88 +283,88 @@ export default { ?.replaceAll(">", ">"); }, ScheduleDate() { - return this.submittedOrder?.order.schedule?.date; + return this.submittedOrder?.schedule?.date; }, AppointmentType() { - return this.submittedOrder?.order.serviceLocation?.appointmentType; + return this.submittedOrder?.serviceLocation?.appointmentType; }, ScheduleStartTime() { - return this.submittedOrder?.order.schedule?.startTime; + return this.submittedOrder?.schedule?.startTime; }, ScheduleEndTime() { - return this.submittedOrder?.order.schedule?.endTime; + return this.submittedOrder?.schedule?.endTime; }, InShopWordingText() { return this.getCmsContent("InShopWordingWidget", "BodyText") ?.replaceAll( "{custom:submittedOrder.vehicle.year}", - this.submittedOrder?.order?.vehicle?.year + this.submittedOrder?.vehicle?.year ) ?.replaceAll( "{custom:submittedOrder.vehicle.make}", - this.submittedOrder?.order?.vehicle?.make + this.submittedOrder?.vehicle?.make ) ?.replaceAll( "{custom:submittedOrder.vehicle.model}", - this.submittedOrder?.order?.vehicle?.model + this.submittedOrder?.vehicle?.model ); }, MobileWordingText() { return this.getCmsContent("MobileWordingWidget", "BodyText") ?.replaceAll( "{custom:submittedOrder.vehicle.year}", - this.submittedOrder?.order?.vehicle?.year + this.submittedOrder?.vehicle?.year ) ?.replaceAll( "{custom:submittedOrder.vehicle.make}", - this.submittedOrder?.order?.vehicle?.make + this.submittedOrder?.vehicle?.make ) ?.replaceAll( "{custom:submittedOrder.vehicle.model}", - this.submittedOrder?.order?.vehicle?.model + this.submittedOrder?.vehicle?.model ); }, DropOffWordingText() { return this.getCmsContent("DropOffWordingWidget", "BodyText") ?.replaceAll( "{custom:submittedOrder.vehicle.year}", - this.submittedOrder?.order?.vehicle?.year + this.submittedOrder?.vehicle?.year ) ?.replaceAll( "{custom:submittedOrder.vehicle.make}", - this.submittedOrder?.order?.vehicle?.make + this.submittedOrder?.vehicle?.make ) ?.replaceAll( "{custom:submittedOrder.vehicle.model}", - this.submittedOrder?.order?.vehicle?.model + this.submittedOrder?.vehicle?.model ); }, ServiceLocationAddress() { - return this.submittedOrder?.order?.serviceLocation?.address; + return this.submittedOrder?.serviceLocation?.address; }, ServiceLocationAddress2() { - return this.submittedOrder?.order?.serviceLocation?.address2; + return this.submittedOrder?.serviceLocation?.address2; }, ServiceLocationCity() { - return this.submittedOrder?.order?.serviceLocation?.city; + return this.submittedOrder?.serviceLocation?.city; }, ServiceLocationState() { - return this.submittedOrder?.order?.serviceLocation?.state; + return this.submittedOrder?.serviceLocation?.state; }, ServiceLocationZipCode() { - return this.submittedOrder?.order?.serviceLocation?.zipCode; + return this.submittedOrder?.serviceLocation?.zipCode; }, ProviderAddress() { - return this.submittedOrder?.order?.serviceLocation?.provider?.address?.streetAddress; + return this.submittedOrder?.serviceLocation?.provider?.address?.streetAddress; }, ProviderCity() { - return this.submittedOrder?.order?.serviceLocation?.provider?.address?.city; + return this.submittedOrder?.serviceLocation?.provider?.address?.city; }, ProviderState() { - return this.submittedOrder?.order?.serviceLocation?.provider?.address?.state; + return this.submittedOrder?.serviceLocation?.provider?.address?.state; }, ProviderZipCode() { - return this.submittedOrder?.order?.serviceLocation?.provider?.address?.zipCode; + return this.submittedOrder?.serviceLocation?.provider?.address?.zipCode; }, AppointmentWordingText() { if (this.AppointmentType == AppointmentTypeStrings.MOBILE) { @@ -408,7 +408,7 @@ export default { } if (this.AppointmentType == AppointmentTypeStrings.DROP_OFF) { if ( - this.submittedOrder?.order?.schedule?.routeCode.includes( + this.submittedOrder?.schedule?.routeCode.includes( RouteCodeFlags.OVERNIGHT_DROP_OFF ) ) { @@ -420,22 +420,22 @@ export default { return `at ${get12HourTimeFormat(this.ScheduleStartTime)}`; }, vehicleBannerImageUrl() { - return this.submittedOrder?.order?.vehicle.imageUrl; + return this.submittedOrder?.vehicle.imageUrl; }, damageInfo() { - return this.submittedOrder?.order?.damage; + return this.submittedOrder?.damage; }, isMSRFeeApplicable() { - return this.submittedOrder?.order?.isMSRFeeApplicable; + return this.submittedOrder?.isMSRFeeApplicable; }, isInsurance() { - return this.submittedOrder?.order?.payment?.isInsurance; + return this.submittedOrder?.payment?.isInsurance; }, isNoComp() { - return this.submittedOrder?.order?.policy?.isNoComp; + return this.submittedOrder?.policy?.isNoComp; }, isItac() { - return this.submittedOrder?.order?.policy?.isItac; + return this.submittedOrder?.policy?.isItac; }, hasVapsInCart() { if (this.lineItems?.vaps?.length > 0) { @@ -448,28 +448,28 @@ export default { if (this.isNoComp || this.isItac) { return coverageStatus.NOCOMP; } else { - return this.submittedOrder?.order?.payment?.insuranceCoverage?.coverageStatus; + return this.submittedOrder?.payment?.insuranceCoverage?.coverageStatus; } }, currentDeductible() { - return this.submittedOrder?.order?.policy?.currentDeductible; + return this.submittedOrder?.policy?.currentDeductible; }, insuranceCompanyName() { - return this.submittedOrder?.order?.policy?.insuranceCompanyName; + return this.submittedOrder?.policy?.insuranceCompanyName; }, isPia() { - return this.submittedOrder?.order?.payment?.isPia; + return this.submittedOrder?.payment?.isPia; }, AppointmentDuration() { - const durationMaximum = this.submittedOrder?.order?.schedule?.jobMaxMinutes; - const durationMinimum = this.submittedOrder?.order?.schedule?.jobMinMinutes; + const durationMaximum = this.submittedOrder?.schedule?.jobMaxMinutes; + const durationMinimum = this.submittedOrder?.schedule?.jobMinMinutes; const durationLengthString = "Duration: "; if ( - this.submittedOrder?.order?.schedule?.routeCode.includes(RouteCodeFlags.ALL_DAY_DROP_OFF) + this.submittedOrder?.schedule?.routeCode.includes(RouteCodeFlags.ALL_DAY_DROP_OFF) ) { return durationLengthString.concat("All Day"); } else if ( - this.submittedOrder?.order?.schedule?.routeCode.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF) + this.submittedOrder?.schedule?.routeCode.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF) ) { return durationLengthString.concat("Overnight"); } else { @@ -541,7 +541,7 @@ export default { parseInt(this.donationAmount), false ); - this.lineItems = deepClone(this.getSubmittedOrder().order.lineItems); + this.lineItems = deepClone(this.getSubmittedOrder().lineItems); } else { this.showDonationError = true; this.showDonationSuccess = false; diff --git a/src/store/index.js b/src/store/index.js index 05cb572e1..032660c6f 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1854,7 +1854,6 @@ export const actions = { if (windshieldPartWithRecal) { url += `/${windshieldPartWithRecal.partNumber}`; } - url += "/false"; return globalMethods.callHttpClient({ method: endpoints.GetProviders.method, @@ -3264,10 +3263,7 @@ export const actions = { } // create a submitted order object from vuex. - const submittedOrder = { - order: context.state.order, - applicationUser: context.state.applicationUser, - }; + const submittedOrder = context.state.order; const experiments = context.state.applicationUser.experiments; const affiliateCookies = context.state.applicationUser.affiliateCookies; From 76b26e2991597aefaa61dd03664fff3ff8f009a5 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Thu, 3 Apr 2025 10:57:06 -0400 Subject: [PATCH 047/110] CASH-417 CASH-417 use the isBigTruck property returned from the service instead of computing it based on subType and special class --- src/constants/store-mutations.js | 2 ++ src/constants/vehicle-categories.js | 8 +----- .../service-location/service-location.vue | 2 +- .../shop-question/shop-question.vue | 7 +++++- src/layouts/vehicle/vehicle.vue | 25 +++++++++++-------- src/store/index.js | 24 +++++++++++++----- 6 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 509988c6e..2f53d8133 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -10,6 +10,8 @@ const storeMutations = { UPDATE_MODEL: "updateModel", UPDATE_STYLE: "updateStyle", UPDATE_VEHICLE_SUBTYPE: "updateVehicleSubType", + UPDATE_VEHICLE_SPECIAL_CLASS: "updateVehicleSpecialClass", + UPDATE_IS_BIGTRUCK: "updateIsBigTruck", UPDATE_CAR_ID: "updateCarId", UPDATE_VEHICLE_CATEGORY: "updateVehicleCategory", UPDATE_VEHICLE_IMAGE_URL: "updateVehicleImageUrl", diff --git a/src/constants/vehicle-categories.js b/src/constants/vehicle-categories.js index 9300f47e2..8ef3e0134 100644 --- a/src/constants/vehicle-categories.js +++ b/src/constants/vehicle-categories.js @@ -8,10 +8,4 @@ const vehicleCategories = { SEMI: "SEMI", }; -export { vehicleCategories }; - -const vehicleSubTypes = { - HEAVY_TRUCK: "HEAVY TRUCK", -}; - -export { vehicleSubTypes }; +export { vehicleCategories }; \ No newline at end of file diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index 142c3468b..758dc88e9 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -537,7 +537,7 @@ export default { return store.getters.order.serviceLocation.zipCode; }, getIsVehicleHeavyTruckFromStore() { - return store.getters.isHeavyTruckVehicle; + return store.getters.order.vehicle.isBigTruck; }, getIsVehicleProtectedFromStore() { return store.getters.order.serviceLocation.isVehicleProtected; diff --git a/src/layouts/service-location/shop-question/shop-question.vue b/src/layouts/service-location/shop-question/shop-question.vue index a15d8bb0b..c0e2bffe0 100644 --- a/src/layouts/service-location/shop-question/shop-question.vue +++ b/src/layouts/service-location/shop-question/shop-question.vue @@ -179,10 +179,15 @@ export default { } }); + var joinedShops = shops.join(","); + if (!joinedShops) { + joinedShops = "no-shops"; + } + this.pushEventToGA( this.GaCategories.SERVICE_LOCATION, gaAction, - shops.join(","), + joinedShops, true ); } diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index da4ee6689..257de9bf6 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -49,7 +49,7 @@ placeHolderText="Select style" customDropdownId="styleQuestionField" /> -
+
{ @@ -63,6 +62,8 @@ const getDefaultState = () => { model: null, style: null, vehicleSubType: null, + vehicleSpecialClass: null, + isBigTruck: false, carId: null, category: null, vin: null, @@ -217,6 +218,12 @@ export const mutations = { updateVehicleSubType(state, vehicleSubType) { state.order.vehicle.vehicleSubType = vehicleSubType; }, + updateVehicleSpecialClass(state, vehicleSpecialClass) { + state.order.vehicle.vehicleSpecialClass = vehicleSpecialClass; + }, + updateIsBigTruck(state, isBigTruck) { + state.order.vehicle.isBigTruck = isBigTruck; + }, updateCarId(state, carId) { state.order.vehicle.carId = carId; }, @@ -847,9 +854,6 @@ export const getters = { return false; }, - isHeavyTruckVehicle: (state) => { - return state.order.vehicle.vehicleSubType === vehicleSubTypes.HEAVY_TRUCK; - }, isMobileAppointment: (state) => { return state.order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE; }, @@ -1849,7 +1853,7 @@ export const actions = { endPoint += `&${glassPieces}`; } - endPoint += `&isHeavyTruckVehicle=${context.getters.isHeavyTruckVehicle}`; + endPoint += `&isHeavyTruckVehicle=${context.getters.order.vehicle.isBigTruck}`; return globalMethods.callHttpClient({ method: endpoints.GetServiceabilityDetails.method, @@ -1878,7 +1882,7 @@ export const actions = { url += `/${windshieldPartWithRecal.partNumber}`; } //heavy truck vehicle - url += `/${context.getters.isHeavyTruckVehicle}`; + url += `/${context.getters.order.vehicle.isBigTruck}`; return globalMethods.callHttpClient({ method: endpoints.GetProviders.method, @@ -2111,6 +2115,8 @@ export const actions = { make: vehicle.make, model: vehicle.model, subType: vehicle.vehicleSubType, + specialClass: vehicle.vehicleSpecialClass, + isBigTruck: vehicle.isBigTruck, isInsurance: order.payment.isInsurance ?? false, isVerified: order.payment.insuranceCoverage.isVerified ?? false, lineItems: { @@ -2165,6 +2171,8 @@ export const actions = { style: vehicle.style, vin: vehicle.vin, vehicleSubType: vehicle.vehicleSubType, + vehicleSpecialClass: vehicle.vehicleSpecialClass, + isBigTruck: vehicle.isBigTruck, registration: { firstName: vehicle.registration.firstName, lastName: vehicle.registration.lastName, @@ -2381,6 +2389,8 @@ export const actions = { model, style, vehicleSubType, + vehicleSpecialClass, + isBigTruck, carId, category, canSafeliteService, @@ -2404,6 +2414,8 @@ export const actions = { context.commit(storeMutations.UPDATE_MODEL, model); context.commit(storeMutations.UPDATE_STYLE, style); context.commit(storeMutations.UPDATE_VEHICLE_SUBTYPE, vehicleSubType); + context.commit(storeMutations.UPDATE_VEHICLE_SPECIAL_CLASS, vehicleSpecialClass); + context.commit(storeMutations.UPDATE_IS_BIGTRUCK, isBigTruck); context.commit(storeMutations.UPDATE_CAR_ID, carId); context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, category); context.commit(storeMutations.UPDATE_VEHICLE_CAN_SAFELITE_SERVICE, canSafeliteService); From 749fa3219e5d8eef2e068805a3b1832c569867cd Mon Sep 17 00:00:00 2001 From: CarlNation Date: Thu, 3 Apr 2025 12:07:11 -0400 Subject: [PATCH 048/110] prettier --- src/constants/vehicle-categories.js | 2 +- .../service-location/shop-question/shop-question.vue | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/constants/vehicle-categories.js b/src/constants/vehicle-categories.js index 8ef3e0134..37ffcf5e1 100644 --- a/src/constants/vehicle-categories.js +++ b/src/constants/vehicle-categories.js @@ -8,4 +8,4 @@ const vehicleCategories = { SEMI: "SEMI", }; -export { vehicleCategories }; \ No newline at end of file +export { vehicleCategories }; diff --git a/src/layouts/service-location/shop-question/shop-question.vue b/src/layouts/service-location/shop-question/shop-question.vue index c0e2bffe0..0a3e9eefa 100644 --- a/src/layouts/service-location/shop-question/shop-question.vue +++ b/src/layouts/service-location/shop-question/shop-question.vue @@ -184,12 +184,7 @@ export default { joinedShops = "no-shops"; } - this.pushEventToGA( - this.GaCategories.SERVICE_LOCATION, - gaAction, - joinedShops, - true - ); + this.pushEventToGA(this.GaCategories.SERVICE_LOCATION, gaAction, joinedShops, true); } if (this.answers.length === 0) { From 21c9607682b5c180289f12fca81068dad0317f68 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Thu, 3 Apr 2025 12:26:58 -0400 Subject: [PATCH 049/110] CASH-417 CASH-417 null check --- src/layouts/service-location/service-location.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index 758dc88e9..a85a5bd17 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -537,7 +537,7 @@ export default { return store.getters.order.serviceLocation.zipCode; }, getIsVehicleHeavyTruckFromStore() { - return store.getters.order.vehicle.isBigTruck; + return store.getters.order.vehicle?.isBigTruck ?? false; }, getIsVehicleProtectedFromStore() { return store.getters.order.serviceLocation.isVehicleProtected; From 77c007c4447ff5a05db4614605269ea9cb1db4cb Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Thu, 3 Apr 2025 13:19:44 -0400 Subject: [PATCH 050/110] CASH-462 | Rename and restructure submittedOrder Rename to submittedState Add an applicationUser attribute --- src/constants/store-actions.js | 6 +-- .../add-to-calendar/add-to-calendar.vue | 2 +- src/layouts/confirmation/confirmation.vue | 7 +--- .../payment-pia-return/payment-pia-return.vue | 2 +- src/layouts/payment/payment.vue | 2 +- src/layouts/vehicle/vehicle.vue | 2 +- src/mixins/analytics-mixin.js | 2 +- src/mixins/analytics-mixin.spec.js | 2 +- src/mixins/base-mixin.js | 12 +++++- src/router/index.js | 4 +- src/store/index.js | 39 ++++++++++++------- 11 files changed, 47 insertions(+), 33 deletions(-) diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index e7cb38953..1e8945c49 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -109,9 +109,9 @@ const storeActions = { SAVE_IS_RECAL_ACK_OPT_IN: "saveIsRecalAckOptIn", SAVE_IS_MSR_FEE_APPLICABLE: "saveIsMSRFeeApplicable", - CREATE_SUBMITTED_ORDER: "createSubmittedOrder", - RESET_SUBMITTED_ORDER: "resetSubmittedOrder", - ADD_DONATION_TO_SUBMITTED_ORDER: "addDonationToSubmittedOrder", + CREATE_SUBMITTED_STATE: "createSubmittedState", + RESET_SUBMITTED_STATE: "resetSubmittedState", + ADD_DONATION_TO_SUBMITTED_STATE: "addDonationToSubmittedState", RESET_EXTERNAL_PARAMETER_STATE: "resetExternalParameterState", UPDATE_EXTERNAL_PARAMETER_MMS: "updateExternalParameterMMS", diff --git a/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue b/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue index 1fef02247..c986e0366 100644 --- a/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue +++ b/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue @@ -115,7 +115,7 @@ export default { }, ServiceType() { const isRepair = this.getSubmittedOrder()?.damage.isRepair; - const funnelHasRecalibrationPart = store.getters.isRecalibrationOnSubmittedOrder; + const funnelHasRecalibrationPart = store.getters.isRecalibrationOnSubmittedState; if (!isRepair) { if (funnelHasRecalibrationPart) { return serviceType.REPLACEMENT_AND_RECALIBRATION; diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 8e49f298d..7e9cfe71e 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -164,7 +164,7 @@ export default { } // Create order - await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_ORDER); // This nulls the Store order + await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_STATE); // This nulls the Store order // Call APIs const submittedOrder = baseMixin.methods.getSubmittedOrder(); @@ -255,11 +255,8 @@ export default { }, ShowCart() { if (this.isPia && this.submittedOrder?.settledTenderAmount == 0) { - // settleTenderAmount always shows 0 via localhost or dev. - // Temporarily set return true to see cart in localhost or dev environment return false; } - return true; }, ScheduleConfirmationText() { @@ -537,7 +534,7 @@ export default { this.showDonationSuccess = true; this.showDonationError = false; await baseMixin.methods.dispatchStoreAction( - storeActions.ADD_DONATION_TO_SUBMITTED_ORDER, + storeActions.ADD_DONATION_TO_SUBMITTED_STATE, parseInt(this.donationAmount), false ); diff --git a/src/layouts/payment-pia-return/payment-pia-return.vue b/src/layouts/payment-pia-return/payment-pia-return.vue index b9f19f64a..f0b4433ea 100644 --- a/src/layouts/payment-pia-return/payment-pia-return.vue +++ b/src/layouts/payment-pia-return/payment-pia-return.vue @@ -192,7 +192,7 @@ export default { } this.$refs.loadingModal.isModalVisible = false; - await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_ORDER); + await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_STATE); this.$router.navigateWithoutSaving(this.navigationScenarios.PIA_SUCCESS, this.$route); }, }, diff --git a/src/layouts/payment/payment.vue b/src/layouts/payment/payment.vue index abf06927b..3c87f85f2 100644 --- a/src/layouts/payment/payment.vue +++ b/src/layouts/payment/payment.vue @@ -683,7 +683,7 @@ export default { submitAfterSave: true, }); - await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_ORDER); + await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_STATE); window.location = applicationConfig.CONFIRMATION_URL; } catch (error) { console.log("error: response from submit work order(payment pg):" + error.message); diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index 12e7268fa..5f769b9b7 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -448,7 +448,7 @@ export default { this.displayNoServiceAlert = false; }, async forwardButtonAction() { - await this.dispatchStoreAction(storeActions.RESET_SUBMITTED_ORDER); + await this.dispatchStoreAction(storeActions.RESET_SUBMITTED_STATE); this.dispatchStoreAction( storeActions.SAVE_VEHICLE, { diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index e59ec5039..d6e608d4b 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -337,7 +337,7 @@ export default { // Recalibration if (hasSubmittedOrder) { - payload.isRecalibrationOnOrder = store.getters.isRecalibrationOnSubmittedOrder; + payload.isRecalibrationOnOrder = store.getters.isRecalibrationOnSubmittedState; } else { payload.isRecalibrationOnOrder = store.getters.isRecalibrationOnOrder; } diff --git a/src/mixins/analytics-mixin.spec.js b/src/mixins/analytics-mixin.spec.js index a4b4672bb..711702c4a 100644 --- a/src/mixins/analytics-mixin.spec.js +++ b/src/mixins/analytics-mixin.spec.js @@ -425,7 +425,7 @@ describe("analyticsMixin.js", () => { workOrderId: "222222222222", }; store.getters.isRecalibrationOnOrder = true; - store.getters.isRecalibrationOnSubmittedOrder = false; + store.getters.isRecalibrationOnSubmittedState = false; }); test("Pushes to data layer if nominal", () => { diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 151d17dd9..1c33640f8 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -198,10 +198,18 @@ export default { } }, getSubmittedOrder() { - return JSON.parse(window.sessionStorage.getItem("submittedOrder")); + return JSON.parse(window.sessionStorage.getItem("submittedState"))?.order; }, hasSubmittedOrder() { - return window.sessionStorage.getItem("submittedOrder") !== null; + const submittedState = window.sessionStorage.getItem("submittedState"); + return submittedState !== null && submittedState.order !== null; + }, + getSubmittedApplicationUser() { + return JSON.parse(window.sessionStorage.getItem("submittedState"))?.applicationUser; + }, + hasSubmittedApplicationUser() { + const submittedState = window.sessionStorage.getItem("submittedState"); + return submittedState !== null && submittedState.applicationUser !== null; }, }, computed: { diff --git a/src/router/index.js b/src/router/index.js index 345790734..e2263b32d 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -93,10 +93,10 @@ const routes = [ log(" --to.query.fmgPage ", to.query?.fmgPage); // Intercept all navigation if a submitted order exists in storage - if (window.sessionStorage.getItem("submittedOrder") !== null) { + if (window.sessionStorage.getItem("submittedState") !== null) { if (to.query.fmgPage !== funnelStartPageName) { to.query.fmgPage = fmgPageValues.CONFIRMATION; - log(" --has submittedOrder go to confirmation"); + log(" --has submittedState go to confirmation"); } } // On entering the funnel "fresh", read cookie information, decide what to do next. diff --git a/src/store/index.js b/src/store/index.js index 032660c6f..cdd81d164 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -822,8 +822,8 @@ export const getters = { }, coverageIsVerified: (state) => { let order; - if (window.sessionStorage.getItem("submittedOrder") !== null) { - order = JSON.parse(window.sessionStorage.getItem("submittedOrder")); + if (window.sessionStorage.getItem("submittedState") !== null) { + order = JSON.parse(window.sessionStorage.getItem("submittedState")).order; } else { order = state.order; } @@ -850,10 +850,10 @@ export const getters = { isRecalibrationOnOrder: (state) => { return getHasRecalibrationPart(state); }, - isRecalibrationOnSubmittedOrder: (state) => { - if (window.sessionStorage.getItem("submittedOrder") !== null) { + isRecalibrationOnSubmittedState: (state) => { + if (window.sessionStorage.getItem("submittedState") !== null) { return getHasRecalibrationPart({ - order: JSON.parse(window.sessionStorage.getItem("submittedOrder")), + order: JSON.parse(window.sessionStorage.getItem("submittedState")).order, }); } @@ -861,8 +861,8 @@ export const getters = { }, shouldHideRecalibration: (state) => { var order; - if (window.sessionStorage.getItem("submittedOrder") !== null) { - order = JSON.parse(window.sessionStorage.getItem("submittedOrder")); + if (window.sessionStorage.getItem("submittedState") !== null) { + order = JSON.parse(window.sessionStorage.getItem("submittedState")).order; } else { order = state.order; } @@ -3257,19 +3257,22 @@ export const actions = { return false; }, - createSubmittedOrder(context) { - if (window.sessionStorage.getItem("submittedOrder") !== null) { + createSubmittedState(context) { + if (window.sessionStorage.getItem("submittedState") !== null) { return; } // create a submitted order object from vuex. - const submittedOrder = context.state.order; + const submittedState = { + order: context.state.order, + applicationUser: context.state.applicationUser + }; const experiments = context.state.applicationUser.experiments; const affiliateCookies = context.state.applicationUser.affiliateCookies; // set to local storage - window.sessionStorage.setItem("submittedOrder", JSON.stringify(submittedOrder)); + window.sessionStorage.setItem("submittedState", JSON.stringify(submittedState)); window.sessionStorage.setItem("createNewSessionForHeritage", true); // clear vuex @@ -3288,10 +3291,11 @@ export const actions = { context.commit(storeMutations.UPDATE_AFFILIATE_COOKIES, affiliateCookies); }, - addDonationToSubmittedOrder(context, donationAmount) { + addDonationToSubmittedState(context, donationAmount) { console.log("running addDonationToSubmittedOrder()... donationAmount: ", donationAmount); const submittedOrder = deepClone(baseMixin.methods.getSubmittedOrder()); + const submittedApplicationUser = deepClone(baseMixin.methods.getSubmittedApplicationUser()); if (donationAmount > 0) { console.log( @@ -3320,13 +3324,18 @@ export const actions = { }); submittedOrder.lineItems.supportingItems = nonDonationItems; } + + const submittedState = { + order: submittedOrder, + applicationUser: submittedApplicationUser + } // set to local storage - window.sessionStorage.setItem("submittedOrder", JSON.stringify(submittedOrder)); + window.sessionStorage.setItem("submittedState", JSON.stringify(submittedState)); }, - resetSubmittedOrder(context) { + resetSubmittedState(context) { // clear from local storage - window.sessionStorage.removeItem("submittedOrder"); + window.sessionStorage.removeItem("submittedState"); }, resetExternalParameterState(context) { if (context.getters.isExternalParameter) { From b90c3644d6e7151fec00b41eb0c1df320b4717c8 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Thu, 3 Apr 2025 13:20:25 -0400 Subject: [PATCH 051/110] CASH-462 | Styling --- src/store/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index cdd81d164..4d079056e 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -3265,7 +3265,7 @@ export const actions = { // create a submitted order object from vuex. const submittedState = { order: context.state.order, - applicationUser: context.state.applicationUser + applicationUser: context.state.applicationUser, }; const experiments = context.state.applicationUser.experiments; @@ -3327,8 +3327,8 @@ export const actions = { const submittedState = { order: submittedOrder, - applicationUser: submittedApplicationUser - } + applicationUser: submittedApplicationUser, + }; // set to local storage window.sessionStorage.setItem("submittedState", JSON.stringify(submittedState)); }, From 15c49c1d635316419d47262bb18a83b09ffa11f0 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Thu, 3 Apr 2025 13:32:12 -0400 Subject: [PATCH 052/110] CASH-403 WIP footer updates. --- src/assets/img/neighborhood.svg | 123 ++++++--------------- src/assets/img/skyline-van.svg | 182 +++++++++++++------------------- 2 files changed, 104 insertions(+), 201 deletions(-) diff --git a/src/assets/img/neighborhood.svg b/src/assets/img/neighborhood.svg index 4022f9116..30eef566e 100644 --- a/src/assets/img/neighborhood.svg +++ b/src/assets/img/neighborhood.svg @@ -1,92 +1,33 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/img/skyline-van.svg b/src/assets/img/skyline-van.svg index 443ae3463..c452e70f1 100644 --- a/src/assets/img/skyline-van.svg +++ b/src/assets/img/skyline-van.svg @@ -1,114 +1,76 @@ - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + \ No newline at end of file From f0843d4212ce07fee90f7b6534a32233c6894bcc Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Thu, 3 Apr 2025 13:50:40 -0400 Subject: [PATCH 053/110] CASH-403 WIP remove link underline. --- src/fmg-components/funnel-footer/funnel-footer.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fmg-components/funnel-footer/funnel-footer.vue b/src/fmg-components/funnel-footer/funnel-footer.vue index 00f843b0e..5617e44ce 100644 --- a/src/fmg-components/funnel-footer/funnel-footer.vue +++ b/src/fmg-components/funnel-footer/funnel-footer.vue @@ -91,6 +91,7 @@ export default { align-items: center; :deep(a) { + text-decoration: none; &.new-window-link { margin: 0 0.75rem; } From 43d1353e52776e9832dc826e691305c4967cbc99 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Thu, 3 Apr 2025 14:15:39 -0400 Subject: [PATCH 054/110] CASH-462 | Add constant for submittedState --- src/constants/session-storage.js | 3 +++ src/mixins/base-mixin.js | 9 +++++---- src/router/index.js | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 src/constants/session-storage.js diff --git a/src/constants/session-storage.js b/src/constants/session-storage.js new file mode 100644 index 000000000..577fa4c0f --- /dev/null +++ b/src/constants/session-storage.js @@ -0,0 +1,3 @@ +export const sessionStorageKeyConstants = { + SUBMITTED_STATE: "submittedState" +} \ No newline at end of file diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 1c33640f8..73677726a 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -1,6 +1,7 @@ import store from "@/store"; import { storeActions } from "@/constants/store-actions.js"; import { storeMutations } from "@/constants/store-mutations.js"; +import { sessionStorageKeyConstants } from "@/constants/session-storage.js"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import { vehicleCategories } from "@/constants/vehicle-categories.js"; import { routerParams } from "@/router/router-constants/router-params"; @@ -198,17 +199,17 @@ export default { } }, getSubmittedOrder() { - return JSON.parse(window.sessionStorage.getItem("submittedState"))?.order; + return JSON.parse(window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE))?.order; }, hasSubmittedOrder() { - const submittedState = window.sessionStorage.getItem("submittedState"); + const submittedState = window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE); return submittedState !== null && submittedState.order !== null; }, getSubmittedApplicationUser() { - return JSON.parse(window.sessionStorage.getItem("submittedState"))?.applicationUser; + return JSON.parse(window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE))?.applicationUser; }, hasSubmittedApplicationUser() { - const submittedState = window.sessionStorage.getItem("submittedState"); + const submittedState = window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE); return submittedState !== null && submittedState.applicationUser !== null; }, }, diff --git a/src/router/index.js b/src/router/index.js index e2263b32d..95aca54d8 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -2,6 +2,7 @@ import { createWebHistory, createRouter } from "vue-router"; import { storeActions } from "@/constants/store-actions"; import { storeMutations } from "../constants/store-mutations"; +import { sessionStorageKeyConstants } from "@/constants/session-storage.js"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; @@ -39,6 +40,7 @@ import { shouldStripPromoQueryString } from "@/helpers/promotions-helper"; import bailout from "@/layouts/bailout/bailout"; import { nextTick } from "vue"; import { getBoolFromString } from "@/helpers/boolean-helper"; +import { sessionStorageKeyConstants } from "../constants/session-storage"; const routes = [ { @@ -93,10 +95,10 @@ const routes = [ log(" --to.query.fmgPage ", to.query?.fmgPage); // Intercept all navigation if a submitted order exists in storage - if (window.sessionStorage.getItem("submittedState") !== null) { + if (window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) !== null) { if (to.query.fmgPage !== funnelStartPageName) { to.query.fmgPage = fmgPageValues.CONFIRMATION; - log(" --has submittedState go to confirmation"); + log(` --has ${sessionStorageKeyConstants.SUBMITTED_STATE} go to confirmation`); } } // On entering the funnel "fresh", read cookie information, decide what to do next. From af9775aa3b8e470f1360b1160448b3a408e65a24 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Thu, 3 Apr 2025 14:17:31 -0400 Subject: [PATCH 055/110] CASH-462 | Prettier changes --- src/constants/session-storage.js | 6 +++--- src/mixins/base-mixin.js | 16 ++++++++++++---- src/router/index.js | 10 +++++++--- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/constants/session-storage.js b/src/constants/session-storage.js index 577fa4c0f..589dd6b71 100644 --- a/src/constants/session-storage.js +++ b/src/constants/session-storage.js @@ -1,3 +1,3 @@ -export const sessionStorageKeyConstants = { - SUBMITTED_STATE: "submittedState" -} \ No newline at end of file +export const sessionStorageKeyConstants = { + SUBMITTED_STATE: "submittedState", +}; diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 73677726a..b29eae8c1 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -199,17 +199,25 @@ export default { } }, getSubmittedOrder() { - return JSON.parse(window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE))?.order; + return JSON.parse( + window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) + )?.order; }, hasSubmittedOrder() { - const submittedState = window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE); + const submittedState = window.sessionStorage.getItem( + sessionStorageKeyConstants.SUBMITTED_STATE + ); return submittedState !== null && submittedState.order !== null; }, getSubmittedApplicationUser() { - return JSON.parse(window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE))?.applicationUser; + return JSON.parse( + window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) + )?.applicationUser; }, hasSubmittedApplicationUser() { - const submittedState = window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE); + const submittedState = window.sessionStorage.getItem( + sessionStorageKeyConstants.SUBMITTED_STATE + ); return submittedState !== null && submittedState.applicationUser !== null; }, }, diff --git a/src/router/index.js b/src/router/index.js index 95aca54d8..5ec909f97 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -40,7 +40,6 @@ import { shouldStripPromoQueryString } from "@/helpers/promotions-helper"; import bailout from "@/layouts/bailout/bailout"; import { nextTick } from "vue"; import { getBoolFromString } from "@/helpers/boolean-helper"; -import { sessionStorageKeyConstants } from "../constants/session-storage"; const routes = [ { @@ -95,10 +94,15 @@ const routes = [ log(" --to.query.fmgPage ", to.query?.fmgPage); // Intercept all navigation if a submitted order exists in storage - if (window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) !== null) { + if ( + window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) !== + null + ) { if (to.query.fmgPage !== funnelStartPageName) { to.query.fmgPage = fmgPageValues.CONFIRMATION; - log(` --has ${sessionStorageKeyConstants.SUBMITTED_STATE} go to confirmation`); + log( + ` --has ${sessionStorageKeyConstants.SUBMITTED_STATE} go to confirmation` + ); } } // On entering the funnel "fresh", read cookie information, decide what to do next. From fe666f381abce1e3c9ce945010e1335c2b6656f3 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Thu, 3 Apr 2025 14:23:09 -0400 Subject: [PATCH 056/110] CASH-462 | Utilize new constant in the store --- src/store/index.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index 4d079056e..673bf36ee 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,6 +1,7 @@ import { createStore } from "vuex"; import { endpoints } from "@/constants/endpoints.js"; import { storeMutations } from "@/constants/store-mutations"; +import { sessionStorageKeyConstants } from "@/constants/session-storage.js"; import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper"; import createPersistedState from "vuex-persistedstate"; import globalMethods from "@/global-methods"; @@ -822,8 +823,8 @@ export const getters = { }, coverageIsVerified: (state) => { let order; - if (window.sessionStorage.getItem("submittedState") !== null) { - order = JSON.parse(window.sessionStorage.getItem("submittedState")).order; + if (window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) !== null) { + order = JSON.parse(window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE)).order; } else { order = state.order; } @@ -851,9 +852,9 @@ export const getters = { return getHasRecalibrationPart(state); }, isRecalibrationOnSubmittedState: (state) => { - if (window.sessionStorage.getItem("submittedState") !== null) { + if (window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) !== null) { return getHasRecalibrationPart({ - order: JSON.parse(window.sessionStorage.getItem("submittedState")).order, + order: JSON.parse(window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE)).order, }); } @@ -861,8 +862,8 @@ export const getters = { }, shouldHideRecalibration: (state) => { var order; - if (window.sessionStorage.getItem("submittedState") !== null) { - order = JSON.parse(window.sessionStorage.getItem("submittedState")).order; + if (window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) !== null) { + order = JSON.parse(window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE)).order; } else { order = state.order; } @@ -3258,7 +3259,7 @@ export const actions = { }, createSubmittedState(context) { - if (window.sessionStorage.getItem("submittedState") !== null) { + if (window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) !== null) { return; } @@ -3272,7 +3273,7 @@ export const actions = { const affiliateCookies = context.state.applicationUser.affiliateCookies; // set to local storage - window.sessionStorage.setItem("submittedState", JSON.stringify(submittedState)); + window.sessionStorage.setItem(sessionStorageKeyConstants.SUBMITTED_STATE, JSON.stringify(submittedState)); window.sessionStorage.setItem("createNewSessionForHeritage", true); // clear vuex @@ -3330,12 +3331,12 @@ export const actions = { applicationUser: submittedApplicationUser, }; // set to local storage - window.sessionStorage.setItem("submittedState", JSON.stringify(submittedState)); + window.sessionStorage.setItem(sessionStorageKeyConstants.SUBMITTED_STATE, JSON.stringify(submittedState)); }, resetSubmittedState(context) { // clear from local storage - window.sessionStorage.removeItem("submittedState"); + window.sessionStorage.removeItem(sessionStorageKeyConstants.SUBMITTED_STATE); }, resetExternalParameterState(context) { if (context.getters.isExternalParameter) { From ca9aba53e434d0e441705655cbd40a74f02bdd0a Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Fri, 4 Apr 2025 08:35:39 -0400 Subject: [PATCH 057/110] CASH-403 footer updates. --- src/fmg-components/funnel-footer/funnel-footer.vue | 2 +- src/styles/common-styles.scss | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/fmg-components/funnel-footer/funnel-footer.vue b/src/fmg-components/funnel-footer/funnel-footer.vue index 5617e44ce..dc3cf9577 100644 --- a/src/fmg-components/funnel-footer/funnel-footer.vue +++ b/src/fmg-components/funnel-footer/funnel-footer.vue @@ -70,7 +70,7 @@ export default { display: flex; flex-direction: column; width: 100%; - background: #ffffff; + background: transparent; align-items: end; margin-top: auto; diff --git a/src/styles/common-styles.scss b/src/styles/common-styles.scss index eda5b58b5..85065a799 100644 --- a/src/styles/common-styles.scss +++ b/src/styles/common-styles.scss @@ -8,6 +8,14 @@ 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-fluid { padding: 0 1.5rem; From 375d2dd1482add6a6fe12dca02c40d0d17158f1d Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Fri, 4 Apr 2025 08:47:51 -0400 Subject: [PATCH 058/110] CASH-403 update navbar position and z-index. --- src/fmg-components/nav-bar/nav-bar.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fmg-components/nav-bar/nav-bar.vue b/src/fmg-components/nav-bar/nav-bar.vue index f23ecd244..eaf37047c 100644 --- a/src/fmg-components/nav-bar/nav-bar.vue +++ b/src/fmg-components/nav-bar/nav-bar.vue @@ -129,6 +129,8 @@ export default { overflow: visible; display: flex; padding: 0; + position: relative; + z-index: 2; a { display: flex; justify-content: center; From 1649ea14077449503533cc4f99fa29c16402418a Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Mon, 7 Apr 2025 15:29:47 +0530 Subject: [PATCH 059/110] CASH-433 hide drop off option for big truck --- .../appointment-type-question.vue | 19 ++++++++++++++++--- .../service-location/service-location.vue | 13 +++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/layouts/service-location/appointment-type-question/appointment-type-question.vue b/src/layouts/service-location/appointment-type-question/appointment-type-question.vue index 64bf159ff..4c1c0d031 100644 --- a/src/layouts/service-location/appointment-type-question/appointment-type-question.vue +++ b/src/layouts/service-location/appointment-type-question/appointment-type-question.vue @@ -32,6 +32,7 @@ export default { cmsWidgetName: String, isServiceableMobile: Boolean, isServiceableInshop: Boolean, + isServiceableDropoff: Boolean, mobileFeeApplies: Boolean, }, computed: { @@ -45,7 +46,7 @@ export default { const shouldShowMobile = this.isServiceableMobile; const shouldShowInshop = this.isServiceableInshop; const shouldShowDropoff = - this.isServiceableInshop && !this.$store.getters.damage.isRepair; + this.isServiceableDropoff && !this.$store.getters.damage.isRepair; var answers = this.answersFromCms ? this.answersFromCms.filter((answer) => { @@ -77,6 +78,11 @@ export default { isMobileOnly() { return this.isServiceableMobile && !this.isServiceableInshop; }, + isInshopOnly() { + return ( + this.isServiceableInshop && !this.isServiceableMobile && !this.isServiceableDropoff + ); + }, }, watch: { answersToDisplay: { @@ -86,7 +92,7 @@ export default { newValue.length == 1 && newValue.findIndex((answer) => answer.Name == "Mobile") != -1 ) { - this.selectedValues = "Mobile"; + this.selectedValue = "Mobile"; } }, immediate: true, @@ -94,7 +100,14 @@ export default { isMobileOnly: { handler(newValue) { if (newValue) { - this.selectedValues = "Mobile"; + this.selectedValue = "Mobile"; + } + }, + }, + isInshopOnly: { + handler(newValue) { + if (newValue) { + this.selectedValue = "Inshop"; } }, }, diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index a85a5bd17..7b3163c87 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -76,6 +76,7 @@ v-show="isAppointmentTypeDisplayed" :isServiceableMobile="isServiceableMobile" :isServiceableInshop="isServiceableInshop" + :isServiceableDropoff="isServiceableDropoff" :isDisplayed="isAppointmentTypeDisplayed" :mobileFeeApplies="mobileFeeApplies" ref="appointmentTypeQuestion" @@ -196,6 +197,8 @@ export default { isVehicleProtected: this.getIsVehicleProtectedFromStore(), isGlassServiceableInshop: null, isRecalibrationServiceableInshop: null, + isGlassServiceableDropoff: null, + isRecalibrationServiceableDropoff: null, isGlassServiceableMobile: null, isRecalibrationServiceableMobile: null, selectedAppointmentType: this.getSelectedAppointmentType(), @@ -354,6 +357,13 @@ export default { return this.isGlassServiceableInshop; } }, + isServiceableDropoff() { + if (this.isRecalibrationServiceableDropoff !== null) { + return this.isGlassServiceableDropoff && this.isRecalibrationServiceableDropoff; + } else { + return this.isGlassServiceableDropoff; + } + }, isShopQuestionDisplayed() { return ( this.selectedAppointmentType === "Inshop" || @@ -559,6 +569,9 @@ export default { this.isGlassServiceableInshop = serviceabilityDetails.isGlassServiceableInshop; this.isRecalibrationServiceableInshop = serviceabilityDetails.isRecalibrationServiceableInshop; + this.isGlassServiceableDropoff = serviceabilityDetails.isGlassServiceableDropoff; + this.isRecalibrationServiceableDropoff = + serviceabilityDetails.isRecalibrationServiceableDropoff; this.isGlassServiceableMobile = serviceabilityDetails.isGlassServiceableMobile; this.isRecalibrationServiceableMobile = serviceabilityDetails.isRecalibrationServiceableMobile; From 3be58faead23b45d78e53bca4a2b125cba3ea9d6 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Mon, 7 Apr 2025 09:31:36 -0400 Subject: [PATCH 060/110] Format code. Hide menu modal. --- src/App.vue | 3 +- .../funnel-footer/funnel-footer.vue | 73 +++++++++---------- .../funnel-header/funnel-header.vue | 4 +- src/styles/common-styles.scss | 2 +- 4 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/App.vue b/src/App.vue index a0d5cad86..422ae2893 100644 --- a/src/App.vue +++ b/src/App.vue @@ -5,7 +5,7 @@ - + @@ -35,7 +35,6 @@ export default { components: { loadingModal, funnelFooter, - }, }; diff --git a/src/fmg-components/funnel-footer/funnel-footer.vue b/src/fmg-components/funnel-footer/funnel-footer.vue index dc3cf9577..89db470f0 100644 --- a/src/fmg-components/funnel-footer/funnel-footer.vue +++ b/src/fmg-components/funnel-footer/funnel-footer.vue @@ -3,57 +3,50 @@
- +
- +
- diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index af6f9e5ab..3b3ead4c1 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -72,7 +72,8 @@ :donationValues="donationValues" :showDonationSuccess="showDonationSuccess" :showDonationError="showDonationError" - @DonationAddedEvent="addDonationToOrder" /> + @DonationAddedEvent="addDonationToOrder" + ref="donationBlock" />

@@ -544,10 +545,12 @@ export default { false ); this.lineItems = deepClone(this.getSubmittedOrder().lineItems); + this.$refs.donationBlock.removeLoader(); } else { this.showDonationError = true; this.showDonationSuccess = false; this.donationAmount = 0; + this.$refs.donationBlock.removeLoader(); } }, }, From 6965437137303799723a9effc305078c21800e0f Mon Sep 17 00:00:00 2001 From: Chris Redelinghuys Date: Thu, 10 Apr 2025 14:11:55 -0400 Subject: [PATCH 108/110] CASH-203: Add Afterpay breakout display --- src/constants/experiments.js | 2 + .../service-package-radio-for-afterpay.vue | 474 ++++++++++++++++++ .../afterpay-modal-banner.vue | 26 +- src/layouts/quote/quote.spec.js | 6 + src/layouts/quote/quote.vue | 40 ++ .../service-package-question.vue | 23 +- 6 files changed, 565 insertions(+), 6 deletions(-) create mode 100644 src/experiment-components/service-package-radio-for-afterpay.vue diff --git a/src/constants/experiments.js b/src/constants/experiments.js index d64849466..c5c24536d 100644 --- a/src/constants/experiments.js +++ b/src/constants/experiments.js @@ -3,6 +3,7 @@ const experimentUniverses = { RECAL_PRICE_REMOVAL: "NextGen_RecalPriceRemoval", MSR: "MSR", IGQ_SkipQuote: "NextGen_IGQSkipToInsurance", + AFTERPAY_BREAKOUT_DISPLAY: "AfterpayBreakoutDisplay", }; const experimentSettings = { @@ -24,6 +25,7 @@ const experimentSettings = { PRICING_BY_DAY: "DisplayPricingByDay", FOSTER_LOVE: "DisplayFosterLove", SKIP_TO_INSURANCE: "SkipToInsurance", + DISPLAY_AFTERPAY_BREAKOUT_DISPLAY: "Display_AfterpayBreakoutDisplay", }; const experimentTriggers = { diff --git a/src/experiment-components/service-package-radio-for-afterpay.vue b/src/experiment-components/service-package-radio-for-afterpay.vue new file mode 100644 index 000000000..3356ee225 --- /dev/null +++ b/src/experiment-components/service-package-radio-for-afterpay.vue @@ -0,0 +1,474 @@ + + + + + diff --git a/src/layouts/quote/afterpay-modal-banner/afterpay-modal-banner.vue b/src/layouts/quote/afterpay-modal-banner/afterpay-modal-banner.vue index 9f393e260..3b682e52b 100644 --- a/src/layouts/quote/afterpay-modal-banner/afterpay-modal-banner.vue +++ b/src/layouts/quote/afterpay-modal-banner/afterpay-modal-banner.vue @@ -2,16 +2,16 @@ @@ -292,5 +291,12 @@ export default { left: -0.25rem; } } + .custom-secondary { + &:hover { + color: $blue; + background: transparent; + border: 1px solid $blue; + } + } } diff --git a/src/ux-components/button-main/button-main.vue b/src/ux-components/button-main/button-main.vue index fcf78e19b..982e7bb1b 100644 --- a/src/ux-components/button-main/button-main.vue +++ b/src/ux-components/button-main/button-main.vue @@ -3,11 +3,7 @@ :aria-disabled="isDisabled" class="btn d-flex align-items-center justify-content-center py-3 px-4 delay" :class="[ - customSecondary - ? 'btn-secondary custom-secondary' - : isPrimary - ? 'btn-primary' - : 'btn-secondary', + isPrimary ? 'btn-primary' : 'btn-secondary', isFloat ? 'float-end' : '', isLoaderDisplayed && !suppressLoader ? 'has-loader' : '', ]" @@ -33,7 +29,6 @@ export default { loaderPosition: String, isFloat: Boolean, suppressLoader: Boolean, - customSecondary: Boolean, // New property to check if it comes from donationBlock }, data() { return { @@ -161,13 +156,6 @@ export default { transition: background 0s 0s ease-in-out; } } - &.custom-secondary { - &:hover { - color: $blue !important; - background: transparent !important; - border: 1px solid $blue; - } - } &.btn-success { position: relative; background: $green-100;