From 00d17363f2ece6721ee487f64a21b531d8daf955 Mon Sep 17 00:00:00 2001 From: andrei Date: Sat, 31 May 2025 19:10:49 +0500 Subject: [PATCH] =?UTF-8?q?=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D0=B5=D1=82=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=B0=D0=BA=D1=82=D0=B8=D0=B2=D0=BD=D0=BE=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WEB/src/pages/HomePage.vue | 108 ++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 42 deletions(-) diff --git a/WEB/src/pages/HomePage.vue b/WEB/src/pages/HomePage.vue index c5cdbc3..a5045b5 100644 --- a/WEB/src/pages/HomePage.vue +++ b/WEB/src/pages/HomePage.vue @@ -4,7 +4,7 @@
@@ -29,7 +29,7 @@ > - + @@ -57,7 +57,7 @@ - +
@@ -80,7 +80,7 @@
-
+
import {ref, computed, onMounted} from 'vue' -import { useRouter} from 'vue-router' -import { Ripple, Notify } from 'quasar' +import {useRouter} from 'vue-router' +import {Ripple, Notify} from 'quasar' import axios from "axios"; -import { parseStringPromise } from 'xml2js' +import {parseStringPromise} from 'xml2js' import CONFIG from "@/core/config.js"; -defineExpose({ directives: { ripple: Ripple } }) +defineExpose({directives: {ripple: Ripple}}) const router = useRouter() @@ -168,19 +168,19 @@ const teamName = ref('Digital Dream Team') // --- Участники --- const members = ref([ - { id: 1, name: 'Иван Иванов', role: 'Team Lead', avatar: 'https://randomuser.me/api/portraits/men/32.jpg' }, - { id: 2, name: 'Мария Петрова', role: 'Frontend', avatar: 'https://randomuser.me/api/portraits/women/44.jpg' }, - { id: 3, name: 'Алексей Смирнов', role: 'Backend', avatar: 'https://randomuser.me/api/portraits/men/65.jpg' }, - { id: 4, name: 'Анна Кузнецова', role: 'Designer', avatar: 'https://randomuser.me/api/portraits/women/56.jpg' }, - { id: 5, name: 'Дмитрий Орлов', role: 'QA', avatar: 'https://randomuser.me/api/portraits/men/78.jpg' }, + {id: 1, name: 'Иван Иванов', role: 'Team Lead', avatar: 'https://randomuser.me/api/portraits/men/32.jpg'}, + {id: 2, name: 'Мария Петрова', role: 'Frontend', avatar: 'https://randomuser.me/api/portraits/women/44.jpg'}, + {id: 3, name: 'Алексей Смирнов', role: 'Backend', avatar: 'https://randomuser.me/api/portraits/men/65.jpg'}, + {id: 4, name: 'Анна Кузнецова', role: 'Designer', avatar: 'https://randomuser.me/api/portraits/women/56.jpg'}, + {id: 5, name: 'Дмитрий Орлов', role: 'QA', avatar: 'https://randomuser.me/api/portraits/men/78.jpg'}, ]) // --- Конкурсы --- const contests = ref([ - { id: 1, title: 'Hackathon 2024', description: 'Ежегодный хакатон для стартапов' }, - { id: 2, title: 'CodeFest', description: 'Соревнование по программированию' }, - { id: 3, title: 'UI/UX Challenge', description: 'Конкурс дизайна интерфейсов' }, - { id: 4, title: 'AI Innovation', description: 'Инициатива в области искусственного интеллекта' }, + {id: 1, title: 'Hackathon 2024', description: 'Ежегодный хакатон для стартапов'}, + {id: 2, title: 'CodeFest', description: 'Соревнование по программированию'}, + {id: 3, title: 'UI/UX Challenge', description: 'Конкурс дизайна интерфейсов'}, + {id: 4, title: 'AI Innovation', description: 'Инициатива в области искусственного интеллекта'}, ]) // --- Активность --- @@ -198,8 +198,15 @@ const weekDays = ['пн', 'ср', 'пт']; const activityGrid = computed(() => { const weeks = []; let week = []; - let firstDay = new Date(activityData.value[0]?.date || new Date()); - firstDay.setDate(firstDay.getDate() - 364); // Начинаем с 365 дней назад + const firstDay = new Date(); + firstDay.setDate(firstDay.getDate() - 364); // Год назад от текущей даты + const dayOfWeek = firstDay.getDay(); + const offset = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // Смещение для выравнивания по понедельнику + + // Добавляем пустые ячейки в начало + for (let i = 0; i < offset; i++) { + week.push({ date: '', count: 0 }); + } for (let i = 0; i < 365; i++) { const date = new Date(firstDay); @@ -218,11 +225,11 @@ const activityGrid = computed(() => { // Цвета активности (как в Gitea) function getActivityColor(count) { - if (count === 0) return '#ebedf0'; - if (count <= 2) return '#c6e48b'; - if (count <= 4) return '#7bc96f'; - if (count <= 6) return '#239a3b'; - return '#196127'; + if (count === 0) return '#ede9fe'; // Светлый фон карточек + if (count <= 2) return '#d8cff9'; // Светлый сиреневый + if (count <= 4) return '#a287ff'; // Светлый фиолетовый + if (count <= 6) return '#7c3aed'; // Яркий фиолетовый + return '#4f046f'; // Темно-фиолетовый } // Позиционирование подписей месяцев @@ -239,24 +246,23 @@ const username = 'andrei'; async function loadActivity() { try { const response = await axios.get(`${CONFIG.BASE_URL}/rss/${username}/`); - activityData.value = response.data; - - // Дополняем до 365 дней + const fetchedData = response.data.map(item => ({ + date: item.date, + count: parseInt(item.count, 10) || 0 + })); + const dataMap = new Map(fetchedData.map(d => [d.date, d.count])); const lastDate = new Date(); const startDate = new Date(lastDate); startDate.setDate(lastDate.getDate() - 364); - const existingDates = new Set(activityData.value.map(d => d.date)); activityData.value = []; for (let i = 0; i < 365; i++) { const date = new Date(startDate); date.setDate(startDate.getDate() + i); const dateStr = date.toISOString().slice(0, 10); - const dayData = response.data.find(d => d.date === dateStr) || { date: dateStr, count: 0 }; - activityData.value.push(dayData); + const count = dataMap.get(dateStr) || 0; + activityData.value.push({date: dateStr, count}); } - - // Сортировка не требуется, так как мы формируем массив в правильном порядке } catch (error) { console.error('Ошибка загрузки активности:', error); Notify.create({ @@ -274,7 +280,7 @@ async function loadActivity() { const date = new Date(startDate); date.setDate(startDate.getDate() + i); const dateStr = date.toISOString().slice(0, 10); - activityData.value.push({ date: dateStr, count: 0 }); + activityData.value.push({date: dateStr, count: 0}); } } } @@ -294,6 +300,18 @@ function decreaseScale() { \ No newline at end of file