import { createRouter, createWebHistory } from 'vue-router' import { useAppStore } from '../stores/app' const router = createRouter({ history: createWebHistory(), routes: [ { path: '/', component: () => import('../views/OnboardingWrapper.vue'), meta: { public: true }, children: [ { path: '', component: () => import('../views/RootRedirect.vue'), }, { path: 'login', name: 'login', component: () => import('../views/Login.vue'), }, { path: 'onboarding/intro', name: 'onboarding-intro', component: () => import('../views/OnboardingIntro.vue'), }, { path: 'onboarding/options', name: 'onboarding-options', component: () => import('../views/OnboardingOptions.vue'), }, { path: 'onboarding/path', name: 'onboarding-path', component: () => import('../views/OnboardingPath.vue'), }, { path: 'onboarding/did', name: 'onboarding-did', component: () => import('../views/OnboardingDid.vue'), }, { path: 'onboarding/backup', name: 'onboarding-backup', component: () => import('../views/OnboardingBackup.vue'), }, { path: 'onboarding/verify', name: 'onboarding-verify', component: () => import('../views/OnboardingVerify.vue'), }, { path: 'onboarding/done', name: 'onboarding-done', component: () => import('../views/OnboardingDone.vue'), }, ], }, { path: '/dashboard', component: () => import('../views/Dashboard.vue'), children: [ { path: '', name: 'home', component: () => import('../views/Home.vue'), }, { path: 'apps', name: 'apps', component: () => import('../views/Apps.vue'), }, { path: 'apps/:id', name: 'app-details', component: () => import('../views/AppDetails.vue'), }, { path: 'marketplace', name: 'marketplace', component: () => import('../views/Marketplace.vue'), }, { path: 'marketplace/:id', name: 'marketplace-app-detail', component: () => import('../views/MarketplaceAppDetails.vue'), }, { path: 'cloud', name: 'cloud', component: () => import('../views/Cloud.vue'), }, { path: 'cloud/:folderId', name: 'cloud-folder', component: () => import('../views/CloudFolder.vue'), }, { path: 'server', name: 'server', component: () => import('../views/Server.vue'), }, { path: 'web5', name: 'web5', component: () => import('../views/Web5.vue'), }, { path: 'settings', name: 'settings', component: () => import('../views/Settings.vue'), }, // Containers removed: My Apps serves the same purpose. Redirect old links. { path: 'containers', redirect: () => ({ path: '/dashboard/apps' }), }, { path: 'containers/:id', redirect: (to) => ({ path: `/dashboard/apps/${to.params.id}` }), }, ], }, ], }) /** * Navigation Guard * Handles authentication and onboarding flow routing */ router.beforeEach(async (to, _from, next) => { const store = useAppStore() const isPublic = to.meta.public // Allow all public routes (login, onboarding) without auth check if (isPublic) { // If already authenticated and trying to access login, redirect to dashboard if (to.path === '/login' && store.isAuthenticated) { next('/dashboard') return } next() return } // Protected routes require authentication // Check session if not already authenticated if (!store.isAuthenticated) { const hasSession = await store.checkSession() if (hasSession) { next() return } // No valid session - redirect to login next('/login') return } // User is already authenticated (from localStorage on page load) // Make sure WebSocket is connected if (!store.isConnected && !store.isReconnecting) { console.log('[Router] User authenticated but WebSocket not connected, connecting...') store.connectWebSocket().catch((err) => { console.warn('[Router] WebSocket connection failed:', err) }) } // Authenticated user accessing protected route next() }) export default router