From 32a73e25f43572a0e1a772c72c7c1d4da4cee3cb Mon Sep 17 00:00:00 2001 From: CarlNation Date: Sun, 19 Jan 2025 12:22:51 -0500 Subject: [PATCH] CASH-109 add logic to direct to return user page when navigating from external site excluding heritage CASH-109 add logic to direct to return user page when navigating from external site excluding heritage --- src/constants/query-strings.js | 1 + src/layouts/return-user/return-user.vue | 11 ++- src/mixins/analytics-mixin.js | 6 +- src/router/index.js | 72 ++++++++++++++++++-- src/router/router-constants/routing-table.js | 10 +++ 5 files changed, 90 insertions(+), 10 deletions(-) diff --git a/src/constants/query-strings.js b/src/constants/query-strings.js index 3cdfd655f..210ac28f0 100644 --- a/src/constants/query-strings.js +++ b/src/constants/query-strings.js @@ -45,6 +45,7 @@ const queryStrings = { ORGANIC: "organic", ORGANIC_SOCIAL: "organic_social", EXPERIMENTS: "experiments", + FROM_HERITAGE: "fromheritage", }; export { queryStrings }; diff --git a/src/layouts/return-user/return-user.vue b/src/layouts/return-user/return-user.vue index 189d6592f..3e72c91a9 100644 --- a/src/layouts/return-user/return-user.vue +++ b/src/layouts/return-user/return-user.vue @@ -82,8 +82,10 @@ export default { }, async forwardButtonAction() { - // clicking continue and use no page name to trigger the implicit navigation in router - window.location.href = "/fmg/"; + this.$router.navigateWithoutSaving( + this.navigationScenarios.CLICKED_FORWARD, + this.$route + ); }, async startOver() { @@ -95,7 +97,10 @@ export default { ); deleteFunnelCookie(); await this.dispatchStoreAction(storeActions.RESET_STATE); - window.location.href = "/fmg/"; + this.$router.navigateWithoutSaving( + this.navigationScenarios.CLICKED_FORWARD, + this.$route + ); }, }, components: { diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 5a2da603d..136c0ef14 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -715,7 +715,11 @@ export default { // 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) { + if ( + this.noSession() && + funnelCookieLastTouched !== null && + funnelCookieLastTouched !== undefined + ) { await this.initSession(); window.location.href = applicationConfig.RETURN_USER_PAGE; return; diff --git a/src/router/index.js b/src/router/index.js index f6950b624..f04c0613d 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -26,6 +26,7 @@ import { loadSessionIfPresent, saveSession } from "@/helpers/heritage-integratio import { getPageToRouteExistingOrderTo, navigateToHeritageFunnel, + getImplicitNavigation, } from "@/helpers/heritage-integration/navigation-helper"; import baseMixin from "@/mixins/base-mixin"; @@ -53,6 +54,7 @@ const routes = [ log("------------- router index.js beforeEnter start -----------------"); log(" --to: ", to); log(" --cookie: ", getFunnelCookie()); + log(` --from.redirectedFrom:>${JSON.stringify(from.redirectedFrom)}<`, ""); await analyticsMixin.methods.validateSession(); @@ -78,6 +80,9 @@ const routes = [ return; } + const fromHeritage = getQuerystringParameter(queryStrings.FROM_HERITAGE) === "true"; + const fromReturnUser = from?.name === fmgPageValues.RETURN_USER; + // Intercept all navigation if a submitted order exists in storage if (window.sessionStorage.getItem("submittedOrder") !== null) { if (to.query.fmgPage !== funnelStartPageName) { @@ -86,7 +91,21 @@ const routes = [ } } // On entering the funnel "fresh", read cookie information, decide what to do next. - else if (from.redirectedFrom === undefined) { + else if (from.redirectedFrom === undefined || fromReturnUser) { + // if entering the funnel from non-funnel check and see if there is already a funnel cookie. + // if so, send them to return-user page + const funnelCookieLastTouched = getFunnelCookie()?.LastTouched; + if ( + to?.query?.fmgPage !== fmgPageValues.RETURN_USER && + !fromReturnUser && + !fromHeritage && + funnelCookieLastTouched !== null && + funnelCookieLastTouched !== undefined + ) { + log(" --navigate to return user"); + NavigateToReturnUser(next, to); + } + // clear the saveSessionPromise - if it exists in the vuex store but a new instance was created // the saveSessionPromise will no longer point to a valid promise log(" --clear promise"); @@ -145,6 +164,11 @@ const routes = [ store.commit(storeMutations.RESET_GLASS_PARTS_STATE); } + // if coming from the return user page, clear the destination page so implicit navigation runs + if (fromReturnUser && to.query) { + to.query[queryStrings.FMG_PAGE] = ""; + } + const pageToRedirectTo = await getPageToRouteExistingOrderTo(to); log(" --pageToRedirectTo ", JSON.stringify(pageToRedirectTo)); @@ -237,11 +261,11 @@ const routes = [ GoToFunnelStartOn404(next, errorPayload); return; - } // Get route info for the given url. Names will have a 1:1 relationship with names in the Cms. const routeData = GetRouteInfoFromPageName(to.query.fmgPage); + log("--routeData:", routeData); // Add our dynamic route. router.addRoute({ @@ -258,7 +282,6 @@ const routes = [ .components.default(); if (!arePagePrerequisitesValid(nextComponent)) { - // prettier-ignore console.log("Page Prereqs not valid for next component: " + nextComponent.default.name); @@ -319,6 +342,7 @@ const router = createRouter({ //---------------------------------------------------------- Router Functions ---------------------------------------------------------- router.beforeEach(async (to, from, next) => { + log("------------- router index.js beforeEach start -----------------"); // set lastNavigationPage here to capture state before API calls for analytics. // use current page url query string name when to.name is "root" (due to unresolved navigation in beforeEach) router.lastNavigationPage = to.name == "root" ? analyticsMixin.methods.getPageName() : to.name; @@ -370,6 +394,7 @@ router.beforeEach(async (to, from, next) => { } else { next(); } + log("------------- router index.js beforeEach end -----------------"); }); router.afterEach(async (to, from) => { @@ -626,6 +651,42 @@ function GetRouteInfoFromPageName(pageName) { return routeData; } +async function NavigateToReturnUser(next, to) { + const returnRoute = GetRouteInfoFromPageName(fmgPageValues.RETURN_USER); + log("--returnRoute:", returnRoute); + + if (router.hasRoute(to.query.fmgPage)) { + // Since our route is already in scope, we can grab the component from it and call the arePagePrerequisitesValid function. + let component = router + .getRoutes() + .filter((x) => x.name === fmgPageValues.RETURN_USER)[0].components; + + log("--return-user component:", component); + + // If the component hasn't been loaded fully, load it before we check prerequisites. + if (component.default.methods === undefined) { + component = await component.default(); + } + + log(" --has route for return-user:", fmgPageValues.RETURN_USER); + return next({ name: fmgPageValues.RETURN_USER, query: to.query, params: to.params }); + } else { + log(" --add route for return-user:", fmgPageValues.RETURN_USER); + router.addRoute({ + path: returnRoute[0].path, // Always the same path, because we control it with query strings. + name: returnRoute[0].name, + component: returnRoute[0].component, + }); + + next({ + name: returnRoute[0].name, + query: Object.assign(to.query, { fmgPage: returnRoute[0].name }), + params: to.params, + }); + return; + } +} + // Go to our start page on a 404. function GoToFunnelStartOn404(next, errorPayload = null) { if (errorPayload !== null) { @@ -637,7 +698,6 @@ function GoToFunnelStartOn404(next, errorPayload = null) { "color: white; background-color: blue; padding: 5px;", errorPayload ); - } // Put item on the bus @@ -661,7 +721,7 @@ function GoToFunnelStartOn404(next, errorPayload = null) { async function DisplayPageError(errorPayload = null) { console.log("%c running DisplayPageError()... ", "font-size: 20px; color: purple;"); - if(errorPayload !== null) { + if (errorPayload !== null) { errorPayload.type = "DisplayPageError"; analyticsMixin.methods.pushPageErrorToDataLayer(errorPayload); } else { @@ -670,7 +730,7 @@ async function DisplayPageError(errorPayload = null) { try { currentPage = getQuerystringParameter(queryStrings.FMG_PAGE); } catch (e) { - // pass + // pass } errorPayload = { type: "DisplayPageError", diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 3e3dbd4bf..8891e7cff 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -530,6 +530,16 @@ const routingTable = function (store) { { fmgPageValue: fmgPageValues.CONFIRMATION, }, + // The destination page for return user does not matter. the router will invoke implicit navigation + { + fmgPageValue: fmgPageValues.RETURN_USER, + maps: [ + { + scenario: navigationScenarios.CLICKED_FORWARD, + destinationFmgPageValue: fmgPageValues.VEHICLE, + }, + ], + }, ]; };