87a32b7ee8
Adds the unified file manager view (Windows Explorer-style), collapsible folder tree sidebar item, full vitest test suite (55 tests, 4 files), and commits all Phase 4 backend/frontend fixes that were staged but uncommitted. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
77 lines
2.3 KiB
JavaScript
77 lines
2.3 KiB
JavaScript
import { createRouter, createWebHistory } from 'vue-router'
|
|
import { useAuthStore } from '../stores/auth.js'
|
|
import FileManagerView from '../views/FileManagerView.vue'
|
|
import TopicsView from '../views/TopicsView.vue'
|
|
import DocumentView from '../views/DocumentView.vue'
|
|
import SettingsView from '../views/SettingsView.vue'
|
|
|
|
const routes = [
|
|
// File manager is the home — handles both root and folder views
|
|
{ path: '/', component: FileManagerView },
|
|
{ path: '/topics', component: TopicsView },
|
|
{ path: '/topics/:name', component: TopicsView },
|
|
{ path: '/document/:id', component: DocumentView },
|
|
{ path: '/settings', component: SettingsView },
|
|
|
|
// Phase 2 — public auth routes (no guard)
|
|
{
|
|
path: '/login',
|
|
component: () => import('../views/auth/LoginView.vue'),
|
|
meta: { public: true },
|
|
},
|
|
{
|
|
path: '/register',
|
|
component: () => import('../views/auth/RegisterView.vue'),
|
|
meta: { public: true },
|
|
},
|
|
{
|
|
path: '/password-reset',
|
|
component: () => import('../views/auth/PasswordResetView.vue'),
|
|
meta: { public: true },
|
|
},
|
|
{
|
|
path: '/password-reset/confirm',
|
|
component: () => import('../views/auth/NewPasswordView.vue'),
|
|
meta: { public: true },
|
|
},
|
|
|
|
// Phase 2 — authenticated routes
|
|
{ path: '/account', component: () => import('../views/AccountView.vue') },
|
|
{ path: '/admin', component: () => import('../views/AdminView.vue') },
|
|
|
|
// Phase 4 — folder and sharing routes
|
|
{
|
|
path: '/folders/:folderId',
|
|
name: 'folder',
|
|
component: FileManagerView,
|
|
meta: { requiresAuth: true },
|
|
},
|
|
{
|
|
path: '/shared',
|
|
name: 'shared',
|
|
component: () => import('../views/SharedView.vue'),
|
|
meta: { requiresAuth: true },
|
|
},
|
|
]
|
|
|
|
const router = createRouter({
|
|
history: createWebHistory(),
|
|
routes,
|
|
})
|
|
|
|
// Navigation guard (D-10): redirect unauthenticated users to /login.
|
|
// On page reload the access token is gone (memory-only per CLAUDE.md), so we attempt
|
|
// a silent refresh via the httpOnly cookie before concluding the session is gone.
|
|
router.beforeEach(async (to) => {
|
|
const authStore = useAuthStore()
|
|
if (!to.meta.public && !authStore.accessToken) {
|
|
try {
|
|
await authStore.refresh()
|
|
} catch {
|
|
return { path: '/login', query: { redirect: to.fullPath } }
|
|
}
|
|
}
|
|
})
|
|
|
|
export default router
|