53c3a8eba7
modified: serv_nginx/bbvue/src/router/index.js set notification
187 lines
5.1 KiB
JavaScript
187 lines
5.1 KiB
JavaScript
import { createRouter, createWebHistory } from 'vue-router'
|
|
import Home from '../views/Home.vue'
|
|
import { useAuthStore } from '../stores/auth'
|
|
|
|
const router = createRouter({
|
|
history: createWebHistory(import.meta.env.BASE_URL),
|
|
routes: [
|
|
{
|
|
path: '/',
|
|
name: 'Home',
|
|
component: Home
|
|
},
|
|
{
|
|
path: '/about',
|
|
name: 'About',
|
|
component: () => import('../views/About.vue')
|
|
},
|
|
{
|
|
path: '/achievements',
|
|
name: 'Achievements',
|
|
component: () => import('../views/Achievements.vue')
|
|
},
|
|
{
|
|
path: '/gallery',
|
|
name: 'Gallery',
|
|
component: () => import('../views/Gallery.vue')
|
|
},
|
|
{
|
|
path: '/training',
|
|
name: 'Training',
|
|
component: () => import('../views/Training.vue')
|
|
},
|
|
{
|
|
path: '/news',
|
|
name: 'News',
|
|
component: () => import('../views/News.vue')
|
|
},
|
|
{
|
|
path: '/members',
|
|
name: 'Members',
|
|
component: () => import('../views/Members.vue')
|
|
},
|
|
{
|
|
path: '/reviews',
|
|
name: 'Reviews',
|
|
component: () => import('../views/Reviews.vue')
|
|
},
|
|
{
|
|
path: '/login',
|
|
name: 'Login',
|
|
component: () => import('../views/Login.vue'),
|
|
meta: { guestOnly: true }
|
|
},
|
|
{
|
|
path: '/profile',
|
|
name: 'Profile',
|
|
component: () => import('../views/Profile.vue'),
|
|
meta: { requiresAuth: true }
|
|
},
|
|
{
|
|
path: '/register',
|
|
name: 'Register',
|
|
component: () => import('../views/Register.vue'),
|
|
meta: { guestOnly: true }
|
|
},
|
|
{
|
|
path: '/profile/edit',
|
|
name: 'ProfileEdit',
|
|
component: () => import('../views/ProfileEdit.vue'),
|
|
meta: { requiresAuth: true }
|
|
},
|
|
{
|
|
path: '/terms',
|
|
name: 'TermsOfService',
|
|
component: () => import('../views/TermsOfService.vue')
|
|
},
|
|
{
|
|
path: '/privacy',
|
|
name: 'PrivacyPolicy',
|
|
component: () => import('../views/PrivacyPolicy.vue')
|
|
},
|
|
// Добавляем маршрут для выхода
|
|
{
|
|
path: '/logout',
|
|
name: 'Logout',
|
|
component: () => import('../views/Logout.vue')
|
|
}
|
|
]
|
|
})
|
|
|
|
// Функция для показа уведомлений
|
|
function showNotification(message) {
|
|
// Создаем элемент уведомления
|
|
const notification = document.createElement('div')
|
|
notification.style.cssText = `
|
|
position: fixed;
|
|
top: 50px;
|
|
right: 20px;
|
|
bottom: auto; /* Для предотвращения конфликта с другими фиксированными элементами */
|
|
left: auto;
|
|
|
|
/* Кросс-браузерное позиционирование */
|
|
transform: translate(0, 0);
|
|
|
|
background: rgba(46, 139, 86, 0.04); /* Основной фон */
|
|
background-color: #fff3e048; /* Fallback для браузеров без поддержки rgba */
|
|
|
|
/* Поддержка размытия */
|
|
-webkit-backdrop-filter: blur(10px);
|
|
backdrop-filter: blur(10px);
|
|
|
|
/* Fallback для старых браузеров */
|
|
-webkit-box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
|
|
color: white;
|
|
color: #333; /* Fallback для темных фонов */
|
|
|
|
padding: 15px 20px;
|
|
border-radius: 8px;
|
|
z-index: 10000;
|
|
|
|
/* Адаптивная ширина */
|
|
max-width: 300px;
|
|
width: 90vw;
|
|
min-width: 200px;
|
|
|
|
/* Анимация появления */
|
|
opacity: 1;
|
|
transition: all 0.3s ease;
|
|
`;
|
|
|
|
|
|
|
|
notification.textContent = message
|
|
|
|
document.body.appendChild(notification)
|
|
|
|
// Автоматически удаляем через 3 секунды
|
|
setTimeout(() => {
|
|
if (notification.parentNode) {
|
|
notification.parentNode.removeChild(notification)
|
|
}
|
|
}, 3000)
|
|
}
|
|
|
|
router.beforeEach(async (to, from, next) => {
|
|
const authStore = useAuthStore()
|
|
|
|
// Проверяем, требует ли маршрут аутентификации
|
|
if (to.meta.requiresAuth && !authStore.isAuthenticated) {
|
|
// Если есть токен, пробуем загрузить профиль
|
|
if (authStore.token) {
|
|
try {
|
|
await authStore.fetchProfile()
|
|
next()
|
|
return
|
|
} catch (error) {
|
|
console.log('Token validation failed:', error)
|
|
// Если токен невалидный, очищаем его и редиректим на логин
|
|
authStore.clearAuth()
|
|
next('/login')
|
|
return
|
|
}
|
|
} else {
|
|
// Если нет токена, редиректим на логин
|
|
next('/login')
|
|
return
|
|
}
|
|
}
|
|
|
|
// Проверяем, предназначен ли маршрут только для гостей
|
|
if (to.meta.guestOnly && authStore.isAuthenticated) {
|
|
showNotification("Вы уже авторизованы. Перенаправляем в профиль...")
|
|
|
|
// Ждем немного чтобы пользователь увидел уведомление, затем редиректим
|
|
setTimeout(() => {
|
|
next('/profile')
|
|
}, 2000)
|
|
return
|
|
}
|
|
|
|
// Если все проверки пройдены, разрешаем навигацию
|
|
next()
|
|
})
|
|
|
|
export default router |