import { createRouter, createWebHistory } from 'vue-router'; import moduleRoutes from './module.routes'; import portfolioRoutes from './portfolio.routes'; import onboardingRoutes from './onboarding.routes'; import meRoutes from './me.routes'; import authRoutes from './auth.routes'; import roomRoutes from './room.routes'; import { store } from '@/store'; import { LAYOUT_SIMPLE } from '@/router/core.constants'; import { EMAIL_NOT_VERIFIED_STATE, NO_VALID_LICENSE_STATE, SUCCESS_STATE } from './oauth.names'; import start from '@/pages/start.vue'; import { PAGE_LOAD_TIMEOUT } from '@/consts/navigation.consts'; import { matomoTrackPageView } from '@/helpers/matomo-client'; const instrument = () => import('@/pages/instrument.vue'); const instrumentOverview = () => import('@/pages/instrumentOverview.vue'); const article = () => import('@/pages/article.vue'); const news = () => import('@/pages/news.vue'); const surveyPage = () => import('@/pages/survey.vue'); const styleGuidePage = () => import('@/pages/styleguide.vue'); const joinClass = () => import('@/pages/joinClass.vue'); const topic = () => import('@/pages/topic-page.vue'); const p404 = () => import('@/pages/p404.vue'); const submission = () => import('@/pages/studentSubmission.vue'); const postLoginRedirectUrlKey = 'postLoginRedirectionUrl'; const notFoundRoute = { component: p404, meta: { layout: 'blank', matomoUrl: '/not-found', }, }; const routes = [ { path: '/', name: 'home', component: start, meta: { matomoUrl: '/' }, }, ...moduleRoutes, ...authRoutes, ...roomRoutes, ...onboardingRoutes, ...portfolioRoutes, ...meRoutes, { path: '/article/:slug', name: 'article', component: article, meta: { layout: LAYOUT_SIMPLE } }, { path: '/instruments/', name: 'instrument-overview', component: instrumentOverview, meta: { matomoUrl: '/instrument/' }, }, { path: '/instrument/:slug', name: 'instrument', component: instrument, meta: { layout: LAYOUT_SIMPLE, matomoUrlCallback: (to) => `/instrument/${to.params.slug}` }, }, { path: '/submission/:id', name: 'submission', component: submission, meta: { layout: LAYOUT_SIMPLE } }, { path: '/topic/:topicSlug', name: 'topic', component: topic, alias: '/book/topic/:topicSlug', meta: { matomoUrlCallback: (to) => `/topic/${to.params.topicSlug}/` }, }, { path: '/join-class', name: 'join-class', component: joinClass, meta: { layout: LAYOUT_SIMPLE, matomoUrl: '/join-class' }, }, { path: '/survey/:id', component: surveyPage, name: 'survey', props: true, meta: { layout: LAYOUT_SIMPLE }, }, { path: '/news', component: news, name: 'news', meta: { matomoUrl: '/news' }, }, { path: '/oauth-redirect', redirect: (to) => { switch (to.query.state) { case EMAIL_NOT_VERIFIED_STATE: return '/verify-email'; case NO_VALID_LICENSE_STATE: return '/license-activation'; case SUCCESS_STATE: if (window.localStorage && localStorage.getItem(postLoginRedirectUrlKey)) { const redirectUrl = localStorage.getItem(postLoginRedirectUrlKey); localStorage.removeItem(postLoginRedirectUrlKey); return redirectUrl; } return '/'; default: return '/unknown-auth-error'; } }, }, { path: '/styleguide', component: styleGuidePage }, { path: '/not-found', name: 'not-found', ...notFoundRoute, }, { path: '/:pathMatch(.*)*', ...notFoundRoute, }, ]; const router = createRouter({ routes, history: createWebHistory(), mode: 'history', scrollBehavior(to, from, savedPosition) { if (savedPosition) { return new Promise((resolve) => { setTimeout(() => { resolve(savedPosition); }, PAGE_LOAD_TIMEOUT); }); } return { left: 0, top: 0 }; }, }); router.afterEach(() => { store.commit('setEditModule', false); store.dispatch('showMobileNavigation', false); }); router.afterEach((to) => { if (to.meta.matomoUrl) { matomoTrackPageView(to.meta.matomoUrl); } if (to.meta.matomoUrlCallback) { matomoTrackPageView(to.meta.matomoUrlCallback(to)); } }); export { router, postLoginRedirectUrlKey };