1. Создание личных проектов 2. Управление командой 3. Приглашение участников 4. Уведомления и многое другое...
160 lines
5.0 KiB
JavaScript
160 lines
5.0 KiB
JavaScript
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
|