import { createRouter, createWebHistory } from 'vue-router' import Layout from '@/themes' import { hasAnyActiveRolePermission } from '@/core/utils/activeRolePermission' import { getRouteRequiredPermissions } from '@/core/utils/routePermission' import { authPublicRoutes, resolvePostAuthRoute } from '@/modules/auth' import { membershipApplicationPublicRoutes, membershipApplicationLayoutRoutes } from '@/modules/membership-application' import { profileLayoutRoutes, profilePublicRoutes } from '@/modules/profile' import { pinia } from '@/pinia' import { useAuthStore } from '@/stores/auth' import { userLayoutRoutes } from '@/modules/user' import { roleLayoutRoutes } from '@/modules/role' import { activityLayoutRoutes } from '@/modules/activity' import { dashboardLayoutRoutes } from '@/modules/dashboard' import { externalSystemLayoutRoutes } from '@/modules/external-system' import { activityLogLayoutRoutes } from '@/modules/activity-log' import { feedbackPublicRoutes, feedbackLayoutRoutes } from '@/modules/feedback' const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { // Main Layout path: '/', component: Layout, children: [ ...dashboardLayoutRoutes, ...profileLayoutRoutes, ...userLayoutRoutes, ...roleLayoutRoutes, ...activityLogLayoutRoutes, ...activityLayoutRoutes, ...externalSystemLayoutRoutes, ...membershipApplicationLayoutRoutes, ...feedbackLayoutRoutes, ], }, ...authPublicRoutes, ...membershipApplicationPublicRoutes, ...feedbackPublicRoutes, ...profilePublicRoutes, ], }) const PUBLIC_ROUTE_NAMES = new Set(['login', 'register', 'membership-application-apply', 'feedback-submit']) router.beforeEach(async (to) => { const authStore = useAuthStore(pinia) const routeName = String(to.name ?? '') // Hydrate session on public auth entry pages. if (PUBLIC_ROUTE_NAMES.has(routeName) && !authStore.isAuthenticated && !authStore.loading) { await authStore.fetchSession() } // Pending-approval page: authenticated pending users only. if (routeName === 'account-pending') { if (!authStore.isAuthenticated && !authStore.loading) { await authStore.fetchSession() } if (!authStore.isAuthenticated) { return { name: 'login' } } if (!authStore.isAccountPending) { return resolvePostAuthRoute(authStore.user) } return true } if ( authStore.isAuthenticated && PUBLIC_ROUTE_NAMES.has(routeName) && routeName !== 'membership-application-apply' && routeName !== 'feedback-submit' ) { return resolvePostAuthRoute(authStore.user) } // Public routes (auth pages, membership application, privacy, terms, etc.). if (to.meta?.public === true || to.meta?.module === 'auth' || PUBLIC_ROUTE_NAMES.has(routeName)) { return true } // Protected routes: require session. if (!authStore.isAuthenticated && !authStore.loading) { await authStore.fetchSession() } if (!authStore.isAuthenticated) { return { name: 'login', query: { redirect: to.fullPath }, } } if (authStore.isAccountPending) { return { name: 'account-pending' } } const requiredPermissions = getRouteRequiredPermissions(to) if ( requiredPermissions.length && !hasAnyActiveRolePermission( authStore.user, authStore.activeRole, requiredPermissions, ) ) { return { name: 'forbidden' } } return true }) export default router