init
This commit is contained in:
197
src/router/index.ts
Normal file
197
src/router/index.ts
Normal file
@@ -0,0 +1,197 @@
|
||||
// index.ts
|
||||
import {createRouter, createWebHistory, RouteRecordRaw} from 'vue-router'
|
||||
import {useToolbarStore} from '@/stores/toolbar-store'
|
||||
import {useSpaceStore} from '@/stores/spaceStore'
|
||||
import CategoryCreateUpdate from "@/components/settings/CategoryCreateUpdate.vue";
|
||||
import DashboardView from "@/components/dashboard/DashboardView.vue";
|
||||
import RecurrentyCreateUpdate from "@/components/settings/RecurrentyCreateUpdate.vue";
|
||||
import TransactionList from "@/components/transactions/TransactionList.vue";
|
||||
|
||||
// 📝 Расширяем тип меты роутов (типобезопасный toolbar, requiresAuth, guestOnly)
|
||||
declare module 'vue-router' {
|
||||
interface RouteMeta {
|
||||
requiresAuth?: boolean
|
||||
guestOnly?: boolean
|
||||
toolbar?: import('@/stores/toolbar-store').ToolbarConfig
|
||||
}
|
||||
}
|
||||
|
||||
// ⚙️ Ленивая загрузка компонентов (code-splitting)
|
||||
const SettingsList = () => import('@/components/settings/SettingsList.vue')
|
||||
const CategoriesList = () => import('@/components/settings/CategoriesList.vue')
|
||||
const RecurrentsList = () => import('@/components/settings/RecurrentsList.vue')
|
||||
const SpaceSettings = () => import('@/components/settings/SpaceSettings.vue')
|
||||
const NotificationSettings = () => import('@/components/settings/NotificationSettings.vue')
|
||||
|
||||
// Имена роутов для автокомплита и навигации
|
||||
export const enum RouteName {
|
||||
Dashboard = 'dashboard',
|
||||
TransactionList = 'transaction-list',
|
||||
SettingsList = 'settings-list',
|
||||
CategoriesList = 'categories-list',
|
||||
CategoryCreate = 'category-create',
|
||||
CategoryUpdate = 'category-update',
|
||||
RecurrentsList = 'recurrents-list',
|
||||
RecurrentCreate = 'recurrent-create',
|
||||
RecurrentUpdate = 'recurrent-update',
|
||||
SpaceSettings = 'space-settings',
|
||||
NotificationSettings = 'notification-settings',
|
||||
}
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{path: '/', name: RouteName.Dashboard, component: DashboardView, meta: {requiresAuth: true}},
|
||||
{path: '/transactions', name: RouteName.TransactionList, component: TransactionList, meta: {requiresAuth: true}},
|
||||
{path: '/settings', name: RouteName.SettingsList, component: SettingsList, meta: {requiresAuth: true}},
|
||||
{
|
||||
path: '/categories', name: RouteName.CategoriesList, component: CategoriesList, meta: {
|
||||
requiresAuth: true,
|
||||
toolbar: ({spaceStore}: { spaceStore: ReturnType<typeof useSpaceStore> }) => [
|
||||
{
|
||||
id: 'space',
|
||||
text: spaceStore.selectedSpaceName ?? 'Select Space',
|
||||
icon: '',
|
||||
onClickId: 'openSpacePicker',
|
||||
},
|
||||
{id: 'openCategoryCreation', text: '', icon: 'pi pi-plus', onClickId: 'openCategoryCreation'},
|
||||
],
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/categories/create', name: RouteName.CategoryCreate, component: CategoryCreateUpdate, meta: {
|
||||
requiresAuth: true,
|
||||
toolbar: ({spaceStore}: { spaceStore: ReturnType<typeof useSpaceStore> }) => [
|
||||
{
|
||||
id: 'space',
|
||||
text: spaceStore.selectedSpaceName ?? 'Select Space',
|
||||
icon: '',
|
||||
onClickId: 'openSpacePicker',
|
||||
},
|
||||
{id: 'createCategory', text: '', icon: 'pi pi-save', onClickId: 'createCategory'},
|
||||
],
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/categories/:id/edit', name: RouteName.CategoryUpdate, component: CategoryCreateUpdate, meta: {
|
||||
requiresAuth: true,
|
||||
toolbar: ({spaceStore}: { spaceStore: ReturnType<typeof useSpaceStore> }) => [
|
||||
{
|
||||
id: 'space',
|
||||
text: spaceStore.selectedSpaceName ?? 'Select Space',
|
||||
icon: '',
|
||||
onClickId: 'openSpacePicker',
|
||||
},
|
||||
{id: 'deleteCategory', text: '', icon: 'pi pi-trash', onClickId: 'deleteCategory'},
|
||||
{id: 'updateCategory', text: '', icon: 'pi pi-save', onClickId: 'updateCategory'},
|
||||
],
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: '/recurrents', name: RouteName.RecurrentsList, component: RecurrentsList, meta: {
|
||||
requiresAuth: true,
|
||||
toolbar: ({spaceStore}: { spaceStore: ReturnType<typeof useSpaceStore> }) => [
|
||||
{
|
||||
id: 'space',
|
||||
text: spaceStore.selectedSpaceName ?? 'Select Space',
|
||||
icon: 'pi pi-home',
|
||||
onClickId: 'openSpacePicker',
|
||||
},
|
||||
{id: 'openRecurrentCreation', text: '', icon: 'pi pi-plus', onClickId: 'openRecurrentCreation'},
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/recurrents/create', name: RouteName.RecurrentCreate, component: RecurrentyCreateUpdate, meta: {
|
||||
requiresAuth: true,
|
||||
toolbar: ({spaceStore}: { spaceStore: ReturnType<typeof useSpaceStore> }) => [
|
||||
{
|
||||
id: 'space',
|
||||
text: spaceStore.selectedSpaceName ?? 'Select Space',
|
||||
icon: '',
|
||||
onClickId: 'openSpacePicker',
|
||||
},
|
||||
{id: 'createRecurrent', text: '', icon: 'pi pi-save', onClickId: 'createCategory'},
|
||||
],
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/recurrents/:id/edit', name: RouteName.RecurrentUpdate, component: RecurrentyCreateUpdate, meta: {
|
||||
requiresAuth: true,
|
||||
toolbar: ({spaceStore}: { spaceStore: ReturnType<typeof useSpaceStore> }) => [
|
||||
{
|
||||
id: 'space',
|
||||
text: spaceStore.selectedSpaceName ?? 'Select Space',
|
||||
icon: '',
|
||||
onClickId: 'openSpacePicker',
|
||||
},
|
||||
{id: 'deleteRecurrent', text: '', icon: 'pi pi-trash', onClickId: 'deleteRecurrent'},
|
||||
{id: 'updateRecurrent', text: '', icon: 'pi pi-save', onClickId: 'updateRecurrent'},
|
||||
],
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/space-settings',
|
||||
name: RouteName.SpaceSettings,
|
||||
component: SpaceSettings,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
toolbar: ({spaceStore}: { spaceStore: ReturnType<typeof useSpaceStore> }) => [
|
||||
{
|
||||
id: 'space',
|
||||
text: spaceStore.selectedSpaceName ?? 'Select Space',
|
||||
icon: 'pi pi-home',
|
||||
onClickId: 'openSpacePicker',
|
||||
},
|
||||
{id: 'save', text: 'Save', icon: 'pi pi-check', onClickId: 'saveSettings'},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/notification-settings',
|
||||
name: RouteName.NotificationSettings,
|
||||
component: NotificationSettings,
|
||||
meta: {requiresAuth: true}
|
||||
},
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes,
|
||||
scrollBehavior() {
|
||||
return {top: 0, left: 0, behavior: 'auto'}
|
||||
},
|
||||
})
|
||||
|
||||
function isAuthed() {
|
||||
return !!localStorage.getItem('token')
|
||||
}
|
||||
|
||||
router.beforeEach((to, _from, next) => {
|
||||
const authed = isAuthed()
|
||||
|
||||
if (to.meta.requiresAuth && !authed) {
|
||||
const back = encodeURIComponent(to.fullPath)
|
||||
return next(`/login?back=${back}`)
|
||||
}
|
||||
|
||||
if (to.meta.guestOnly && authed) {
|
||||
return next({name: RouteName.SettingsList})
|
||||
}
|
||||
|
||||
return next()
|
||||
})
|
||||
|
||||
// 🔁 Авто-обновление тулбара при каждом переходе
|
||||
router.afterEach((to) => {
|
||||
const toolbar = useToolbarStore()
|
||||
const cfg = to.meta.toolbar
|
||||
|
||||
if (typeof cfg === 'function') {
|
||||
// даём конфигу доступ к сторам (расширяй при необходимости)
|
||||
toolbar.setByConfig(({...ctx}) => cfg({spaceStore: useSpaceStore(), ...ctx}))
|
||||
} else {
|
||||
toolbar.setByConfig(cfg)
|
||||
}
|
||||
})
|
||||
|
||||
export default router
|
||||
Reference in New Issue
Block a user