import { createRouter, createWebHistory } from 'vue-router' import { useAuthStore } from '@/stores/auth' const routes = [ { path: '/', redirect: '/dashboard' }, { path: '/login', name: 'Login', component: () => import('@/views/auth/LoginView.vue'), meta: { requiresGuest: true } }, { path: '/register', name: 'Register', component: () => import('@/views/auth/RegisterView.vue'), meta: { requiresGuest: true } }, { path: '/forgot-password', name: 'ForgotPassword', component: () => import('@/views/auth/ForgotPasswordView.vue'), meta: { requiresGuest: true } }, { path: '/reset-password', name: 'ResetPassword', component: () => import('@/views/auth/ResetPasswordView.vue'), meta: { requiresGuest: true } }, { path: '/dashboard', name: 'Dashboard', component: () => import('@/views/dashboard/DashboardView.vue') // meta: { requiresAuth: true } }, { path: '/work-orders', name: 'WorkOrders', component: () => import('@/views/workorders/WorkOrdersView.vue'), // meta: { requiresAuth: true }, children: [ { path: '', name: 'WorkOrdersList', component: () => import('@/views/workorders/WorkOrdersListView.vue') }, { path: 'create', name: 'CreateWorkOrder', component: () => import('@/views/workorders/CreateWorkOrderView.vue') }, { path: ':id', name: 'WorkOrderDetail', component: () => import('@/views/workorders/WorkOrderDetailView.vue'), props: true }, { path: ':id/edit', name: 'EditWorkOrder', component: () => import('@/views/workorders/EditWorkOrderView.vue'), props: true }, { path: 'calendar', name: 'WorkOrdersCalendar', component: () => import('@/views/workorders/WorkOrdersCalendarView.vue') } ] }, { path: '/assets', name: 'Assets', component: () => import('@/views/assets/AssetsView.vue'), // meta: { requiresAuth: true }, // Removed for development access children: [ { path: '', name: 'AssetsList', component: () => import('@/views/assets/AssetsListView.vue') }, { path: 'create', name: 'CreateAsset', component: () => import('@/views/assets/CreateAssetView.vue') }, { path: ':id', name: 'AssetDetail', component: () => import('@/views/assets/AssetDetailView.vue'), props: true }, { path: ':id/edit', name: 'EditAsset', component: () => import('@/views/assets/EditAssetView.vue'), props: true } ] }, { path: '/locations', name: 'Locations', component: () => import('@/views/locations/LocationsView.vue'), // meta: { requiresAuth: true }, children: [ { path: '', name: 'LocationsList', component: () => import('@/views/locations/LocationsListView.vue') }, { path: ':id', name: 'LocationDetail', component: () => import('@/views/locations/LocationDetailView.vue'), props: true } ] }, { path: '/people', name: 'People', component: () => import('@/views/people/PeopleView.vue'), // meta: { requiresAuth: true, requiresPermission: 'PEOPLE_AND_TEAMS:VIEW' }, children: [ { path: '', name: 'PeopleList', component: () => import('@/views/people/PeopleListView.vue') }, { path: 'teams', name: 'TeamsList', component: () => import('@/views/people/TeamsListView.vue') } ] }, { path: '/inventory', name: 'Inventory', component: () => import('@/views/inventory/InventoryView.vue') // meta: { requiresAuth: true } }, { path: '/inventory/parts', name: 'Parts', component: () => import('@/views/inventory/PartsView.vue'), // meta: { requiresAuth: true }, children: [ { path: '', name: 'PartsList', component: () => import('@/views/inventory/PartsListView.vue') }, { path: ':id', name: 'PartDetail', component: () => import('@/views/inventory/PartDetailView.vue'), props: true } ] }, { path: '/inventory/stock-alerts', name: 'StockAlerts', component: () => import('@/views/inventory/StockAlertsView.vue') // meta: { requiresAuth: true } }, { path: '/inventory/transfers', name: 'InventoryTransfers', component: () => import('@/views/inventory/InventoryTransfersView.vue') // meta: { requiresAuth: true } }, { path: '/maintenance', name: 'Maintenance', component: () => import('@/views/maintenance/MaintenanceView.vue') // meta: { requiresAuth: true } }, { path: '/maintenance/preventive', name: 'PreventiveMaintenance', component: () => import('@/views/maintenance/PreventiveMaintenanceView.vue'), // meta: { requiresAuth: true }, children: [ { path: '', name: 'PreventiveMaintenanceList', component: () => import('@/views/maintenance/PreventiveMaintenanceListView.vue') }, { path: ':id', name: 'PreventiveMaintenanceDetail', component: () => import('@/views/maintenance/PreventiveMaintenanceDetailView.vue'), props: true } ] }, { path: '/reports', name: 'Reports', component: () => import('@/views/reports/ReportsView.vue') // meta: { requiresAuth: true } }, { path: '/categories', name: 'Categories', component: () => import('@/views/categories/CategoriesView.vue'), // meta: { requiresAuth: true }, children: [ { path: '', name: 'CategoriesIndex', component: () => import('@/views/categories/CategoriesIndexView.vue') }, { path: 'work-order-categories', name: 'WorkOrderCategories', component: () => import('@/views/categories/CategoriesListView.vue'), props: { categoryType: 'work-order-categories' } }, { path: 'asset-categories', name: 'AssetCategories', component: () => import('@/views/categories/CategoriesListView.vue'), props: { categoryType: 'asset-categories' } }, { path: 'part-categories', name: 'PartCategories', component: () => import('@/views/categories/CategoriesListView.vue'), props: { categoryType: 'part-categories' } }, { path: 'cost-categories', name: 'CostCategories', component: () => import('@/views/categories/CategoriesListView.vue'), props: { categoryType: 'cost-categories' } }, { path: 'meter-categories', name: 'MeterCategories', component: () => import('@/views/categories/CategoriesListView.vue'), props: { categoryType: 'meter-categories' } }, { path: 'purchase-order-categories', name: 'PurchaseOrderCategories', component: () => import('@/views/categories/CategoriesListView.vue'), props: { categoryType: 'purchase-order-categories' } } ] }, { path: '/vendors', name: 'Vendors', component: () => import('@/views/vendors/VendorsView.vue'), // meta: { requiresAuth: true }, children: [ { path: '', name: 'VendorsList', component: () => import('@/views/vendors/VendorsListView.vue') }, { path: ':id', name: 'VendorDetail', component: () => import('@/views/vendors/VendorDetailView.vue'), props: true } ] }, { path: '/requests', name: 'Requests', component: () => import('@/views/requests/RequestsView.vue'), // meta: { requiresAuth: true }, children: [ { path: '', name: 'RequestsList', component: () => import('@/views/requests/RequestsListView.vue') }, { path: ':id', name: 'RequestDetail', component: () => import('@/views/requests/RequestDetailView.vue'), props: true } ] }, { path: '/meters', name: 'Meters', component: () => import('@/views/meters/MetersView.vue'), // meta: { requiresAuth: true }, children: [ { path: '', name: 'MetersList', component: () => import('@/views/meters/MetersListView.vue') }, { path: ':id', name: 'MeterDetail', component: () => import('@/views/meters/MeterDetailView.vue'), props: true } ] }, { path: '/customers', name: 'Customers', component: () => import('@/views/customers/CustomersView.vue'), // meta: { requiresAuth: true }, children: [ { path: '', name: 'CustomersList', component: () => import('@/views/customers/CustomersListView.vue') }, { path: ':id', name: 'CustomerDetail', component: () => import('@/views/customers/CustomerDetailView.vue'), props: true } ] }, { path: '/contracts', name: 'Contracts', component: () => import('@/views/contracts/ContractsView.vue'), // meta: { requiresAuth: true }, children: [ { path: '', name: 'ContractsList', component: () => import('@/views/contracts/ContractsListView.vue') }, { path: ':id', name: 'ContractDetail', component: () => import('@/views/contracts/ContractDetailView.vue'), props: true } ] }, { path: '/settings', name: 'Settings', component: () => import('@/views/settings/SettingsView.vue') // meta: { requiresAuth: true, requiresRole: ['ADMIN', 'MANAGER'] } }, { path: '/profile', name: 'Profile', component: () => import('@/views/settings/ProfileView.vue') // meta: { requiresAuth: true } }, { path: '/demo', name: 'FrappeUIDemo', component: () => import('@/views/demo/FrappeUIDemo.vue') }, { path: '/simple-demo', name: 'SimpleDemo', component: () => import('@/views/demo/SimpleDemo.vue') }, { path: '/basic-test', name: 'BasicTest', component: () => import('@/views/demo/BasicTest.vue') }, { path: '/theme-test', name: 'ThemeTest', component: () => import('@/views/demo/ThemeTest.vue') }, { path: '/unauthorized', name: 'Unauthorized', component: () => import('@/views/UnauthorizedView.vue') }, { path: '/:pathMatch(.*)*', name: 'NotFound', component: () => import('@/views/NotFoundView.vue') } ] const router = createRouter({ history: createWebHistory(), routes }) router.beforeEach(async (to, from, next) => { const authStore = useAuthStore() if (to.meta.requiresAuth) { if (!authStore.isAuthenticated) { next('/login') return } if (!authStore.user) { try { await authStore.getCurrentUser() } catch (error) { console.error('Failed to get current user:', error) next('/login') return } } if (to.meta.requiresRole) { const userRole = authStore.userRole const allowedRoles = Array.isArray(to.meta.requiresRole) ? to.meta.requiresRole : [to.meta.requiresRole] if (!allowedRoles.includes(userRole)) { next('/unauthorized') return } } if (to.meta.requiresPermission) { const requiredPermissions = Array.isArray(to.meta.requiresPermission) ? to.meta.requiresPermission : [to.meta.requiresPermission] const hasPermission = requiredPermissions.every(permission => authStore.hasPermission(permission) ) if (!hasPermission) { next('/unauthorized') return } } } if (to.meta.requiresGuest && authStore.isAuthenticated) { next('/dashboard') return } next() }) export default router