1
0
Files
TaskBoard/front_vue/src/router.js
Falknat 190b4d0a5e Большое обновление
1. Создание личных проектов
2. Управление командой
3. Приглашение участников
4. Уведомления

и многое другое...
2026-01-18 20:17:02 +07:00

160 lines
5.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { createRouter, createWebHistory } from 'vue-router'
import MainApp from './views/MainApp.vue'
import LoginPage from './views/LoginPage.vue'
import TeamPage from './views/TeamPage.vue'
import ArchivePage from './views/ArchivePage.vue'
import NoProjectsPage from './views/NoProjectsPage.vue'
import InvitesPage from './views/InvitesPage.vue'
import { authApi } from './api'
import { useProjectsStore } from './stores/projects'
// Кэш авторизации (чтобы не делать запрос при каждой навигации)
let authCache = {
isAuthenticated: null, // null = не проверяли, true/false = результат
user: null, // Данные пользователя
lastCheck: 0
}
// Время жизни кэша авторизации (5 минут)
const AUTH_CACHE_TTL = 5 * 60 * 1000
// Проверка авторизации (с кэшированием)
const checkAuth = async (forceCheck = false) => {
const now = Date.now()
// Используем кэш если он валиден и не форсируем проверку
if (!forceCheck && authCache.isAuthenticated !== null && (now - authCache.lastCheck) < AUTH_CACHE_TTL) {
return authCache.isAuthenticated
}
try {
const data = await authApi.check()
authCache.isAuthenticated = data.success === true
authCache.user = data.user || null
authCache.lastCheck = now
return authCache.isAuthenticated
} catch {
// При ошибке сети — используем кэш если есть, иначе false
if (authCache.isAuthenticated !== null) {
return authCache.isAuthenticated
}
return false
}
}
// Сброс кэша (вызывать при logout)
export const clearAuthCache = () => {
authCache = { isAuthenticated: null, user: null, lastCheck: 0 }
}
// Глобальный доступ для api.js (избегаем циклической зависимости)
window.__clearAuthCache = clearAuthCache
// Установка кэша (вызывать при успешном login)
export const setAuthCache = (isAuth, user = null) => {
authCache = { isAuthenticated: isAuth, user, lastCheck: Date.now() }
}
// Получить закэшированного пользователя
export const getCachedUser = () => authCache.user
const routes = [
{
path: '/',
name: 'main',
component: MainApp,
meta: { requiresAuth: true, requiresProject: true }
},
{
path: '/team',
name: 'team',
component: TeamPage,
meta: { requiresAuth: true, requiresProject: true }
},
{
path: '/archive',
name: 'archive',
component: ArchivePage,
meta: { requiresAuth: true, requiresProject: true }
},
{
path: '/no-projects',
name: 'no-projects',
component: NoProjectsPage,
meta: { requiresAuth: true }
},
{
path: '/invites',
name: 'invites',
component: InvitesPage,
meta: { requiresAuth: true }
},
{
path: '/login',
name: 'login',
component: LoginPage
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
// Navigation guard — проверка авторизации и наличия проектов
router.beforeEach(async (to, from, next) => {
// Если переходим между защищёнными страницами и кэш валиден — не проверяем сеть
const needsAuth = to.meta.requiresAuth
const needsProject = to.meta.requiresProject
const fromProtected = from.meta?.requiresAuth
// Форсируем проверку только при переходе на защищённую страницу извне
// или при переходе на /login (чтобы редиректнуть если уже авторизован)
const forceCheck = (needsAuth && !fromProtected) || to.path === '/login'
const isAuth = await checkAuth(forceCheck)
if (needsAuth && !isAuth) {
// Не авторизован — на логин
next('/login')
return
}
if (to.path === '/login' && isAuth) {
// Уже авторизован — на главную
next('/')
return
}
// Проверка наличия проектов для страниц, которые их требуют
if (needsProject && isAuth) {
const store = useProjectsStore()
// Инициализируем store если ещё не инициализирован
if (!store.initialized) {
await store.init()
}
// Нет проектов — на страницу /no-projects
if (store.projects.length === 0) {
next('/no-projects')
return
}
}
// Если на /no-projects но проекты есть — на главную
if (to.path === '/no-projects' && isAuth) {
const store = useProjectsStore()
if (!store.initialized) {
await store.init()
}
if (store.projects.length > 0) {
next('/')
return
}
}
next()
})
export default router