Files
tp/main_dc/BB/bbvue/src/router/index.js
T
valitovgaziz 1c774ce80c modified: main_dc/BB/bbvue/src/components/EventCard.vue
modified:   main_dc/BB/bbvue/src/router/index.js
	modified:   main_dc/BB/bbvue/src/stores/event.js
	modified:   main_dc/BB/bbvue/src/views/Events.vue
	modified:   main_dc/BB/bbvue/src/views/Profile.vue
add events page and event store and eventcard modal
2025-10-25 05:50:36 +05:00

227 lines
6.3 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: '/stats/detailed',
name: 'DetailedStats',
component: () => import('../views/DetailedStats.vue'),
meta: { requiresAuth: true }
},
{
path: '/stats/personal-bests',
name: 'PersonalBests',
component: () => import('../views/PersonalBests.vue'),
meta: { requiresAuth: true }
},
{
path: '/verify-email',
name: 'VerifyEmail',
component: () => import('../views/VerifayEmail.vue'),
meta: { guestOnly: true } // Только для неавторизованных
},
{
path: '/reset-password',
name: 'ResetPassword',
component: () => import('../views/PasswordReset.vue'),
meta: { guestOnly: true } // Только для неавторизованных
},
{
path: '/forgot-password',
name: 'ForgotPassword',
component: () => import('../views/ForgotPassword.vue'),
meta: { guestOnly: true }
},
{
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')
},
{
path: '/events',
name: 'Events',
component: () => import('../views/Events.vue')
},
{
path: '/events/:id',
name: 'EventDetails',
component: () => import('../views/DetailedStats.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