diff --git a/begushiybashkir/bbvue/src/views/Members.vue b/begushiybashkir/bbvue/src/views/Members.vue index 7be3368..e66a92f 100644 --- a/begushiybashkir/bbvue/src/views/Members.vue +++ b/begushiybashkir/bbvue/src/views/Members.vue @@ -1,20 +1,457 @@ @@ -24,46 +461,1425 @@ export default { name: 'Members', data() { return { + searchQuery: '', + filters: { + level: 'all', + distance: 'all', + city: 'all' + }, + viewMode: 'grid', + currentPage: 1, + membersPerPage: 12, + showProfileModal: false, + selectedMember: null, + searchTimeout: null, members: [ - { id: 1, name: 'Сергей', role: 'Марафонец', achievement: 'Лучший: 3:27.49', avatar: 'https://via.placeholder.com/80/2e8b57/ffffff?text=С' }, - { id: 2, name: 'Ильгам', role: 'Спринтер', achievement: '10км: 37:59', avatar: 'https://via.placeholder.com/80/2e8b57/ffffff?text=И' }, - { id: 3, name: 'Данил', role: 'Ультрамарафонец', achievement: 'Трейлы 120км', avatar: 'https://via.placeholder.com/80/2e8b57/ffffff?text=Д' }, - { id: 4, name: 'Ғаяз', role: 'Стайер', achievement: 'Марафон: 3:34.33', avatar: 'https://via.placeholder.com/80/2e8b57/ffffff?text=Ғ' } + // Здесь будет большой массив участников (для примера 24 участника) + { + id: 1, + name: 'Сергей', + city: 'Уфа', + level: 'professional', + avatar: 'https://via.placeholder.com/120/2e8b57/ffffff?text=СИ', + weeklyDistance: 65, + totalDistance: 2450, + memberSince: '2 года', + bestDistance: 'Марафон 3:27:49', + pb: '10км - 36:52', + recentAchievement: 'I место РосХим 2025', + interests: ['Марафоны', 'Трейлраннинг', 'Силовые тренировки'], + isOnline: true, + telegram: '@sergei_runner', + trainingsCount: 156, + achievementsCount: 23, + about: 'Бегаю с 2020 года. Участвую в марафонах и ультразабегах. Люблю горные трейлы и длительные дистанции.' + }, + { + id: 2, + name: 'Ильгам', + city: 'Уфа', + level: 'advanced', + avatar: 'https://via.placeholder.com/120/26734a/ffffff?text=ИХ', + weeklyDistance: 45, + totalDistance: 1800, + memberSince: '1.5 года', + bestDistance: '10км - 37:59', + pb: '5км - 17:45', + interests: ['Спринт', 'Интервальные тренировки', 'Футбол'], + isOnline: false, + telegram: '@ilgam_sprint', + trainingsCount: 98, + achievementsCount: 15 + }, + // ... остальные 22 участника с аналогичной структурой + // Для демонстрации создам еще несколько + { + id: 3, + name: 'Данил', + city: 'Уфа', + level: 'professional', + avatar: 'https://via.placeholder.com/120/2e8b57/ffffff?text=ДХ', + weeklyDistance: 80, + totalDistance: 3200, + memberSince: '2.5 года', + bestDistance: 'Ультра 120км', + pb: 'Полумарафон 1:30:40', + interests: ['Ультрамарафоны', 'Трейл', 'Горный бег'], + isOnline: true, + telegram: '@danil_ultra', + trainingsCount: 201, + achievementsCount: 31, + about: 'Специализируюсь на ультрамарафонах и трейлраннинге. Помогаю новичкам в подготовке к длительным дистанциям.' + }, + { + id: 4, + name: 'Ғаяз', + city: 'Уфа', + level: 'advanced', + avatar: 'https://via.placeholder.com/120/26734a/ffffff?text=ҒВ', + weeklyDistance: 55, + totalDistance: 2100, + memberSince: '1 год', + bestDistance: 'Марафон 3:34:33', + pb: 'Полумарафон 1:31:40', + interests: ['Марафоны', 'Велоспорт', 'Плавание'], + isOnline: true, + telegram: '@gaziz_marathon', + trainingsCount: 112, + achievementsCount: 18 + }, + { + id: 5, + name: 'Анна', + city: 'Стерлитамак', + level: 'intermediate', + avatar: 'https://via.placeholder.com/120/e74c3c/ffffff?text=АП', + weeklyDistance: 25, + totalDistance: 650, + memberSince: '8 месяцев', + bestDistance: '10км - 53:25', + pb: '5км - 25:13', + interests: ['ОФП', 'Йога', 'Здоровое питание'], + isOnline: false, + telegram: '@anna_health', + trainingsCount: 45, + achievementsCount: 8, + about: 'Начала бегать для здоровья и похудения. За 8 месяцев похудела на 12 кг и полюбила активный образ жизни!' + }, + { + id: 6, + name: 'Михаил', + city: 'Уфа', + level: 'beginner', + avatar: 'https://via.placeholder.com/120/3498db/ffffff?text=МК', + weeklyDistance: 15, + totalDistance: 180, + memberSince: '3 месяца', + bestDistance: '5км - 32:15', + interests: ['Начальный уровень', 'Общефизическая подготовка'], + isOnline: true, + trainingsCount: 18, + achievementsCount: 3 + } + // ... можно добавить еще участников для демонстрации ] } + }, + computed: { + totalMembers() { + return this.members.length + }, + activeMembers() { + return this.members.filter(member => member.isOnline).length + }, + citiesCount() { + const cities = new Set(this.members.map(member => member.city)) + return cities.size + }, + totalDistance() { + return this.members.reduce((sum, member) => sum + member.totalDistance, 0) + }, + cities() { + return [...new Set(this.members.map(member => member.city))].sort() + }, + filteredMembers() { + let filtered = this.members + + // Поиск по имени и городу + if (this.searchQuery) { + const query = this.searchQuery.toLowerCase() + filtered = filtered.filter(member => + member.name.toLowerCase().includes(query) || + member.city.toLowerCase().includes(query) + ) + } + + // Фильтрация по уровню + if (this.filters.level !== 'all') { + filtered = filtered.filter(member => member.level === this.filters.level) + } + + // Фильтрация по городу + if (this.filters.city !== 'all') { + filtered = filtered.filter(member => member.city === this.filters.city) + } + + return filtered + }, + paginatedMembers() { + const startIndex = (this.currentPage - 1) * this.membersPerPage + return this.filteredMembers.slice(startIndex, startIndex + this.membersPerPage) + }, + totalPages() { + return Math.ceil(this.filteredMembers.length / this.membersPerPage) + }, + visiblePages() { + const pages = [] + const startPage = Math.max(1, this.currentPage - 2) + const endPage = Math.min(this.totalPages, startPage + 4) + + for (let i = startPage; i <= endPage; i++) { + pages.push(i) + } + return pages + }, + showFilterStats() { + return this.searchQuery || + this.filters.level !== 'all' || + this.filters.distance !== 'all' || + this.filters.city !== 'all' + } + }, + methods: { + getLevelLabel(level) { + const labels = { + 'beginner': 'Новичок', + 'intermediate': 'Любитель', + 'advanced': 'Опытный', + 'professional': 'Профи' + } + return labels[level] || level + }, + handleSearch() { + // Дебаунс поиска + clearTimeout(this.searchTimeout) + this.searchTimeout = setTimeout(() => { + this.currentPage = 1 + }, 300) + }, + applyFilters() { + this.currentPage = 1 + }, + clearFilters() { + this.searchQuery = '' + this.filters = { + level: 'all', + distance: 'all', + city: 'all' + } + this.currentPage = 1 + }, + changePage(page) { + this.currentPage = page + window.scrollTo({ top: 0, behavior: 'smooth' }) + }, + viewProfile(member) { + this.selectedMember = member + this.showProfileModal = true + document.body.style.overflow = 'hidden' + }, + closeProfileModal() { + this.showProfileModal = false + document.body.style.overflow = '' + }, + contactMember(member) { + if (member.telegram) { + window.open(`https://t.me/${member.telegram.replace('@', '')}`, '_blank') + } + }, + suggestTraining(member) { + alert(`Предложить совместную тренировку ${member.name}`) + // В реальном приложении открыть форму предложения тренировки + }, + handleImageError(event) { + event.target.src = 'https://via.placeholder.com/120/666666/ffffff?text=🏃' + }, + handleKeydown(event) { + if (event.key === 'Escape' && this.showProfileModal) { + this.closeProfileModal() + } + } + }, + mounted() { + document.addEventListener('keydown', this.handleKeydown) + + // Загрузка дополнительных данных (мок) + this.loadAdditionalMembers() + }, + beforeUnmount() { + document.removeEventListener('keydown', this.handleKeydown) + document.body.style.overflow = '' } } \ No newline at end of file diff --git a/begushiybashkir/bbvue/src/views/Reviews.vue b/begushiybashkir/bbvue/src/views/Reviews.vue index 68ea515..a97d932 100644 --- a/begushiybashkir/bbvue/src/views/Reviews.vue +++ b/begushiybashkir/bbvue/src/views/Reviews.vue @@ -352,6 +352,7 @@