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: '', redirect: (_to) => { // Initial routing logic - determines first screen after splash const devMode = import.meta.env.VITE_DEV_MODE const seenOnboarding = localStorage.getItem('neode_onboarding_complete') === '1' // const isSetup = localStorage.getItem('neode_setup_complete') === '1' // Setup mode: go directly to login (original StartOS setup) if (devMode === 'setup') { return '/login' } // Onboarding mode: go to experimental onboarding flow if (devMode === 'onboarding') { return seenOnboarding ? '/login' : '/onboarding/intro' } // Existing user mode: go to login if (devMode === 'existing') { return '/login' } // Default: check if user has completed onboarding return seenOnboarding ? '/login' : '/onboarding/intro' }, }, { 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'), }, ], }, ], }) /** * 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 } // Authenticated user accessing protected route next() }) export default router