import { createWebHistory, createRouter } from "vue-router"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader"; import {issPageValues} from '@/router/router-constants/issPage-values'; import { routingTable } from "@/router/router-constants/routing-table"; import { useMainStore } from '@/store'; import eventBus from "@/helpers/event-bus/event-bus"; import { globalEvents, globalEventTypes } from "@/constants/events"; import analyticsMixin from "@/mixins/analytics-mixin"; const routes = [ { path: '/', name: 'root', async beforeEnter(to, from, next) { try { to.query.issPage = !to.query.issPage ? issPageValues.VEHICLE_YEAR : to.query.issPage; if (router.hasRoute(to.query.issPage)) { return next({ name: to.query.issPage, query: to.query, params: to.params }); } const routeData = await GetRouteInfoFromPageName(to.query.issPage); if(routeData[0].name.toLowerCase() === "error") { throw("Page not found!"); } // Add our dynamic route. router.addRoute({ path: routeData[0].path, // Always the same path, because we control it with query strings. name: routeData[0].name, component: routeData[0].component, }); // Assign current query string parameters, as well as our issPage one. next({ name: routeData[0].name, query: Object.assign(to.query, { issPage: routeData[0].name }), params: to.params }); } catch (error) { console.log(error); GoToStartOn404(next); } } }]; const router = createRouter({ history: createWebHistory("/"), routes, }); router.afterEach((to, from) => { const store = useMainStore(); // Update lastPageVisited in the store store.updateLastPageVisited(to.name); // Push page view to GA analyticsMixin.methods.pushPageViewToGA(); // Push experiments to Data Layer analyticsMixin.methods.pushExperimentsToDataLayer(); }); // Get route information by page name. // This will reach out to the Cms and there is a 1:1 relationship between page names and route names. async function GetRouteInfoFromPageName(pageName) { const response = await useMainStore().getRouteInfo(pageName); const jsonFromResponse = JSON.parse(response.data.Result); let routeData = []; // Add our route data and return our array. Object.keys(jsonFromResponse).forEach((key) => { routeData.push({ path: "/", name: `${key}`, component: lazyLoadComponent(jsonFromResponse[key].LayoutName), }); }); return routeData; }; router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}) => { navigate(scenario, currentRoute, false, optionalQuery, optionalParams); } // Navigate to the next route, depending on the scenario. function navigate (scenario, currentRoute, optionalQuery = {}, optionalParams = {}) { if (!scenario) { console.error("No scenario provided. Please review the routing table."); return; } // Match our maps up and navigate if we have a destination. const matchingScenarioMap = getNavigationMap(scenario, currentRoute); if (!matchingScenarioMap){ console.error("No matching scenario found. Please review the routing table."); return; } if (matchingScenarioMap.destinationIssPageValue) { // We're always pushing the same path, just changing query strings. Make sure our optional query strings get combined with our issPage one. router.push({ name: "root", query: Object.assign(optionalQuery, { issPage: matchingScenarioMap.destinationIssPageValue, }), params: optionalParams }); } else if (matchingScenarioMap.destinationUrl) { navigateToUrl(matchingScenarioMap.destinationUrl, optionalQuery); } }; // Navigate to an external url. function navigateToUrl(url, optionalQuery = {}) { // possibly show some loading screen in the future here. let externalUrl = new URL(url); for (const queryKey in optionalQuery) { externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]); } window.location.assign(externalUrl); }; // Get navigation map depending on the scenario and the current 'page' you're on. function getNavigationMap (scenario, currentRoute) { const issPageValue = currentRoute.query.issPage; try { const matchedQueryValue = routingTable(useMainStore()) .filter( (item) => item.issPageValue === issPageValue && item.maps.filter((map) => map.scenario === scenario).length > 0 ); let maps = matchedQueryValue ? matchedQueryValue.map((m) => m.maps.filter((map) => map.scenario === scenario))[0] : undefined; return maps ? maps.filter(x => x.filter === true || x.filter === undefined)[0] : undefined; } catch (e) { console.error(e); return undefined; } }; function GoToStartOn404(next) { const errorPageName = issPageValues.VEHICLE_YEAR; router.addRoute({ path: "/", name: errorPageName, component: lazyLoadComponent(errorPageName), }); // Put item on the bus eventBus.addEventToBus( globalEvents.Categories.GLOBAL_ALERT, globalEvents.SubCategories.PAGE_NOT_FOUND, { isDismissible: true, messageCopy: "You can get a quote by starting on this page.", messageHeadline: "We're sorry, something went wrong.", type: globalEventTypes.Danger, } ); next({ name: errorPageName, query: {issPage: errorPageName }, }); }; export default router;