отображение сетки активности
This commit is contained in:
parent
24ce580bd2
commit
00d17363f2
@ -80,7 +80,7 @@
|
||||
|
||||
<div class="activity-grid-row row no-wrap">
|
||||
<!-- Дни недели слева -->
|
||||
<div class="weekdays-column column q-pr-sm" style="width: 40px; user-select: none;">
|
||||
<div class="weekdays-column column q-pr-sm" style="width: 40px; user-select: none; justify-content: space-around;">
|
||||
<div
|
||||
v-for="(day, idx) in weekDays"
|
||||
:key="day"
|
||||
@ -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({
|
||||
@ -294,6 +300,18 @@ function decreaseScale() {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.activity-grid {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow-x: auto;
|
||||
}
|
||||
.activity-card {
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
.activity-card .activity-square {
|
||||
border-radius: 4px !important;
|
||||
}
|
||||
.bg-violet-strong {
|
||||
background: linear-gradient(135deg, #4f046f 0%, #7c3aed 100%);
|
||||
min-height: 100vh;
|
||||
@ -301,7 +319,6 @@ function decreaseScale() {
|
||||
color: #3e2465;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.team-logo {
|
||||
background: #fff;
|
||||
border-radius: 50%;
|
||||
@ -316,27 +333,23 @@ function decreaseScale() {
|
||||
transform: scale(1.1);
|
||||
box-shadow: 0 0 14px #a287ffaa;
|
||||
}
|
||||
|
||||
.team-name-card {
|
||||
border-radius: 20px;
|
||||
background: #ede9fe;
|
||||
box-shadow: 0 8px 24px rgba(124, 58, 237, 0.18), 0 2px 8px rgba(124, 58, 237, 0.12);
|
||||
max-width: 900px;
|
||||
}
|
||||
|
||||
.violet-card {
|
||||
border-radius: 22px;
|
||||
background: #ede9fe;
|
||||
box-shadow: 0 8px 24px rgba(124, 58, 237, 0.18), 0 2px 8px rgba(124, 58, 237, 0.12);
|
||||
transition: box-shadow 0.3s ease, transform 0.3s ease;
|
||||
}
|
||||
|
||||
.violet-card:hover {
|
||||
box-shadow: 0 14px 40px rgba(124, 58, 237, 0.30), 0 6px 16px rgba(124, 58, 237, 0.20);
|
||||
transform: translateY(-6px);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.member-card, .contest-card {
|
||||
min-height: 140px;
|
||||
padding: 8px 12px;
|
||||
@ -344,27 +357,38 @@ function decreaseScale() {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.activity-card {
|
||||
max-width: 920px;
|
||||
border-radius: 20px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.activity-grid {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.activity-week {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.activity-square {
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 0 3px rgba(124, 58, 237, 0.3);
|
||||
cursor: default;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
.months-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
margin-left: 40px; /* Синхронизация с .weekdays-column */
|
||||
margin-bottom: 24px !important;
|
||||
position: relative;
|
||||
}
|
||||
.month-label {
|
||||
width: auto;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
position: absolute; /* Для точного позиционирования */
|
||||
}
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user