add changed revileing header in ather pages begushiybashkir.ru site

This commit is contained in:
2025-10-18 23:56:59 +05:00
parent 53c3a8eba7
commit 3ade3b5a97
16 changed files with 392 additions and 88 deletions
+1
View File
@@ -120,6 +120,7 @@ body {
}
.header-container {
max-width: 1200px;
display: flex;
justify-content: space-between;
align-items: center;
@@ -167,6 +167,7 @@ export default {
padding: 0;
position: relative;
transition: transform 0.3s ease;
}
.burger-menu:hover {
@@ -181,7 +182,7 @@ export default {
display: block;
height: 3px;
width: 100%;
background-color: white;
background-color: rgb(0, 0, 0);
border-radius: 3px;
transition: all 0.3s ease;
transform-origin: center;
@@ -33,12 +33,16 @@ export default {
width: 30px;
height: 30px;
object-fit: contain;
border: 2px solid white;
}
.mobile-logo span {
font-weight: 600;
color: #2e8b57;
font-size: 0.9rem;
border: 2px solid black; /* Black border for the text */
padding: 2px 4px; /* Optional: Adds space inside the border */
border-radius: 4px; /* Optional: Rounded corners */
}
/* Скрыть на десктопе по умолчанию */
+29
View File
@@ -281,6 +281,23 @@
export default {
// eslint-disable-next-line vue/multi-word-component-names
name: 'About',
mounted() {
window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true })
window.addEventListener('click', this.handleFirstInteraction, { once: true })
window.addEventListener('touchstart', this.handleFirstInteraction, { once: true })
this.autoShowTimeout = setTimeout(() => {
if (!this.hasInteracted) {
this.showContent()
}
}, 3000)
},
beforeUnmount() {
// Убираем обработчики при размонтировании
window.removeEventListener('scroll', this.handleFirstInteraction)
window.removeEventListener('click', this.handleFirstInteraction)
window.removeEventListener('touchstart', this.handleFirstInteraction)
clearTimeout(this.autoShowTimeout)
},
metaInfo: {
title: 'О нас - Бегущий Башкир | Беговой клуб в Уфе',
meta: [
@@ -302,6 +319,18 @@ export default {
console.log(`${baseUrl}images/${path}`)
return `${baseUrl}images/${path}`
},
handleFirstInteraction() {
if (!this.hasInteracted) {
this.hasInteracted = true
this.showContent()
clearTimeout(this.autoShowTimeout)
}
},
showContent() {
this.isContentVisible = true
// Эмитим событие для показа хедера
this.$emit('show-header')
},
}
}
</script>
+42 -49
View File
@@ -27,36 +27,20 @@
<div class="container">
<div class="filters-container">
<div class="search-box">
<input
v-model="searchQuery"
type="text"
placeholder="🔍 Поиск по имени или дистанции..."
class="search-input"
>
<input v-model="searchQuery" type="text" placeholder="🔍 Поиск по имени или дистанции..."
class="search-input">
</div>
<div class="filter-buttons">
<button
v-for="filter in filters"
:key="filter.value"
:class="['filter-btn', { 'active': activeFilter === filter.value }]"
@click="setFilter(filter.value)"
>
<button v-for="filter in filters" :key="filter.value"
:class="['filter-btn', { 'active': activeFilter === filter.value }]" @click="setFilter(filter.value)">
{{ filter.label }}
</button>
</div>
<div class="view-toggle">
<button
:class="['view-btn', { 'active': viewMode === 'grid' }]"
@click="viewMode = 'grid'"
title="Сетка"
>
<button :class="['view-btn', { 'active': viewMode === 'grid' }]" @click="viewMode = 'grid'" title="Сетка">
</button>
<button
:class="['view-btn', { 'active': viewMode === 'list' }]"
@click="viewMode = 'list'"
title="Список"
>
<button :class="['view-btn', { 'active': viewMode === 'list' }]" @click="viewMode = 'list'" title="Список">
</button>
</div>
@@ -71,11 +55,7 @@
<div class="category-section">
<h2 class="category-title">🏆 Командные достижения</h2>
<div class="achievements-grid" :class="viewMode">
<div
v-for="achievement in teamAchievements"
:key="achievement.id"
class="achievement-card team-card"
>
<div v-for="achievement in teamAchievements" :key="achievement.id" class="achievement-card team-card">
<div class="achievement-icon">🏅</div>
<h3>{{ achievement.title }}</h3>
<p>{{ achievement.description }}</p>
@@ -88,19 +68,11 @@
</div>
<!-- Личные достижения по дистанциям -->
<div
v-for="category in filteredCategories"
:key="category.id"
class="category-section"
>
<div v-for="category in filteredCategories" :key="category.id" class="category-section">
<h2 class="category-title">{{ category.icon }} {{ category.title }}</h2>
<div class="achievements-grid" :class="viewMode">
<div
v-for="achievement in category.achievements"
:key="achievement.id"
class="achievement-card"
:class="getAchievementClass(achievement)"
>
<div v-for="achievement in category.achievements" :key="achievement.id" class="achievement-card"
:class="getAchievementClass(achievement)">
<div class="achievement-header">
<h3>{{ achievement.name }}</h3>
<span class="result">{{ achievement.result }}</span>
@@ -111,22 +83,13 @@
<p class="note" v-if="achievement.note">{{ achievement.note }}</p>
<div class="achievement-links" v-if="achievement.telegram">
<a
:href="achievement.telegram"
target="_blank"
class="telegram-link"
title="Написать в Telegram"
>
<a :href="achievement.telegram" target="_blank" class="telegram-link" title="Написать в Telegram">
📱 @{{ getTelegramUsername(achievement.telegram) }}
</a>
</div>
<div class="achievement-meta">
<span
v-if="achievement.pb"
class="badge pb-badge"
title="Личный рекорд"
>
<span v-if="achievement.pb" class="badge pb-badge" title="Личный рекорд">
PB
</span>
<span class="distance">{{ category.distance }}</span>
@@ -191,6 +154,23 @@
export default {
// eslint-disable-next-line vue/multi-word-component-names
name: 'Achievements',
mounted() {
window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true })
window.addEventListener('click', this.handleFirstInteraction, { once: true })
window.addEventListener('touchstart', this.handleFirstInteraction, { once: true })
this.autoShowTimeout = setTimeout(() => {
if (!this.hasInteracted) {
this.showContent()
}
}, 3000)
},
beforeUnmount() {
// Убираем обработчики при размонтировании
window.removeEventListener('scroll', this.handleFirstInteraction)
window.removeEventListener('click', this.handleFirstInteraction)
window.removeEventListener('touchstart', this.handleFirstInteraction)
clearTimeout(this.autoShowTimeout)
},
data() {
return {
searchQuery: '',
@@ -472,6 +452,18 @@ export default {
}
},
methods: {
handleFirstInteraction() {
if (!this.hasInteracted) {
this.hasInteracted = true
this.showContent()
clearTimeout(this.autoShowTimeout)
}
},
showContent() {
this.isContentVisible = true
// Эмитим событие для показа хедера
this.$emit('show-header')
},
setFilter(filter) {
this.activeFilter = filter
},
@@ -980,6 +972,7 @@ export default {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
+26 -1
View File
@@ -261,6 +261,18 @@ export default {
}
},
methods: {
handleFirstInteraction() {
if (!this.hasInteracted) {
this.hasInteracted = true
this.showContent()
clearTimeout(this.autoShowTimeout)
}
},
showContent() {
this.isContentVisible = true
// Эмитим событие для показа хедера
this.$emit('show-header')
},
getImageUrl(path) {
// В продакшене замените на правильный путь
const baseUrl = import.meta.env.BASE_URL
@@ -330,14 +342,27 @@ export default {
}
},
mounted() {
window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true })
window.addEventListener('click', this.handleFirstInteraction, { once: true })
window.addEventListener('touchstart', this.handleFirstInteraction, { once: true })
this.autoShowTimeout = setTimeout(() => {
if (!this.hasInteracted) {
this.showContent()
}
}, 3000)
this.startAutoSlide()
document.addEventListener('keydown', this.handleKeydown)
},
beforeUnmount() {
// Убираем обработчики при размонтировании
window.removeEventListener('scroll', this.handleFirstInteraction)
window.removeEventListener('click', this.handleFirstInteraction)
window.removeEventListener('touchstart', this.handleFirstInteraction)
clearTimeout(this.autoShowTimeout)
this.stopAutoSlide()
document.removeEventListener('keydown', this.handleKeydown)
document.body.style.overflow = ''
}
},
}
</script>
+1 -4
View File
@@ -324,10 +324,7 @@ export default {
font-size: 3rem;
font-weight: 800;
text-shadow:
-1px -1px 0 black,
1px -1px 0 black,
-1px 1px 0 black,
1px 1px 0 black;
2px 2px 4px #26302868;
line-height: 1.1;
margin-bottom: 0.5rem;
letter-spacing: 2px;
+27
View File
@@ -60,6 +60,18 @@ export default {
}
},
methods: {
handleFirstInteraction() {
if (!this.hasInteracted) {
this.hasInteracted = true
this.showContent()
clearTimeout(this.autoShowTimeout)
}
},
showContent() {
this.isContentVisible = true
// Эмитим событие для показа хедера
this.$emit('show-header')
},
async handleLogin() {
const result = await this.authStore.login(this.credentials)
@@ -99,12 +111,27 @@ export default {
}, 3000)
}
},
beforeUnmount() {
// Убираем обработчики при размонтировании
window.removeEventListener('scroll', this.handleFirstInteraction)
window.removeEventListener('click', this.handleFirstInteraction)
window.removeEventListener('touchstart', this.handleFirstInteraction)
clearTimeout(this.autoShowTimeout)
},
// Добавляем проверку при монтировании компонента
mounted() {
// Если пользователь уже авторизован, показываем уведомление
if (this.authStore.isAuthenticated) {
this.showAlreadyLoggedInNotification()
}
window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true })
window.addEventListener('click', this.handleFirstInteraction, { once: true })
window.addEventListener('touchstart', this.handleFirstInteraction, { once: true })
this.autoShowTimeout = setTimeout(() => {
if (!this.hasInteracted) {
this.showContent()
}
}, 3000)
},
showAlreadyLoggedInNotification() {
const notification = document.createElement('div')
+25
View File
@@ -482,6 +482,18 @@ export default {
}
},
methods: {
handleFirstInteraction() {
if (!this.hasInteracted) {
this.hasInteracted = true
this.showContent()
clearTimeout(this.autoShowTimeout)
}
},
showContent() {
this.isContentVisible = true
// Эмитим событие для показа хедера
this.$emit('show-header')
},
getExperienceLabel(experience) {
const labels = {
'beginner': 'Начинающий',
@@ -664,10 +676,23 @@ export default {
mounted() {
document.addEventListener('keydown', this.handleKeydown)
this.loadMembers()
window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true })
window.addEventListener('click', this.handleFirstInteraction, { once: true })
window.addEventListener('touchstart', this.handleFirstInteraction, { once: true })
this.autoShowTimeout = setTimeout(() => {
if (!this.hasInteracted) {
this.showContent()
}
}, 3000)
},
beforeUnmount() {
document.removeEventListener('keydown', this.handleKeydown)
document.body.style.overflow = ''
// Убираем обработчики при размонтировании
window.removeEventListener('scroll', this.handleFirstInteraction)
window.removeEventListener('click', this.handleFirstInteraction)
window.removeEventListener('touchstart', this.handleFirstInteraction)
clearTimeout(this.autoShowTimeout)
}
}
</script>
+26
View File
@@ -387,6 +387,20 @@ export default {
methods: {
...mapActions(useAuthStore, ['fetchProfile']),
handleFirstInteraction() {
if (!this.hasInteracted) {
this.hasInteracted = true
this.showContent()
clearTimeout(this.autoShowTimeout)
}
},
showContent() {
this.isContentVisible = true
// Эмитим событие для показа хедера
this.$emit('show-header')
},
// Валидация формы
validateForm() {
this.clearAllErrors()
@@ -708,10 +722,22 @@ export default {
await this.fetchProfile()
}
this.checkAuth()
window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true })
window.addEventListener('click', this.handleFirstInteraction, { once: true })
window.addEventListener('touchstart', this.handleFirstInteraction, { once: true })
this.autoShowTimeout = setTimeout(() => {
if (!this.hasInteracted) {
this.showContent()
}
}, 3000)
},
beforeUnmount() {
document.removeEventListener('keydown', this.handleKeydown)
document.body.style.overflow = ''
window.removeEventListener('scroll', this.handleFirstInteraction)
window.removeEventListener('click', this.handleFirstInteraction)
window.removeEventListener('touchstart', this.handleFirstInteraction)
clearTimeout(this.autoShowTimeout)
}
}
</script>
+41 -4
View File
@@ -14,7 +14,8 @@
<div class="document-content">
<section class="document-section">
<h2>1. Общие положения</h2>
<p>1.1. Настоящая Политика конфиденциальности регулирует порядок сбора, хранения и использования персональных данных пользователей бегового клуба "Бегущий Башкир".</p>
<p>1.1. Настоящая Политика конфиденциальности регулирует порядок сбора, хранения и использования персональных
данных пользователей бегового клуба "Бегущий Башкир".</p>
<p>1.2. Используя наш сайт и услуги, вы соглашаетесь с условиями настоящей Политики.</p>
</section>
@@ -42,7 +43,8 @@
<section class="document-section">
<h2>4. Защита данных</h2>
<p>4.1. Мы принимаем все необходимые меры для защиты ваших персональных данных от несанкционированного доступа.</p>
<p>4.1. Мы принимаем все необходимые меры для защиты ваших персональных данных от несанкционированного
доступа.</p>
<p>4.2. Данные хранятся на защищенных серверах и передаются в зашифрованном виде.</p>
</section>
@@ -77,7 +79,7 @@
<h2>8. Контакты</h2>
<p>По вопросам, связанным с обработкой персональных данных, обращайтесь:</p>
<p>📧 Email: privacy@begushiybashkir.ru<br>
📞 Телефон: +7 (XXX) XXX-XX-XX</p>
📞 Телефон: +7 (XXX) XXX-XX-XX</p>
</section>
</div>
@@ -96,12 +98,47 @@
<script>
export default {
name: 'PrivacyPolicy',
mounted() {
window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true })
window.addEventListener('click', this.handleFirstInteraction, { once: true })
window.addEventListener('touchstart', this.handleFirstInteraction, { once: true })
this.autoShowTimeout = setTimeout(() => {
if (!this.hasInteracted) {
this.showContent()
}
}, 3000)
},
beforeUnmount() {
// Убираем обработчики при размонтировании
window.removeEventListener('scroll', this.handleFirstInteraction)
window.removeEventListener('click', this.handleFirstInteraction)
window.removeEventListener('touchstart', this.handleFirstInteraction)
clearTimeout(this.autoShowTimeout)
},
data() {
return {
lastUpdated: '10 октября 2024 года'
}
},
methods: {
filteredNews() {
let filtered = this.news
if (this.activeFilter !== 'all') {
filtered = this.news.filter(item => item.category === this.activeFilter)
}
return filtered.slice(0, this.visibleNews)
},
// Проверка валидности формы
isFormValid() {
return this.newsForm.title.length >= 5 &&
this.newsForm.title.length <= 255 &&
this.newsForm.excerpt.length >= 10 &&
this.newsForm.excerpt.length <= 500 &&
this.newsForm.content.length >= 50 &&
this.newsForm.category !== ''
},
downloadPDF() {
const link = document.createElement('a')
link.href = '/documents/privacy-policy.pdf'
@@ -119,7 +156,7 @@ export default {
margin: 0 auto;
background: white;
border-radius: 10px;
box-shadow: 0 2px 15px rgba(0,0,0,0.1);
box-shadow: 0 2px 15px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
+36 -4
View File
@@ -277,6 +277,18 @@ export default {
}
},
methods: {
handleFirstInteraction() {
if (!this.hasInteracted) {
this.hasInteracted = true
this.showContent()
clearTimeout(this.autoShowTimeout)
}
},
showContent() {
this.isContentVisible = true
// Эмитим событие для показа хедера
this.$emit('show-header')
},
async onAvatarUpdated() {
this.avatarLoadError = false;
await this.authStore.fetchProfile();
@@ -416,7 +428,23 @@ export default {
} else {
await this.loadExtendedData();
}
}
window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true })
window.addEventListener('click', this.handleFirstInteraction, { once: true })
window.addEventListener('touchstart', this.handleFirstInteraction, { once: true })
this.autoShowTimeout = setTimeout(() => {
if (!this.hasInteracted) {
this.showContent()
}
}, 3000)
},
beforeUnmount() {
// Убираем обработчики при размонтировании
window.removeEventListener('scroll', this.handleFirstInteraction)
window.removeEventListener('click', this.handleFirstInteraction)
window.removeEventListener('touchstart', this.handleFirstInteraction)
clearTimeout(this.autoShowTimeout)
},
}
</script>
@@ -654,6 +682,7 @@ export default {
.avatar-section {
margin-bottom: 1.5rem;
}
.avatar-preview {
position: relative;
width: 150px;
@@ -664,8 +693,10 @@ export default {
border: 4px solid #2e8b57;
background: linear-gradient(135deg, #f5f5f5, #e0e0e0);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
isolation: isolate; /* Новое свойство */
background-image: none !important; /* Явно убираем фоновое изображение */
isolation: isolate;
/* Новое свойство */
background-image: none !important;
/* Явно убираем фоновое изображение */
}
.avatar-image {
@@ -673,7 +704,8 @@ export default {
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
display: block; /* Убедитесь, что block */
display: block;
/* Убедитесь, что block */
}
.avatar-placeholder {
+28 -1
View File
@@ -137,6 +137,18 @@ export default {
}
},
methods: {
handleFirstInteraction() {
if (!this.hasInteracted) {
this.hasInteracted = true
this.showContent()
clearTimeout(this.autoShowTimeout)
}
},
showContent() {
this.isContentVisible = true
// Эмитим событие для показа хедера
this.$emit('show-header')
},
async onAvatarUpdated() {
// Обновляем данные пользователя после загрузки аватара
await this.authStore.fetchProfile()
@@ -205,7 +217,22 @@ export default {
this.initializeForm()
})
}
}
window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true })
window.addEventListener('click', this.handleFirstInteraction, { once: true })
window.addEventListener('touchstart', this.handleFirstInteraction, { once: true })
this.autoShowTimeout = setTimeout(() => {
if (!this.hasInteracted) {
this.showContent()
}
}, 3000)
},
beforeUnmount() {
// Убираем обработчики при размонтировании
window.removeEventListener('scroll', this.handleFirstInteraction)
window.removeEventListener('click', this.handleFirstInteraction)
window.removeEventListener('touchstart', this.handleFirstInteraction)
clearTimeout(this.autoShowTimeout)
},
}
</script>
+30 -1
View File
@@ -125,6 +125,23 @@ import { useAuthStore } from '../stores/auth'
export default {
// eslint-disable-next-line vue/multi-word-component-names
name: 'Register',
mounted() {
window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true })
window.addEventListener('click', this.handleFirstInteraction, { once: true })
window.addEventListener('touchstart', this.handleFirstInteraction, { once: true })
this.autoShowTimeout = setTimeout(() => {
if (!this.hasInteracted) {
this.showContent()
}
}, 3000)
},
beforeUnmount() {
// Убираем обработчики при размонтировании
window.removeEventListener('scroll', this.handleFirstInteraction)
window.removeEventListener('click', this.handleFirstInteraction)
window.removeEventListener('touchstart', this.handleFirstInteraction)
clearTimeout(this.autoShowTimeout)
},
setup() {
const authStore = useAuthStore()
return { authStore }
@@ -195,7 +212,19 @@ export default {
} else {
console.error('Ошибка регистрации:', result.error)
}
}
},
handleFirstInteraction() {
if (!this.hasInteracted) {
this.hasInteracted = true
this.showContent()
clearTimeout(this.autoShowTimeout)
}
},
showContent() {
this.isContentVisible = true
// Эмитим событие для показа хедера
this.$emit('show-header')
},
}
}
</script>
+27
View File
@@ -372,6 +372,18 @@ export default {
}
},
methods: {
handleFirstInteraction() {
if (!this.hasInteracted) {
this.hasInteracted = true
this.showContent()
clearTimeout(this.autoShowTimeout)
}
},
showContent() {
this.isContentVisible = true
// Эмитим событие для показа хедера
this.$emit('show-header')
},
async loadReviews() {
this.loading = true
try {
@@ -643,10 +655,25 @@ export default {
}
},
mounted() {
window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true })
window.addEventListener('click', this.handleFirstInteraction, { once: true })
window.addEventListener('touchstart', this.handleFirstInteraction, { once: true })
this.autoShowTimeout = setTimeout(() => {
if (!this.hasInteracted) {
this.showContent()
}
}, 3000)
this.checkAuth()
this.loadReviews()
this.loadStats()
},
beforeUnmount() {
// Убираем обработчики при размонтировании
window.removeEventListener('scroll', this.handleFirstInteraction)
window.removeEventListener('click', this.handleFirstInteraction)
window.removeEventListener('touchstart', this.handleFirstInteraction)
clearTimeout(this.autoShowTimeout)
},
watch: {
sortBy() {
this.currentPage = 1
+24
View File
@@ -345,6 +345,18 @@ export default {
}
},
methods: {
handleFirstInteraction() {
if (!this.hasInteracted) {
this.hasInteracted = true
this.showContent()
clearTimeout(this.autoShowTimeout)
}
},
showContent() {
this.isContentVisible = true
// Эмитим событие для показа хедера
this.$emit('show-header')
},
getImageUrl(path) {
// В продакшене замените на правильный путь
const baseUrl = import.meta.env.BASE_URL
@@ -387,10 +399,22 @@ export default {
},
mounted() {
document.addEventListener('keydown', this.handleKeydown)
window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true })
window.addEventListener('click', this.handleFirstInteraction, { once: true })
window.addEventListener('touchstart', this.handleFirstInteraction, { once: true })
this.autoShowTimeout = setTimeout(() => {
if (!this.hasInteracted) {
this.showContent()
}
}, 3000)
},
beforeUnmount() {
document.removeEventListener('keydown', this.handleKeydown)
document.body.style.overflow = ''
window.removeEventListener('scroll', this.handleFirstInteraction)
window.removeEventListener('click', this.handleFirstInteraction)
window.removeEventListener('touchstart', this.handleFirstInteraction)
clearTimeout(this.autoShowTimeout)
}
}
</script>