import { createRouter, createWebHistory } from 'vue-router'; import type { UserRole } from '@mento/shared'; import { useAuthStore } from '@/stores/auth'; import { usePlatformAuthStore } from '@/stores/platform-auth'; export const router = createRouter({ history: createWebHistory(), routes: [ { path: '/login', name: 'login', component: () => import('@/views/LoginView.vue'), meta: { public: true }, }, { path: '/register', name: 'register', component: () => import('@/views/RegisterView.vue'), meta: { public: true }, }, { path: '/f/:token', name: 'public-lead-form', component: () => import('@/views/LeadFormPublicView.vue'), meta: { public: true }, }, { path: '/p/:slug', name: 'portal', component: () => import('@/views/PortalView.vue'), meta: { public: true }, }, { path: '/adm', name: 'adm-login', component: () => import('@/views/adm/AdmLoginView.vue'), meta: { public: true, platformPublic: true }, }, { path: '/adm', component: () => import('@/layouts/AdmLayout.vue'), meta: { public: true, platform: true }, children: [ { path: 'dashboard', name: 'adm-dashboard', component: () => import('@/views/adm/AdmDashboardView.vue'), }, { path: 'organizations', name: 'adm-organizations', component: () => import('@/views/adm/AdmOrganizationsView.vue'), }, { path: 'users', name: 'adm-users', component: () => import('@/views/adm/AdmUsersView.vue'), }, { path: 'admins', name: 'adm-admins', component: () => import('@/views/adm/AdmAdminsView.vue'), }, { path: 'sms', name: 'adm-sms', component: () => import('@/views/adm/AdmSmsView.vue'), }, ], }, { path: '/', component: () => import('@/layouts/AppLayout.vue'), children: [ { path: '', name: 'home', component: () => import('@/views/HomeView.vue'), }, { path: 'profile', name: 'profile', component: () => import('@/views/ProfileView.vue'), }, { path: 'reports', name: 'reports', component: () => import('@/views/ReportsView.vue'), }, { path: 'behavior/disc', name: 'disc-report', component: () => import('@/views/DiscReportView.vue'), }, { path: 'sales/forecast', name: 'sales-forecast', component: () => import('@/views/SalesForecastView.vue'), }, { path: 'tickets', name: 'tickets', component: () => import('@/views/TicketsView.vue'), }, { path: 'conversations', name: 'conversations', component: () => import('@/views/ConversationsView.vue'), }, { path: 'tickets/new', name: 'ticket-new', component: () => import('@/views/TicketFormView.vue'), }, { path: 'tickets/:id', name: 'ticket-detail', component: () => import('@/views/TicketFormView.vue'), }, { path: 'activities', name: 'activities', component: () => import('@/views/ActivitiesView.vue'), }, { path: 'activities/calendar', name: 'activities-calendar', component: () => import('@/views/ActivitiesCalendarView.vue'), }, { path: 'activities/new', name: 'activity-new', component: () => import('@/views/ActivityFormView.vue'), }, { path: 'activities/:id/edit', name: 'activity-edit', component: () => import('@/views/ActivityFormView.vue'), }, { path: 'activities/:id', name: 'activity-detail', component: () => import('@/views/ActivityDetailView.vue'), }, { path: 'routines', component: () => import('@/views/routines/RoutinesShellView.vue'), children: [ { path: '', name: 'routines-today', component: () => import('@/views/routines/RoutinesTodayView.vue'), }, { path: 'overdue', name: 'routines-overdue', component: () => import('@/views/routines/RoutinesOverdueView.vue'), }, { path: 'calendar', name: 'routines-calendar', component: () => import('@/views/routines/RoutinesCalendarView.vue'), }, { path: 'list', name: 'routines-list', component: () => import('@/views/routines/RoutinesListView.vue'), }, { path: 'me', name: 'routines-me', component: () => import('@/views/routines/RoutinesMyPerformanceView.vue'), }, { path: 'team', name: 'routines-team', component: () => import('@/views/routines/RoutinesTeamView.vue'), }, { path: 'manage', name: 'routines-manage', component: () => import('@/views/routines/RoutinesManageView.vue'), }, { path: 'manage/new', name: 'routine-new', component: () => import('@/views/routines/RoutineFormView.vue'), }, { path: 'manage/:id/edit', name: 'routine-edit', component: () => import('@/views/routines/RoutineFormView.vue'), }, { path: 'settings', name: 'routines-settings', component: () => import('@/views/routines/RoutinesSettingsView.vue'), }, ], }, { path: 'quotes', name: 'quotes', component: () => import('@/views/QuotesView.vue'), }, { path: 'quotes/new', name: 'quote-new', component: () => import('@/views/QuoteFormView.vue'), }, { path: 'quotes/:id', name: 'quote-detail', component: () => import('@/views/QuoteFormView.vue'), }, { path: 'invoices', name: 'invoices', component: () => import('@/views/InvoicesView.vue'), }, { path: 'invoices/new', name: 'invoice-new', component: () => import('@/views/InvoiceFormView.vue'), }, { path: 'invoices/:id', name: 'invoice-detail', component: () => import('@/views/InvoiceFormView.vue'), }, { path: 'inventory', name: 'inventory', component: () => import('@/views/InventoryView.vue'), }, { path: 'cheques', name: 'cheques', component: () => import('@/views/ChequesView.vue'), }, { path: 'finance', name: 'finance', component: () => import('@/views/treasury/TreasuryHomeView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'finance/accounts', name: 'finance-accounts', component: () => import('@/views/treasury/TreasuryAccountsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'finance/accounts/:id', name: 'finance-account', component: () => import('@/views/treasury/TreasuryAccountView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'finance/incomes', name: 'finance-incomes', component: () => import('@/views/treasury/TreasuryIncomesView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'finance/expenses', name: 'finance-expenses', component: () => import('@/views/treasury/TreasuryExpensesView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'finance/receivables', name: 'finance-receivables', component: () => import('@/views/treasury/TreasuryReceivablesView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'finance/payroll', name: 'finance-payroll', component: () => import('@/views/treasury/TreasuryPayrollView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'finance/recurring', name: 'finance-recurring', component: () => import('@/views/treasury/TreasuryRecurringView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'finance/reports', name: 'finance-reports', component: () => import('@/views/treasury/TreasuryReportsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'finance/audit', name: 'finance-audit', component: () => import('@/views/treasury/TreasuryAuditView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'finance/categories', name: 'finance-categories', component: () => import('@/views/treasury/TreasuryCategoriesView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'reservations', name: 'reservations', component: () => import('@/views/ReservationsView.vue'), }, { path: 'commissions', name: 'commissions', component: () => import('@/views/CommissionsView.vue'), }, { path: 'pipeline', name: 'pipeline', component: () => import('@/views/PipelineBoardView.vue'), }, { path: 'leads', name: 'leads', component: () => import('@/views/LeadsView.vue'), }, { path: 'leads/board', name: 'leads-board', component: () => import('@/views/LeadBoardView.vue'), }, { path: 'leads/:id', name: 'lead-detail', component: () => import('@/views/LeadDetailView.vue'), }, { path: 'projects', name: 'projects', component: () => import('@/views/ProjectBoardView.vue'), }, { path: 'project-cards/new', name: 'project-card-new', component: () => import('@/views/ProjectCardFormView.vue'), }, { path: 'project-cards/:id', name: 'project-card-detail', component: () => import('@/views/ProjectCardFormView.vue'), }, { path: 'loyalty', name: 'loyalty', component: () => import('@/views/LoyaltyClubView.vue'), }, { path: 'club', name: 'gamification', component: () => import('@/views/gamification/GamificationView.vue'), }, { path: 'club/admin', name: 'gamification-admin', component: () => import('@/views/gamification/GamificationAdminView.vue'), }, { path: 'deals/new', name: 'deal-new', component: () => import('@/views/DealFormView.vue'), }, { path: 'deals/:id', name: 'deal-detail', component: () => import('@/views/DealFormView.vue'), }, { path: 'contacts', name: 'contacts', component: () => import('@/views/ContactsView.vue'), }, { path: 'notes', name: 'notes', component: () => import('@/views/NotesView.vue'), }, { path: 'attachments', name: 'attachments', component: () => import('@/views/AttachmentsView.vue'), }, { path: 'settings/automations', name: 'automations', component: () => import('@/views/AutomationsSettingsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/message-automations', name: 'message-automations', component: () => import('@/views/MessageAutomationsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/lead-stages', name: 'lead-stages', component: () => import('@/views/LeadStagesSettingsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/pipelines', name: 'pipeline-settings', component: () => import('@/views/PipelineSettingsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[], module: 'pipeline' }, }, { path: 'settings/lead-forms', name: 'lead-forms', component: () => import('@/views/LeadFormsSettingsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/lead-forms/:id', name: 'lead-form-builder', component: () => import('@/views/LeadFormBuilderView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/team', name: 'team-settings', component: () => import('@/views/TeamSettingsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/audit-logs', name: 'audit-logs', component: () => import('@/views/AuditLogsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/deletions', name: 'deletion-archives', component: () => import('@/views/DeletionArchivesView.vue'), meta: { roles: ['owner'] as UserRole[] }, }, { path: 'settings/public-api', name: 'public-api', component: () => import('@/views/PublicApiSettingsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/sms-campaigns', name: 'sms-campaigns', component: () => import('@/views/SmsCampaignsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/sms-campaigns/:id/report', name: 'sms-campaign-report', component: () => import('@/views/SmsCampaignReportView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/custom-fields', name: 'custom-fields', component: () => import('@/views/CustomFieldsSettingsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/products', name: 'products', component: () => import('@/views/ProductsSettingsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/products/new', name: 'product-new', component: () => import('@/views/ProductFormView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/products/:id/edit', name: 'product-edit', component: () => import('@/views/ProductFormView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/currencies', name: 'currencies', component: () => import('@/views/CurrencySettingsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/tahesab', name: 'tahesab-settings', component: () => import('@/views/TahesabSettingsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/woocommerce', name: 'woocommerce-settings', component: () => import('@/views/WooCommerceSettingsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/montify', name: 'montify-settings', component: () => import('@/views/MontifySettingsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/voip', name: 'voip-settings', component: () => import('@/views/VoipSettingsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'settings/faq', name: 'faq-settings', component: () => import('@/views/FaqSettingsView.vue'), meta: { roles: ['owner', 'admin'] as UserRole[] }, }, { path: 'contacts/people/new', name: 'person-new', component: () => import('@/views/PersonFormView.vue'), }, { path: 'contacts/people/:id/edit', name: 'person-edit', component: () => import('@/views/PersonFormView.vue'), }, { path: 'contacts/people/:id', name: 'person-detail', component: () => import('@/views/PersonProfileView.vue'), }, { path: 'contacts/companies/new', name: 'company-new', component: () => import('@/views/CompanyFormView.vue'), }, { path: 'contacts/companies/:id', name: 'company-detail', component: () => import('@/views/CompanyFormView.vue'), }, ], }, ], }); router.beforeEach((to) => { if (to.path === '/adm' || to.path.startsWith('/adm/')) { const platform = usePlatformAuthStore(); if (to.meta.platformPublic) { if (platform.isAuthenticated) return { name: 'adm-dashboard' }; return true; } if (!platform.isAuthenticated) return { name: 'adm-login' }; return true; } const auth = useAuthStore(); if (!to.meta.public && !auth.isAuthenticated) { return { name: 'login', query: { redirect: to.fullPath } }; } if ( to.meta.public && auth.isAuthenticated && (to.name === 'login' || to.name === 'register') ) { return { name: 'home' }; } if (String(to.path).startsWith('/behavior')) { const modules = auth.user?.enabledModules; if (modules && !modules.includes('behavior')) return { name: 'home' }; } if (String(to.path).startsWith('/finance')) { const modules = auth.user?.enabledModules; if (modules && !modules.includes('treasury')) return { name: 'home' }; } const roles = to.meta.roles as UserRole[] | undefined; if (roles?.length) { const role = auth.user?.role as UserRole | undefined; if (role && roles.includes(role)) { return true; } if (to.name === 'team-settings' && auth.user?.viewAs?.canOpenTeamSettings) { return true; } if (String(to.path).startsWith('/finance')) { const perms = auth.user?.permissions ?? []; const payroll = to.path.startsWith('/finance/payroll'); if (payroll && perms.includes('treasury_payroll')) return true; if (!payroll && (perms.includes('treasury') || perms.includes('treasury_payroll'))) return true; } return { name: 'home' }; } return true; });