diff --git a/jest.config.js b/jest.config.js
index ce4aa3ad6..052e1c47b 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -27,6 +27,7 @@ module.exports = {
"!src/layouts/insurance/*.vue", // Temp test exclusion while in development
"!src/layouts/insurance-company/*.vue", // Temp test exclusion while in development
"!src/layouts/insurance-company/insurance-company-question/*.vue", // Temp test exclusion while in development
+ "!src/layouts/return-user/*.vue", // Temp test exclusion while in development
// END
], // ! means exclude from coverage.
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
diff --git a/src/constants/application-config.js b/src/constants/application-config.js
index e49426afb..14f195cfc 100644
--- a/src/constants/application-config.js
+++ b/src/constants/application-config.js
@@ -37,6 +37,8 @@ const applicationConfig = {
FRONTEND_LOGGER_PATH: "/analytics/api/v1/logging",
AFFILIATE_COOKIE_CONTAINING_NAME: "_Track",
COOKIE_NAME_LENGTH_MAX_LIMIT: 44,
+ SESSION_TIMEOUT_MINUTES: process.env.VUE_APP_SESSION_TIMEOUT_MINUTES,
+ RETURN_USER_PAGE: "/fmg/?fmgPage=return-user",
};
export { applicationConfig };
diff --git a/src/constants/cookie-names.js b/src/constants/cookie-names.js
index 72e6168fb..9a6c9a2d1 100644
--- a/src/constants/cookie-names.js
+++ b/src/constants/cookie-names.js
@@ -16,7 +16,7 @@ const cookieNames = {
};
const cookieExpirations = {
- SESSION_ID: convertToSeconds({ minutes: 30 }),
+ SESSION_ID: convertToSeconds({ minutes: applicationConfig.SESSION_TIMEOUT_MINUTES }),
DXDEV: convertToSeconds({ years: 1 }),
FUNNEL_USER_ID: convertToSeconds({ weeks: 1 }),
FUNNEL_SESSION_KEY: convertToSeconds({ minutes: 30 }),
diff --git a/src/digital-components/modal/modal.vue b/src/digital-components/modal/modal.vue
index 0676cb610..461d144ae 100644
--- a/src/digital-components/modal/modal.vue
+++ b/src/digital-components/modal/modal.vue
@@ -217,11 +217,11 @@ export default {
flex: none;
}
.textbox-question {
- padding: .25rem 0;
+ padding: 0.25rem 0;
}
}
}
-
+
&.modal-dialog-centered {
align-items: flex-end;
min-height: 100%;
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 e1fc3e180..a25224f69 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
@@ -98,10 +98,10 @@ export default {
// hide save progress button; show success message alert
this.isProgressSaved = true;
-
+
// communicate to parent the new status
this.$emit("save-progress-saved");
-
+
this.modal.closeModal();
},
},
diff --git a/src/global-methods.js b/src/global-methods.js
index 96c5e21fc..77255e99d 100644
--- a/src/global-methods.js
+++ b/src/global-methods.js
@@ -115,7 +115,7 @@ export default {
currentPage: pageNameToLog,
endpoint: endpoint,
};
-
+
router.navigateError(errorPayload);
// do not log 404 errors from services because we return NotFound
diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue
index 1a3fb9174..c45a5c98c 100644
--- a/src/layouts/payment-method/payment-method.vue
+++ b/src/layouts/payment-method/payment-method.vue
@@ -621,7 +621,7 @@ export default {
: this.$store.getters.order.serviceLocation?.appointmentType;
},
ServiceLocationFullAddressText() {
- return `${this.ServiceLocationAddress.toLowerCase()}${this.ServiceLocationAddress2 ? ", " + this.ServiceLocationAddress2 : ""}, ${this.ServiceLocationCity.toLowerCase()}, ${this.ServiceLocationState} ${this.ServiceLocationZipCode}`;
+ return `${this.ServiceLocationAddress?.toLowerCase()}${this.ServiceLocationAddress2 ? ", " + this.ServiceLocationAddress2 : ""}, ${this.ServiceLocationCity?.toLowerCase()}, ${this.ServiceLocationState} ${this.ServiceLocationZipCode}`;
},
ServiceLocationFullAddress() {
if (this.AppointmentType === AppointmentTypeStrings.MOBILE) {
diff --git a/src/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review.vue b/src/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review.vue
index e4fa9ffa3..32118bb95 100644
--- a/src/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review.vue
+++ b/src/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review.vue
@@ -26,7 +26,7 @@ export default {
computed: {
displayContent() {
return [
- `${this.addressInfo.address.toLowerCase()}${this.addressInfo.address2 ? ", " : ""}${this.addressInfo.address2.toLowerCase()}, ${this.addressInfo.city.toLowerCase()}, ${this.addressInfo.state} ${this.addressInfo.zipCode}`,
+ `${this.addressInfo?.address?.toLowerCase()}${this.addressInfo?.address2 ? ", " : ""}${this.addressInfo?.address2?.toLowerCase()}, ${this.addressInfo?.city?.toLowerCase()}, ${this.addressInfo.state} ${this.addressInfo.zipCode}`,
];
},
addressInfo() {
diff --git a/src/layouts/return-user/return-user.vue b/src/layouts/return-user/return-user.vue
new file mode 100644
index 000000000..189d6592f
--- /dev/null
+++ b/src/layouts/return-user/return-user.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+
diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js
index d534a7200..5a2da603d 100644
--- a/src/mixins/analytics-mixin.js
+++ b/src/mixins/analytics-mixin.js
@@ -26,6 +26,7 @@ import store from "@/store";
import baseMixin from "@/mixins/base-mixin";
import { applicationConfig } from "../constants/application-config";
+import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
export default {
methods: {
@@ -651,7 +652,6 @@ export default {
},
pushPageErrorToDataLayer(error) {
-
pushToDataLayerIfDefined({
event: "page-error",
error: error,
@@ -710,6 +710,17 @@ export default {
},
async validateSession() {
+ // The noSession function checks the cookies related to analytics logging(sid). it is not the funnel info cookie.
+ // The sid cookie for analytics will expire every 30 minutes and get recreated in initSession. If this happens
+ // and we also have the funnel cookie present, that indicates they have an existing session that is now expired
+ // so route them to the return user page.
+ const funnelCookieLastTouched = getFunnelCookie()?.LastTouched;
+ if (this.noSession() && funnelCookieLastTouched !== null && funnelCookieLastTouched !== undefined) {
+ await this.initSession();
+ window.location.href = applicationConfig.RETURN_USER_PAGE;
+ return;
+ }
+
if (this.noSession()) {
await this.initSession();
}
diff --git a/src/router/router-constants/fmgPage-values.js b/src/router/router-constants/fmgPage-values.js
index 6b4ec77ea..5fade6506 100644
--- a/src/router/router-constants/fmgPage-values.js
+++ b/src/router/router-constants/fmgPage-values.js
@@ -22,8 +22,10 @@ const fmgPageValues = {
PAYMENT: "payment",
PAYMENT_PIA_RETURN: "payment-pia-return",
CONFIRMATION: "confirmation",
+ RETURN_USER: "return-user",
};
const funnelStartPageName = fmgPageValues.VEHICLE;
+const returnUserPageName = fmgPageValues.RETURN_USER;
-export { fmgPageValues, funnelStartPageName };
+export { fmgPageValues, funnelStartPageName, returnUserPageName };
diff --git a/vue.config.js b/vue.config.js
index 28d20e406..d8cb42355 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -7,6 +7,7 @@ process.env.VUE_APP_MY_ACCOUNT = "https://myaccountdev.safelite.com/";
//process.env.VUE_APP_SAFELITE_HOP = "http://localhost:60966/fmgCheckoutShared.aspx";
process.env.VUE_APP_SAFELITE_HOP = "https://sv2-safelitehop-dev.safelite.com/fmgCheckoutShared.aspx";
process.env.VUE_APP_SOLARWINDS_MONITORING = "";
+process.env.VUE_APP_SESSION_TIMEOUT_MINUTES = 30;
// GA & GTM
process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY =