From 9822cdfedfab2c7decb73b4a289bcc2cc5b5ce33 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 17 Jan 2025 15:34:05 -0500 Subject: [PATCH] CASH-109 return user page CASH-109 return user page for when a session times out --- src/constants/application-config.js | 2 + src/constants/cookie-names.js | 2 +- src/digital-components/modal/modal.vue | 4 +- .../save-progress-modal-question.vue | 4 +- src/global-methods.js | 2 +- src/layouts/payment-method/payment-method.vue | 2 +- .../service-location-review.vue | 2 +- src/layouts/return-user/return-user.vue | 118 ++++++++++++++++++ src/mixins/analytics-mixin.js | 13 +- src/router/router-constants/fmgPage-values.js | 4 +- vue.config.js | 1 + 11 files changed, 144 insertions(+), 10 deletions(-) create mode 100644 src/layouts/return-user/return-user.vue 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 510f7bc3e..a71271aa4 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 @@ -94,10 +94,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 =