import { createRouter, createWebHashHistory, Router } from 'vue-router' import type { RouteRecordRaw } from 'vue-router' // Lazy-loaded route components const LoginPage = () => import('@/components/LoginPage.vue') const RecipesPage = () => import('@/components/recipes/RecipesPage.vue') const MealPlanPage = () => import('@/components/meals/MealPlanPage.vue') const MyShoppingPage = () => import('@/components/shopping/MyShoppingPage.vue') const PurchasedShoppingListPage = () => import('@/components/shopping/PurchasedShoppingListPage.vue') const CurrentShoppingListPage = () => import('@/components/shopping/CurrentShoppingListPage.vue') const EditMealPage = () => import('@/components/meals/EditMealPage.vue') const EditRecipePage = () => import('@/components/recipes/EditRecipePage.vue') const CreateAccount = () => import('@/views/CreateAccount.vue') const Welcome = () => import('@/views/Welcome.vue') const InvitationAccept = () => import('@/views/InvitationAccept.vue') export function createAppRouter(getCurrentUser: () => Promise | unknown): Router { const multitenantEnabled = typeof process !== 'undefined' && process.env?.VUE_APP_MULTITENANT_ENABLED === 'true' const publicRoutes: RouteRecordRaw[] = [ { path: '/login', name: 'login', component: LoginPage }, { path: '/create-account', name: 'create-account', component: CreateAccount }, { path: '/welcome', name: 'welcome', component: Welcome }, { path: '/invitations/accept', name: 'invitation-accept', component: InvitationAccept }, ] const featureChildren: RouteRecordRaw[] = [ { path: 'recipes', name: 'recipes', component: RecipesPage, meta: { requiresAuth: true } }, { path: 'recipes/add', name: 'recipe-add', component: EditRecipePage, meta: { requiresAuth: true } }, { path: 'recipes/:id', name: 'recipe-edit', component: EditRecipePage, props: true, meta: { requiresAuth: true } }, { path: 'mealplan', name: 'mealplan', component: MealPlanPage, meta: { requiresAuth: true } }, { path: 'meals/add', name: 'meal-add', component: EditMealPage, meta: { requiresAuth: true } }, { path: 'meals/:id', name: 'meal-edit', component: EditMealPage, props: true, meta: { requiresAuth: true } }, { path: 'shopping', name: 'shopping', component: MyShoppingPage, meta: { requiresAuth: true } }, { path: 'shopping/current', name: 'shopping-current', component: CurrentShoppingListPage, meta: { requiresAuth: true } }, { path: 'shopping/:id', name: 'shopping-list', component: PurchasedShoppingListPage, props: true, meta: { requiresAuth: true } }, ] const routes: RouteRecordRaw[] = [] if (multitenantEnabled) { routes.push({ path: '/', redirect: { name: 'login' } }) routes.push(...publicRoutes) routes.push({ path: '/:householdSlug', component: { template: '' }, children: featureChildren }) } else { routes.push({ path: '/', redirect: { name: 'mealplan' } }) routes.push(...publicRoutes) // legacy flat routes routes.push( { path: '/recipes', name: 'recipes', component: RecipesPage, meta: { requiresAuth: true } }, { path: '/recipes/add', name: 'recipe-add', component: EditRecipePage, meta: { requiresAuth: true } }, { path: '/recipes/:id', name: 'recipe-edit', component: EditRecipePage, props: true, meta: { requiresAuth: true } }, { path: '/mealplan', name: 'mealplan', component: MealPlanPage, meta: { requiresAuth: true } }, { path: '/meals/add', name: 'meal-add', component: EditMealPage, meta: { requiresAuth: true } }, { path: '/meals/:id', name: 'meal-edit', component: EditMealPage, props: true, meta: { requiresAuth: true } }, { path: '/shopping', name: 'shopping', component: MyShoppingPage, meta: { requiresAuth: true } }, { path: '/shopping/current', name: 'shopping-current', component: CurrentShoppingListPage, meta: { requiresAuth: true } }, { path: '/shopping/:id', name: 'shopping-list', component: PurchasedShoppingListPage, props: true, meta: { requiresAuth: true } }, ) } const router = createRouter({ history: createWebHashHistory(), routes, }) router.beforeEach(async (to) => { if (!to.meta.requiresAuth) return true try { const user = await getCurrentUser() if (user) return true } catch (_) { /* ignore */ } return { name: 'login', query: { redirect: to.fullPath } } }) return router }