diff --git a/src/layouts/estimate/estimate.vue b/src/layouts/estimate/estimate.vue index 66d1544d9..0a5db7d74 100644 --- a/src/layouts/estimate/estimate.vue +++ b/src/layouts/estimate/estimate.vue @@ -62,7 +62,7 @@ import { saveSession } from "@/helpers/heritage-integration/order-helper.js"; import baseMixin from "@/mixins/base-mixin.js"; import { queryStrings } from "@/constants/query-strings"; import { nextTick } from "vue"; -import { consumeQueryFromStash } from "@/router/a-rewrite/methods/helpers/querystring-stash"; +import { consumeQueryFromStash } from "@/router/a-rewrite/logic/querystring-stash"; // Define Validation Rules defineRule("zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED)); diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index 673116965..a6bb07bab 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -119,7 +119,7 @@ import baseMixin from "@/mixins/base-mixin.js"; import store from "@/store"; import vinPagesMixin from "@/mixins/vin-pages-mixin"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; -import { consumeQueryFromStash } from "@/router/a-rewrite/methods/helpers/querystring-stash"; +import { consumeQueryFromStash } from "@/router/a-rewrite/logic/querystring-stash"; import { queryStrings } from "@/constants/query-strings"; // DEFINE VALIDATION RULES diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index 51a3ffd5d..d07434c1f 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -168,7 +168,7 @@ import { getSubTotal, getSalesTax, } from "@/helpers/pricing-helper.js"; -import { consumeQueryFromStash } from "@/router/a-rewrite/methods/helpers/querystring-stash"; +import { consumeQueryFromStash } from "@/router/a-rewrite/logic/querystring-stash"; defineRule("payment-method-required", required(errorMessages.OPTION_REQUIRED)); defineRule("recal-ack-required", required(errorMessages.RECAL_ACK_REQUIRED)); diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index c095d00be..f100a9f32 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -169,7 +169,7 @@ import { } from "@/helpers/heritage-integration/cookie-helper"; import { showFmgLoadingModal } from "@/helpers/loading-modal-helper"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; -import { consumeQueryFromStash } from "@/router/a-rewrite/methods/helpers/querystring-stash"; +import { consumeQueryFromStash } from "@/router/a-rewrite/logic/querystring-stash"; import { storeMutations } from "@/constants/store-mutations"; defineRule("option-required", required(errorMessages.OPTION_REQUIRED)); diff --git a/src/layouts/service-zip/service-zip.vue b/src/layouts/service-zip/service-zip.vue index 6e0bccda6..16c6f7f72 100644 --- a/src/layouts/service-zip/service-zip.vue +++ b/src/layouts/service-zip/service-zip.vue @@ -96,7 +96,7 @@ import { saveSession } from "@/helpers/heritage-integration/order-helper.js"; import baseMixin from "@/mixins/base-mixin.js"; import { queryStrings } from "@/constants/query-strings"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; -import { consumeQueryFromStash } from "@/router/a-rewrite/methods/helpers/querystring-stash"; +import { consumeQueryFromStash } from "@/router/a-rewrite/logic/querystring-stash"; // Define Validation Rules defineRule("zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED)); diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index 8686be85b..1d2e7d2bb 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -113,7 +113,7 @@ import { getQuerystringParameter } from "@/helpers/querystring-helper"; import { consumeQueryFromStash, peekQueryFromStash, -} from "@/router/a-rewrite/methods/helpers/querystring-stash"; +} from "@/router/a-rewrite/logic/querystring-stash"; //define validation rules defineRule("year-required", required(errorMessages.YEAR_REQUIRED)); diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index 277e176f5..5db93d76d 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -160,7 +160,7 @@ import baseMixin from "@/mixins/base-mixin.js"; import store from "@/store"; import vinPagesMixin from "@/mixins/vin-pages-mixin"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; -import { consumeQueryFromStash } from "@/router/a-rewrite/methods/helpers/querystring-stash"; +import { consumeQueryFromStash } from "@/router/a-rewrite/logic/querystring-stash"; import { queryStrings } from "@/constants/query-strings"; // DEFINE VALIDATION RULES diff --git a/src/router/a-rewrite/constants/externalUrl-values.js b/src/router/a-rewrite/constants/externalUrl-values.js deleted file mode 100644 index 5516095c4..000000000 --- a/src/router/a-rewrite/constants/externalUrl-values.js +++ /dev/null @@ -1,6 +0,0 @@ -const externalUrls = { - HERITAGE_FUNNEL: process.env.VUE_APP_HERITAGE_FUNNEL, - SAFELITE_HOP: process.env.VUE_APP_SAFELITE_HOP, -}; - -export { externalUrls }; diff --git a/src/router/a-rewrite/index.js b/src/router/a-rewrite/index.js index 37bd5aa0d..3a84a1730 100644 --- a/src/router/a-rewrite/index.js +++ b/src/router/a-rewrite/index.js @@ -1,16 +1,216 @@ -import { routes } from "@/router/a-rewrite/methods/routes"; -import { afterEach } from "@/router/a-rewrite/methods/after-each"; -import { beforeEach } from "@/router/a-rewrite/methods/before-each"; -import { bailout } from "@/router/a-rewrite/methods/error"; -import { - navigateWithoutSaving, - navigateWithSaving, - navigateWithPageData, - navigateAndForceTopLevelNavigation, -} from "@/router/a-rewrite/methods/navigate"; -import { navigateToExternalUrl } from "@/router/a-rewrite/methods/navigate-external"; +import { routeData, FUNNEL_START_PAGE } from "@/router/a-rewrite/constants/routes"; +import { createRoute, createVirtualRoute } from "@/router/a-rewrite/logic/create-route"; +import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; import { createWebHistory, createRouter } from "vue-router"; +import { getDestination } from "@/router/a-rewrite/logic/get-destination"; +import analyticsMixin from "@/mixins/analytics-mixin"; +import { + getFunnelCookie, + deleteFunnelCookie, + updateOrCreateFunnelCookie, +} from "@/helpers/heritage-integration/cookie-helper"; +import { isSavedSessionStillActive } from "@/helpers/heritage-integration/session-helper"; +import { loadSessionIfPresent, saveSession } from "@/helpers/heritage-integration/order-helper"; +import store from "@/store"; +import { storeActions } from "@/constants/store-actions"; +import { storeMutations } from "@/constants/store-mutations"; +import { sessionStorageKeyConstants } from "@/constants/session-storage"; +import { savePageData } from "@/router/a-rewrite/logic/save-page-data"; +import eventBus from "@/helpers/event-bus/event-bus"; +import { globalEvents, globalEventTypes } from "@/constants/events"; +import { autoRouteTable } from "@/router/a-rewrite/constants/auto-route-table"; +import { queryStrings } from "@/constants/query-strings"; +import { consumeReferralQuerystrings } from "@/router/a-rewrite/logic/consume-referral-info"; +import { initializeFromQueryStrings } from "@/router/a-rewrite/logic/initialize-from-querystrings"; +import { getBoolFromString } from "@/helpers/boolean-helper"; +import { isVerifiedInsurance } from "@/router/a-rewrite/logic/requires-verified-redirect"; +import baseMixin from "@/mixins/base-mixin"; +import { runExperiments } from "@/router/a-rewrite/logic/run-experiments"; import { ROUTE_PREFIX_FULL } from "@/router/a-rewrite/constants/route-prefix"; +import { buildManualUrl } from "@/router/a-rewrite/logic/build-manual-url"; +import { consumeQueryFromStash, stashAllQueries } from "@/router/a-rewrite/logic/querystring-stash"; + +const routes = [ + // Non-virtual pages. + createRoute(routeData.VEHICLE, async (to, from) => { + // If cookie indicates that vehicle has changed during insurance flow, reset parts info. + const hasVehicleChanged = getBoolFromString(getFunnelCookie()?.HasDelayedClaimRegistration); + if (hasVehicleChanged) { + store.commit(storeMutations.RESET_GLASS_PARTS_STATE); + } + + if (isVerifiedInsurance()) { + return { + name: routeData.VEHICLE_DAMAGE.name, + replace: true, + }; + } + }), + createRoute(routeData.VEHICLE_DAMAGE), + createRoute(routeData.ESTIMATE), + createRoute(routeData.ADDRESS_LOOKUP), + createRoute(routeData.VIN_LOOKUP), + createRoute(routeData.LICENSE_PLATE_LOOKUP), + createRoute(routeData.SERVICE_ZIP), + createRoute(routeData.ADDRESS_VEHICLES), + createRoute(routeData.VEHICLE_PARTS), + createRoute(routeData.PART_QUESTIONS), + createRoute(routeData.MOLDING_QUESTIONS), + createRoute(routeData.CAPABILITY_QUESTIONS), + createRoute(routeData.QUOTE, async (to, from) => { + if (isVerifiedInsurance()) { + return { + name: routeData.HERITAGE.name, + replace: true, + }; + } + + const offerQuote = to.query?.[queryStrings.OFFER_QUOTE]; + + if (offerQuote === "true") { + store.commit(storeMutations.UPDATE_IS_INSURANCE, false); + } + }), + createRoute(routeData.INSURANCE_COMPANY, async (to, from) => { + if (isVerifiedInsurance()) { + return { + name: routeData.HERITAGE.name, + replace: true, + }; + } + }), + createRoute(routeData.SERVICE_LOCATION), + createRoute(routeData.SCHEDULE), + createRoute(routeData.CUSTOMER_DETAILS), + createRoute(routeData.PAYMENT_METHOD), + createRoute(routeData.PAYMENT), + createRoute(routeData.PAYMENT_PIA_RETURN), + createRoute(routeData.CONFIRMATION), + createRoute(routeData.RETURN_USER), + + // Virtual pages (resolve to a non-virtual page.) + createVirtualRoute(routeData.LANDING, async (to, from) => { + await initializeFromQueryStrings(); + // Save querystrings to temporary stash so they can be referred to later. + stashAllQueries(to); + // Change referral info. For use in local testing for insurance crossover. + await consumeReferralQuerystrings(); + + // Check for fmgpage parameter + const fmgPage = to?.query?.fmgPage; + if (fmgPage && router.hasRoute(fmgPage)) { + return { + name: fmgPage, + replace: true, + }; + } + + // If a session is still in memory, go to return-user. + if (store.getters.vehicle?.year > 0) { + console.log(`trying to redirect!`); + return { + name: routeData.RETURN_USER.name, + replace: true, + }; + } + + // Otherwise, load session and auto-route + return { + name: routeData.LOAD_SESSION.name, + replace: true, + }; + }), + createVirtualRoute(routeData.HERITAGE, async (to, from) => { + await navigateToHeritageFunnel({ shouldSaveSession: false, pageNameToLog: to.name }); + }), + createVirtualRoute(routeData.LOAD_SESSION, async (to, from) => { + const loadSessionResponse = await loadSessionIfPresent(false, to.name); + + return { + name: routeData.AUTO_ROUTE.name, + replace: true, + }; + }), + createVirtualRoute(routeData.AUTO_ROUTE, async (to, from) => { + for (let i = 0; i < autoRouteTable.length; i++) { + const testRouteData = autoRouteTable[i]; + + const isReady = await router.checkPagePrerequisites(testRouteData.name); + + if (isReady) { + return { + name: testRouteData.name, + replace: true, + }; + } + } + + return { + name: FUNNEL_START_PAGE, + replace: true, + }; + }), + createVirtualRoute(routeData.ERROR, async (to, from) => { + // If we've already encountered one error, clear session to avoid more. + // Otherwise mark that we encoutnered an error here. + if (store.getters.applicationUser.hasAlreadyTriggeredError) { + return { + name: routeData.RESTART.name, + replace: true, + }; + } else { + await store.dispatch(storeActions.UPDATE_HAS_TRIGGERED_ERROR, true); + } + + // Add error event to bus + eventBus.addEventToBus( + globalEvents.Categories.GLOBAL_ALERT, + globalEvents.SubCategories.UNKNOWN_ERROR, + { + isDismissable: true, + messageCopy: "", + messageHeadline: "We're sorry, something went wrong.", + type: globalEventTypes.Danger, + } + ); + + let nextPage = FUNNEL_START_PAGE.name; + + baseMixin.methods?.ResetExternalParamsAndHideModal(); + + if (store.getters.payment?.insuranceCoverage?.isVerified) { + nextPage = routeData.VEHICLE_DAMAGE.name; + } + + if (from.name === nextPage) { + // Router won't load the page if we redirect to the already existing page + // Force refresh in this scenario. + router.go(0); + return false; + } + + return { + name: nextPage, + replace: false, + }; + }), + createVirtualRoute(routeData.RESTART, async (to, from) => { + await store.dispatch(storeActions.RESET_STATE); + deleteFunnelCookie(); + + if (from.name === FUNNEL_START_PAGE.name) { + // Router won't load the page if we redirect to the already existing page + // Force refresh in this scenario. + router.go(0); + return false; + } + + return { + name: FUNNEL_START_PAGE.name, + replace: true, + }; + }), +]; const router = createRouter({ history: createWebHistory(ROUTE_PREFIX_FULL), @@ -21,18 +221,201 @@ const router = createRouter({ }, }); -// Set guards -router.afterEach(async (to, from) => afterEach(to, from)); -router.beforeEach(async (to, from) => beforeEach(to, from)); +////-- Global Guards -// Bind methods for external use -router.navigateWithSaving = navigateWithSaving; -router.navigateWithoutSaving = navigateWithoutSaving; -router.navigateWithPageData = navigateWithPageData; -router.navigateAndForceTopLevelNavigation = navigateAndForceTopLevelNavigation; +router.beforeEach(async (to, from) => { + console.log(to); + try { + await analyticsMixin.methods.validateSession(); -router.bailout = bailout; + if (getFunnelCookie()?.SuppressConceptFunnel) { + // Redirect to heritage. + return { + name: routeData.HERITAGE.name, + }; + } -router.navigateToExternalUrl = navigateToExternalUrl; + // Ensure session has not expired + if (getFunnelCookie() !== null && !isSavedSessionStillActive()) { + const errorPayload = { + cause: "expired session", + currentPage: from?.name, + nextPage: to?.name, + }; + + router.bailout(errorPayload, true); + return false; + } + + // Block navigation if an order has been submitted. + if (window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) !== null) { + if (to.name !== FUNNEL_START_PAGE.name && to.name !== routeData.CONFIRMATION.name) { + return false; + } + } + + // Process funnel cookie. + updateOrCreateFunnelCookie(); + + // If sent from heritage, need to load session. + const fromHeritageFlag = consumeQueryFromStash(queryStrings.FROM_HERITAGE); + if (fromHeritageFlag) { + await loadSessionIfPresent(true, routeData.SERVICE_LOCATION.name); + } + + // Ensure page-prerequisites are fulfilled + const arePagePrerequisitesValid = await router.checkPagePrerequisites(to.name); + + if (!arePagePrerequisitesValid) { + const errorPayload = { + cause: "invalid page prerequisites for page", + currentPage: from?.name, + nextPage: to?.name, + }; + + router.bailout(errorPayload); + return; + } + + await runExperiments(to.name); + } catch (error) { + const errorPayload = { + cause: "Uncaught exception in `beforeEach`.", + currentPage: from?.name, + nextPage: to?.name, + }; + + console.log(error); + + router.bailout(errorPayload); + return; + } +}); + +router.afterEach(async (to, from) => { + // Push page view to GA + analyticsMixin.methods.pushPageViewToGA(); + + // Push experiments to Data Layer + analyticsMixin.methods.pushExperimentsToDataLayer(); + + // Push current order status to Data Layer + analyticsMixin.methods.pushOrderToDataLayer(); +}); + +////-- End Global Guards + +////-- Bound Functions + +router.getRoute = (pageName) => { + return router.getRoutes().find((r) => r.name === pageName); +}; + +router.checkPagePrerequisites = async (pageName) => { + const route = router.getRoute(pageName); + + if (!route) { + return false; + } + + let component = route.components; + + // Virtual routes have no component, so skip check. + if (!component) { + return true; + } + + if (component?.default?.methods === undefined) { + component = await component?.default(); + } + + return component?.default?.methods?.arePagePrerequisitesValid(); +}; + +router.navigateWithoutSaving = async (scenario, currentPageName) => { + return await router.navigate(currentPageName, scenario, false); +}; + +router.navigateWithSaving = async (scenario, currentPageName) => { + return await router.navigate(currentPageName, scenario, true); +}; + +router.navigateWithPageData = async (scenario, currentPageName, pageData = {}) => { + const nextPage = getDestination(currentPageName, scenario); + await savePageData(nextPage.name, pageData); + + return await router.navigate(currentPageName, scenario, true); +}; + +router.navigateAndForceTopLevelNavigation = async (scenario, currentPageName, saving = false) => { + return await router.navigate(currentPageName, scenario, saving, true); +}; + +router.bailout = (errorPayload, forceRestart = false) => { + analyticsMixin.methods.pushPageErrorToDataLayer(errorPayload); + + if (forceRestart) { + router.push({ + name: routeData.RESTART.name, + }); + } else { + router.push({ + name: routeData.ERROR.name, + }); + } +}; + +router.navigate = async ( + currentPageName, + scenario, + withSaving = false, + forceTopLevelNav = false +) => { + // Check to see if calling page is same as current page. + // If not, cancel navigation before it begins. + const callingRoute = currentPageName; + const actualRoute = router.currentRoute.value.name; + + if (callingRoute !== actualRoute) { + return false; + } + + const nextPage = getDestination(currentPageName, scenario); + + if (!nextPage) { + console.error( + `Could not navigate from ${currentPageName} via scenario ${scenario}. Ensure routing table is configured correctly.` + ); + + const errorPayload = { + cause: "invalid page name", + currentPage: currentPageName, + nextPage: nextPage?.name, + }; + + router.bailout(errorPayload); + return; + } + + if (withSaving) { + await saveSession({ pageNameToLog: nextPage.name }); + } + + // Some pages require manually setting the next url + // to work with iframes. + if (forceTopLevelNav) { + const newUrl = buildManualUrl(nextPage); + window.top.location.href = newUrl; + return; + } + + // All other pages use router.push + router.push({ + name: nextPage.name, + query: nextPage.params ?? {}, + }); +}; + +////-- End Router Functions export default router; diff --git a/src/router/a-rewrite/methods/helpers/build-manual-url.js b/src/router/a-rewrite/logic/build-manual-url.js similarity index 93% rename from src/router/a-rewrite/methods/helpers/build-manual-url.js rename to src/router/a-rewrite/logic/build-manual-url.js index 260b41257..017816d6b 100644 --- a/src/router/a-rewrite/methods/helpers/build-manual-url.js +++ b/src/router/a-rewrite/logic/build-manual-url.js @@ -9,7 +9,7 @@ export function buildManualUrl(nextPage) { return url; } -export function buildSearchParams(paramList) { +function buildSearchParams(paramList) { if (!paramList) { return ""; } diff --git a/src/router/a-rewrite/methods/helpers/consume-referral-info.js b/src/router/a-rewrite/logic/consume-referral-info.js similarity index 100% rename from src/router/a-rewrite/methods/helpers/consume-referral-info.js rename to src/router/a-rewrite/logic/consume-referral-info.js diff --git a/src/router/a-rewrite/methods/helpers/create-route.js b/src/router/a-rewrite/logic/create-route.js similarity index 92% rename from src/router/a-rewrite/methods/helpers/create-route.js rename to src/router/a-rewrite/logic/create-route.js index a1535f3c8..44e27b568 100644 --- a/src/router/a-rewrite/methods/helpers/create-route.js +++ b/src/router/a-rewrite/logic/create-route.js @@ -1,4 +1,4 @@ -import { lazyLoadComponent } from "@/router/a-rewrite/methods/helpers/lazy-load-component"; +import { lazyLoadComponent } from "@/router/a-rewrite/logic/lazy-load-component"; import { routeData } from "@/router/a-rewrite/constants/routes"; export function createRoute(routeDatum, beforeEnter = async (to, from) => undefined) { diff --git a/src/router/a-rewrite/methods/helpers/get-destination.js b/src/router/a-rewrite/logic/get-destination.js similarity index 100% rename from src/router/a-rewrite/methods/helpers/get-destination.js rename to src/router/a-rewrite/logic/get-destination.js diff --git a/src/router/a-rewrite/methods/helpers/initialize-from-querystrings.js b/src/router/a-rewrite/logic/initialize-from-querystrings.js similarity index 100% rename from src/router/a-rewrite/methods/helpers/initialize-from-querystrings.js rename to src/router/a-rewrite/logic/initialize-from-querystrings.js diff --git a/src/router/a-rewrite/methods/helpers/lazy-load-component.js b/src/router/a-rewrite/logic/lazy-load-component.js similarity index 100% rename from src/router/a-rewrite/methods/helpers/lazy-load-component.js rename to src/router/a-rewrite/logic/lazy-load-component.js diff --git a/src/router/a-rewrite/methods/helpers/querystring-stash.js b/src/router/a-rewrite/logic/querystring-stash.js similarity index 100% rename from src/router/a-rewrite/methods/helpers/querystring-stash.js rename to src/router/a-rewrite/logic/querystring-stash.js diff --git a/src/router/a-rewrite/methods/helpers/requires-verified-redirect.js b/src/router/a-rewrite/logic/requires-verified-redirect.js similarity index 100% rename from src/router/a-rewrite/methods/helpers/requires-verified-redirect.js rename to src/router/a-rewrite/logic/requires-verified-redirect.js diff --git a/src/router/a-rewrite/methods/helpers/run-experiments.js b/src/router/a-rewrite/logic/run-experiments.js similarity index 100% rename from src/router/a-rewrite/methods/helpers/run-experiments.js rename to src/router/a-rewrite/logic/run-experiments.js diff --git a/src/router/a-rewrite/methods/helpers/save-page-data.js b/src/router/a-rewrite/logic/save-page-data.js similarity index 100% rename from src/router/a-rewrite/methods/helpers/save-page-data.js rename to src/router/a-rewrite/logic/save-page-data.js diff --git a/src/router/a-rewrite/methods/after-each.js b/src/router/a-rewrite/methods/after-each.js deleted file mode 100644 index ef3dc0d93..000000000 --- a/src/router/a-rewrite/methods/after-each.js +++ /dev/null @@ -1,12 +0,0 @@ -import analyticsMixin from "@/mixins/analytics-mixin"; - -export async function afterEach(to, from) { - // Push page view to GA - analyticsMixin.methods.pushPageViewToGA(); - - // Push experiments to Data Layer - analyticsMixin.methods.pushExperimentsToDataLayer(); - - // Push current order status to Data Layer - analyticsMixin.methods.pushOrderToDataLayer(); -} diff --git a/src/router/a-rewrite/methods/before-each.js b/src/router/a-rewrite/methods/before-each.js deleted file mode 100644 index 05264ed3c..000000000 --- a/src/router/a-rewrite/methods/before-each.js +++ /dev/null @@ -1,83 +0,0 @@ -import { queryStrings } from "@/constants/query-strings"; -import { sessionStorageKeyConstants } from "@/constants/session-storage"; -import { - getFunnelCookie, - updateOrCreateFunnelCookie, -} from "@/helpers/heritage-integration/cookie-helper"; -import { loadSessionIfPresent } from "@/helpers/heritage-integration/order-helper"; -import { isSavedSessionStillActive } from "@/helpers/heritage-integration/session-helper"; -import analyticsMixin from "@/mixins/analytics-mixin"; -import { routeData, FUNNEL_START_PAGE } from "@/router/a-rewrite/constants/routes"; -import { consumeQueryFromStash } from "@/router/a-rewrite/methods/helpers/querystring-stash"; -import { runExperiments } from "@/router/a-rewrite/methods/helpers/run-experiments"; - -import { bailout } from "@/router/a-rewrite/methods/error"; -import { checkPagePrerequisites } from "@/router/a-rewrite/methods/page-prerequisites"; - -export async function beforeEach(to, from) { - try { - await analyticsMixin.methods.validateSession(); - - if (getFunnelCookie()?.SuppressConceptFunnel) { - // Redirect to heritage. - return { - name: routeData.HERITAGE.name, - }; - } - - // Ensure session has not expired - if (getFunnelCookie() !== null && !isSavedSessionStillActive()) { - const errorPayload = { - cause: "expired session", - currentPage: from?.name, - nextPage: to?.name, - }; - - bailout(errorPayload, true); - return false; - } - - // Block navigation if an order has been submitted. - if (window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) !== null) { - if (to.name !== FUNNEL_START_PAGE.name && to.name !== routeData.CONFIRMATION.name) { - return false; - } - } - - // Process funnel cookie. - updateOrCreateFunnelCookie(); - - // If sent from heritage, need to load session. - const fromHeritageFlag = consumeQueryFromStash(queryStrings.FROM_HERITAGE); - if (fromHeritageFlag) { - await loadSessionIfPresent(true, routeData.SERVICE_LOCATION.name); - } - - // Ensure page-prerequisites are fulfilled - const arePagePrerequisitesValid = await checkPagePrerequisites(to.name); - - if (!arePagePrerequisitesValid) { - const errorPayload = { - cause: "invalid page prerequisites for page", - currentPage: from?.name, - nextPage: to?.name, - }; - - bailout(errorPayload); - return; - } - - await runExperiments(to.name); - } catch (error) { - const errorPayload = { - cause: "Uncaught exception in `beforeEach`.", - currentPage: from?.name, - nextPage: to?.name, - }; - - console.log(error); - - bailout(errorPayload); - return; - } -} diff --git a/src/router/a-rewrite/methods/error.js b/src/router/a-rewrite/methods/error.js deleted file mode 100644 index 3c50c1768..000000000 --- a/src/router/a-rewrite/methods/error.js +++ /dev/null @@ -1,17 +0,0 @@ -import analyticsMixin from "@/mixins/analytics-mixin"; -import { routeData } from "@/router/a-rewrite/constants/routes"; -import router from "@/router/a-rewrite"; - -export async function bailout(errorPayload, forceRestart = false) { - analyticsMixin.methods.pushPageErrorToDataLayer(errorPayload); - - if (forceRestart) { - router.push({ - name: routeData.RESTART.name, - }); - } else { - router.push({ - name: routeData.ERROR.name, - }); - } -} diff --git a/src/router/a-rewrite/methods/get-route.js b/src/router/a-rewrite/methods/get-route.js deleted file mode 100644 index ead89eb5b..000000000 --- a/src/router/a-rewrite/methods/get-route.js +++ /dev/null @@ -1,5 +0,0 @@ -import router from "@/router/a-rewrite"; - -export function getRoute(pageName) { - return router.getRoutes().find((r) => r.name === pageName); -} diff --git a/src/router/a-rewrite/methods/navigate-external.js b/src/router/a-rewrite/methods/navigate-external.js deleted file mode 100644 index 622bf1e99..000000000 --- a/src/router/a-rewrite/methods/navigate-external.js +++ /dev/null @@ -1,10 +0,0 @@ -export function navigateToExternalUrl(url, optionalQuery = {}) { - // possibly show some loading screen in the future here. - var externalUrl = new URL(url); - - for (const queryKey in optionalQuery) { - externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]); - } - - window.location.assign(externalUrl); -} diff --git a/src/router/a-rewrite/methods/navigate.js b/src/router/a-rewrite/methods/navigate.js deleted file mode 100644 index ca8de4784..000000000 --- a/src/router/a-rewrite/methods/navigate.js +++ /dev/null @@ -1,84 +0,0 @@ -import { saveSession } from "@/helpers/heritage-integration/order-helper"; -import { buildManualUrl } from "@/router/a-rewrite/methods/helpers/build-manual-url"; -import { getDestination } from "@/router/a-rewrite/methods/helpers/get-destination"; -import { savePageData } from "@/router/a-rewrite/methods/helpers/save-page-data"; -import router from "@/router/a-rewrite"; - -import { bailout } from "@/router/a-rewrite/methods/error"; - -async function navigate(scenario, currentPageName, withSaving = false, forceTopLevelNav = false) { - console.log(`Navigate:\n - - scenario: ${scenario}\n - - currentPage: ${currentPageName}\n - - withSaving: ${withSaving}\n - - forceTopLevelNav: ${forceTopLevelNav}`); - - // Check to see if calling page is same as current page. - // If not, cancel navigation before it begins. - const callingRoute = currentPageName; - const actualRoute = router.currentRoute.value.name; - - if (callingRoute !== actualRoute) { - return false; - } - - const nextPage = getDestination(currentPageName, scenario); - - if (!nextPage) { - console.error( - `Could not navigate from ${currentPageName} via scenario ${scenario}. Ensure routing table is configured correctly.` - ); - - const errorPayload = { - cause: "invalid page name", - currentPage: currentPageName, - nextPage: nextPage?.name, - }; - - bailout(errorPayload); - return; - } - - if (withSaving) { - await saveSession({ pageNameToLog: nextPage.name }); - } - - // Some pages require manually setting the next url - // to work with iframes. - if (forceTopLevelNav) { - const newUrl = buildManualUrl(nextPage); - window.top.location.href = newUrl; - return; - } - - // All other pages use router.push - router.push({ - name: nextPage.name, - query: nextPage.params ?? {}, - }); -} - -//// -- Aliases: what's actually called - -export async function navigateWithoutSaving(scenario, currentPageName) { - return await navigate(scenario, currentPageName, false); -} - -export async function navigateWithSaving(scenario, currentPageName) { - return await navigate(scenario, currentPageName, true); -} - -export async function navigateWithPageData(scenario, currentPageName, pageData = {}) { - const nextPage = getDestination(currentPageName, scenario); - await savePageData(nextPage.name, pageData); - - return await navigate(scenario, currentPageName, true); -} - -export async function navigateAndForceTopLevelNavigation( - scenario, - currentPageName, - saving = false -) { - return await navigate(scenario, currentPageName, saving, true); -} diff --git a/src/router/a-rewrite/methods/page-prerequisites.js b/src/router/a-rewrite/methods/page-prerequisites.js deleted file mode 100644 index 581ab0354..000000000 --- a/src/router/a-rewrite/methods/page-prerequisites.js +++ /dev/null @@ -1,22 +0,0 @@ -import { getRoute } from "@/router/a-rewrite/methods/get-route"; - -export async function checkPagePrerequisites(pageName) { - const route = getRoute(pageName); - - if (!route) { - return false; - } - - let component = route.components; - - // Virtual routes have no component, so skip check. - if (!component) { - return true; - } - - if (component?.default?.methods === undefined) { - component = await component?.default(); - } - - return component?.default?.methods?.arePagePrerequisitesValid(); -} diff --git a/src/router/a-rewrite/methods/route-logic/auto-route.js b/src/router/a-rewrite/methods/route-logic/auto-route.js deleted file mode 100644 index a6d55e4fa..000000000 --- a/src/router/a-rewrite/methods/route-logic/auto-route.js +++ /dev/null @@ -1,23 +0,0 @@ -import { autoRouteTable } from "@/router/a-rewrite/constants/auto-route-table"; -import { FUNNEL_START_PAGE } from "@/router/a-rewrite/constants/routes"; -import { checkPagePrerequisites } from "@/router/a-rewrite/methods/page-prerequisites"; - -export async function autoRouteBeforeEnter(to, from) { - for (let i = 0; i < autoRouteTable.length; i++) { - const testRouteData = autoRouteTable[i]; - - const isReady = await checkPagePrerequisites(testRouteData.name); - - if (isReady) { - return { - name: testRouteData.name, - replace: true, - }; - } - } - - return { - name: FUNNEL_START_PAGE, - replace: true, - }; -} diff --git a/src/router/a-rewrite/methods/route-logic/error.js b/src/router/a-rewrite/methods/route-logic/error.js deleted file mode 100644 index c4bdeb6d5..000000000 --- a/src/router/a-rewrite/methods/route-logic/error.js +++ /dev/null @@ -1,52 +0,0 @@ -import { globalEvents, globalEventTypes } from "@/constants/events"; -import { storeActions } from "@/constants/store-actions"; -import eventBus from "@/helpers/event-bus/event-bus"; -import baseMixin from "@/mixins/base-mixin"; -import router from "@/router/a-rewrite"; -import { routeData, FUNNEL_START_PAGE } from "@/router/a-rewrite/constants/routes"; -import store from "@/store"; - -export async function errorBeforeEnter(to, from) { - // If we've already encountered one error, clear session to avoid more. - // Otherwise mark that we encoutnered an error here. - if (store.getters.applicationUser.hasAlreadyTriggeredError) { - return { - name: routeData.RESTART.name, - replace: true, - }; - } else { - await store.dispatch(storeActions.UPDATE_HAS_TRIGGERED_ERROR, true); - } - - // Add error event to bus - eventBus.addEventToBus( - globalEvents.Categories.GLOBAL_ALERT, - globalEvents.SubCategories.UNKNOWN_ERROR, - { - isDismissable: true, - messageCopy: "", - messageHeadline: "We're sorry, something went wrong.", - type: globalEventTypes.Danger, - } - ); - - let nextPage = FUNNEL_START_PAGE.name; - - baseMixin.methods?.ResetExternalParamsAndHideModal(); - - if (store.getters.payment?.insuranceCoverage?.isVerified) { - nextPage = routeData.VEHICLE_DAMAGE.name; - } - - if (from.name === nextPage) { - // Router won't load the page if we redirect to the already existing page - // Force refresh in this scenario. - router.go(0); - return false; - } - - return { - name: nextPage, - replace: false, - }; -} diff --git a/src/router/a-rewrite/methods/route-logic/heritage.js b/src/router/a-rewrite/methods/route-logic/heritage.js deleted file mode 100644 index d1a4c41c4..000000000 --- a/src/router/a-rewrite/methods/route-logic/heritage.js +++ /dev/null @@ -1,5 +0,0 @@ -import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; - -export async function heritageBeforeEnter(to, from) { - await navigateToHeritageFunnel({ shouldSaveSession: false, pageNameToLog: to.name }); -} diff --git a/src/router/a-rewrite/methods/route-logic/insurance-company.js b/src/router/a-rewrite/methods/route-logic/insurance-company.js deleted file mode 100644 index 18d961854..000000000 --- a/src/router/a-rewrite/methods/route-logic/insurance-company.js +++ /dev/null @@ -1,11 +0,0 @@ -import { routeData } from "@/router/a-rewrite/constants/routes"; -import { isVerifiedInsurance } from "@/router/a-rewrite/methods/helpers/requires-verified-redirect"; - -export async function insuranceCompanyBeforeEnter(to, from) { - if (isVerifiedInsurance()) { - return { - name: routeData.HERITAGE.name, - replace: true, - }; - } -} diff --git a/src/router/a-rewrite/methods/route-logic/landing.js b/src/router/a-rewrite/methods/route-logic/landing.js deleted file mode 100644 index b71d7a9db..000000000 --- a/src/router/a-rewrite/methods/route-logic/landing.js +++ /dev/null @@ -1,38 +0,0 @@ -import router from "@/router/a-rewrite"; -import { routeData } from "@/router/a-rewrite/constants/routes"; -import { consumeReferralQuerystrings } from "@/router/a-rewrite/methods/helpers/consume-referral-info"; -import { initializeFromQueryStrings } from "@/router/a-rewrite/methods/helpers/initialize-from-querystrings"; -import { stashAllQueries } from "@/router/a-rewrite/methods/helpers/querystring-stash"; -import store from "@/store"; - -export async function landingBeforeEnter(to, from) { - await initializeFromQueryStrings(); - // Save querystrings to temporary stash so they can be referred to later. - stashAllQueries(to); - // Change referral info. For use in local testing for insurance crossover. - await consumeReferralQuerystrings(); - - // Check for fmgpage parameter - const fmgPage = to?.query?.fmgPage; - if (fmgPage && router.hasRoute(fmgPage)) { - return { - name: fmgPage, - replace: true, - }; - } - - // If a session is still in memory, go to return-user. - if (store.getters.vehicle?.year > 0) { - console.log(`trying to redirect!`); - return { - name: routeData.RETURN_USER.name, - replace: true, - }; - } - - // Otherwise, load session and auto-route - return { - name: routeData.LOAD_SESSION.name, - replace: true, - }; -} diff --git a/src/router/a-rewrite/methods/route-logic/load-session.js b/src/router/a-rewrite/methods/route-logic/load-session.js deleted file mode 100644 index c70eb28d6..000000000 --- a/src/router/a-rewrite/methods/route-logic/load-session.js +++ /dev/null @@ -1,11 +0,0 @@ -import { loadSessionIfPresent } from "@/helpers/heritage-integration/order-helper"; -import { routeData } from "@/router/a-rewrite/constants/routes"; - -export async function loadSessionBeforeEnter(to, from) { - const loadSessionResponse = await loadSessionIfPresent(false, to.name); - - return { - name: routeData.AUTO_ROUTE.name, - replace: true, - }; -} diff --git a/src/router/a-rewrite/methods/route-logic/quote.js b/src/router/a-rewrite/methods/route-logic/quote.js deleted file mode 100644 index 9771b9bbb..000000000 --- a/src/router/a-rewrite/methods/route-logic/quote.js +++ /dev/null @@ -1,20 +0,0 @@ -import { queryStrings } from "@/constants/query-strings"; -import { storeMutations } from "@/constants/store-mutations"; -import { routeData } from "@/router/a-rewrite/constants/routes"; -import { isVerifiedInsurance } from "@/router/a-rewrite/methods/helpers/requires-verified-redirect"; -import store from "@/store"; - -export async function quoteBeforeEnter(to, from) { - if (isVerifiedInsurance()) { - return { - name: routeData.HERITAGE.name, - replace: true, - }; - } - - const offerQuote = to.query?.[queryStrings.OFFER_QUOTE]; - - if (offerQuote === "true") { - store.commit(storeMutations.UPDATE_IS_INSURANCE, false); - } -} diff --git a/src/router/a-rewrite/methods/route-logic/restart.js b/src/router/a-rewrite/methods/route-logic/restart.js deleted file mode 100644 index 4589999e0..000000000 --- a/src/router/a-rewrite/methods/route-logic/restart.js +++ /dev/null @@ -1,22 +0,0 @@ -import { storeActions } from "@/constants/store-actions"; -import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper"; -import router from "@/router/a-rewrite"; -import { FUNNEL_START_PAGE } from "@/router/a-rewrite/constants/routes"; -import store from "@/store"; - -export async function restartBeforeEnter(to, from) { - await store.dispatch(storeActions.RESET_STATE); - deleteFunnelCookie(); - - if (from.name === FUNNEL_START_PAGE.name) { - // Router won't load the page if we redirect to the already existing page - // Force refresh in this scenario. - router.go(0); - return false; - } - - return { - name: FUNNEL_START_PAGE.name, - replace: true, - }; -} diff --git a/src/router/a-rewrite/methods/route-logic/vehicle.js b/src/router/a-rewrite/methods/route-logic/vehicle.js deleted file mode 100644 index ed241d7de..000000000 --- a/src/router/a-rewrite/methods/route-logic/vehicle.js +++ /dev/null @@ -1,21 +0,0 @@ -import { storeMutations } from "@/constants/store-mutations"; -import { getBoolFromString } from "@/helpers/boolean-helper"; -import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper"; -import { routeData } from "@/router/a-rewrite/constants/routes"; -import { isVerifiedInsurance } from "@/router/a-rewrite/methods/helpers/requires-verified-redirect"; -import store from "@/store"; - -export async function vehicleBeforeEnter(to, from) { - // If cookie indicates that vehicle has changed during insurance flow, reset parts info. - const hasVehicleChanged = getBoolFromString(getFunnelCookie()?.HasDelayedClaimRegistration); - if (hasVehicleChanged) { - store.commit(storeMutations.RESET_GLASS_PARTS_STATE); - } - - if (isVerifiedInsurance()) { - return { - name: routeData.VEHICLE_DAMAGE.name, - replace: true, - }; - } -} diff --git a/src/router/a-rewrite/methods/routes.js b/src/router/a-rewrite/methods/routes.js deleted file mode 100644 index 5cbc8e94e..000000000 --- a/src/router/a-rewrite/methods/routes.js +++ /dev/null @@ -1,46 +0,0 @@ -import { createRoute, createVirtualRoute } from "@/router/a-rewrite/methods/helpers/create-route"; -import { routeData } from "@/router/a-rewrite/constants/routes"; - -import { vehicleBeforeEnter } from "@/router/a-rewrite/methods/route-logic/vehicle"; -import { quoteBeforeEnter } from "@/router/a-rewrite/methods/route-logic/quote"; -import { insuranceCompanyBeforeEnter } from "@/router/a-rewrite/methods/route-logic/insurance-company"; -import { landingBeforeEnter } from "@/router/a-rewrite/methods/route-logic/landing"; -import { heritageBeforeEnter } from "@/router/a-rewrite/methods/route-logic/heritage"; -import { loadSessionBeforeEnter } from "@/router/a-rewrite/methods/route-logic/load-session"; -import { autoRouteBeforeEnter } from "@/router/a-rewrite/methods/route-logic/auto-route"; -import { errorBeforeEnter } from "@/router/a-rewrite/methods/route-logic/error"; -import { restartBeforeEnter } from "@/router/a-rewrite/methods/route-logic/restart"; - -export const routes = [ - // Non-virtual pages. - createRoute(routeData.VEHICLE, vehicleBeforeEnter), - createRoute(routeData.VEHICLE_DAMAGE), - createRoute(routeData.ESTIMATE), - createRoute(routeData.ADDRESS_LOOKUP), - createRoute(routeData.VIN_LOOKUP), - createRoute(routeData.LICENSE_PLATE_LOOKUP), - createRoute(routeData.SERVICE_ZIP), - createRoute(routeData.ADDRESS_VEHICLES), - createRoute(routeData.VEHICLE_PARTS), - createRoute(routeData.PART_QUESTIONS), - createRoute(routeData.MOLDING_QUESTIONS), - createRoute(routeData.CAPABILITY_QUESTIONS), - createRoute(routeData.QUOTE, quoteBeforeEnter), - createRoute(routeData.INSURANCE_COMPANY, insuranceCompanyBeforeEnter), - createRoute(routeData.SERVICE_LOCATION), - createRoute(routeData.SCHEDULE), - createRoute(routeData.CUSTOMER_DETAILS), - createRoute(routeData.PAYMENT_METHOD), - createRoute(routeData.PAYMENT), - createRoute(routeData.PAYMENT_PIA_RETURN), - createRoute(routeData.CONFIRMATION), - createRoute(routeData.RETURN_USER), - - // Virtual pages (resolve to a non-virtual page.) - createVirtualRoute(routeData.LANDING, landingBeforeEnter), - createVirtualRoute(routeData.HERITAGE, heritageBeforeEnter), - createVirtualRoute(routeData.LOAD_SESSION, loadSessionBeforeEnter), - createVirtualRoute(routeData.AUTO_ROUTE, autoRouteBeforeEnter), - createVirtualRoute(routeData.ERROR, errorBeforeEnter), - createVirtualRoute(routeData.RESTART, restartBeforeEnter), -];