cmms/frontend/src/router/index.js

457 lines
12 KiB
JavaScript

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