/** * Routes de l'app. AppLayout englobe toutes les pages "public" (sidebar visible). * /admin/login a son propre layout vide (pas de sidebar tant qu'on n'est pas loggé). */ import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router' import AppLayout from '@/layouts/AppLayout.vue' import { getAdminToken } from '@/api/client' /** * Guard pour les routes /admin/* (hors /admin/login). Si pas de token Bearer * en localStorage, redirige vers /admin/login (en mémorisant la destination * via query.next pour qu'on y retourne après auth). */ function requireAdmin(to: { fullPath: string }) { if (!getAdminToken()) { return { name: 'admin-login', query: { next: to.fullPath } } } return true } const routes: RouteRecordRaw[] = [ { path: '/', component: AppLayout, children: [ { path: '', name: 'home', component: () => import('@/pages/HomePage.vue') }, { path: 'dashboard', name: 'dashboard', component: () => import('@/pages/DashboardPage.vue') }, { path: 'donut', name: 'donut', component: () => import('@/pages/DonutPage.vue') }, { path: 'projects', name: 'projects', component: () => import('@/pages/ProjectsPage.vue') }, { path: 'projects/new', name: 'project-new', component: () => import('@/pages/ProjectNewPage.vue') }, { path: 'projects/:slug', name: 'project-detail', component: () => import('@/pages/ProjectDetailPage.vue'), props: true }, { path: 'archives', name: 'archives', component: () => import('@/pages/ArchivesPage.vue') }, { path: 'categories', name: 'categories', component: () => import('@/pages/CategoriesPage.vue') }, // --- Admin dashboard (token Bearer requis pour toutes les sous-pages sauf /admin/login) --- { path: 'admin', name: 'admin-overview', component: () => import('@/pages/admin/AdminOverviewPage.vue'), beforeEnter: requireAdmin }, { path: 'admin/projects', name: 'admin-projects', component: () => import('@/pages/admin/AdminProjectsPage.vue'), beforeEnter: requireAdmin }, { path: 'admin/projects/:slug/edit', name: 'admin-project-edit', component: () => import('@/pages/admin/AdminProjectEditPage.vue'), props: true, beforeEnter: requireAdmin }, { path: 'admin/members', name: 'admin-members', component: () => import('@/pages/admin/AdminMembersPage.vue'), beforeEnter: requireAdmin }, { path: 'admin/members/:slug/edit', name: 'admin-member-edit', component: () => import('@/pages/admin/AdminMemberEditPage.vue'), props: true, beforeEnter: requireAdmin }, { path: 'admin/categories', name: 'admin-categories', component: () => import('@/pages/admin/AdminCategoriesPage.vue'), beforeEnter: requireAdmin }, { path: 'admin/categories/new', name: 'admin-category-new', component: () => import('@/pages/admin/AdminCategoryNewPage.vue'), beforeEnter: requireAdmin }, { path: 'admin/categories/:slug/edit', name: 'admin-category-edit', component: () => import('@/pages/admin/AdminCategoryEditPage.vue'), props: true, beforeEnter: requireAdmin }, { path: 'admin/login', name: 'admin-login', component: () => import('@/pages/AdminLoginPage.vue'), meta: { hideForAuthed: true } }, { path: ':pathMatch(.*)*', name: 'not-found', component: () => import('@/pages/NotFoundPage.vue') }, ], }, ] export const router = createRouter({ history: createWebHistory(), routes, scrollBehavior() { // Scroll en haut à chaque navigation (UX par défaut pour une SPA de contenu). return { top: 0 } }, })