diff --git a/docs/TZ.md b/docs/TZ.md index f281f33..20718dd 100644 --- a/docs/TZ.md +++ b/docs/TZ.md @@ -4,7 +4,7 @@ | | | |---|---| -| Версия ТЗ | 0.10 | +| Версия ТЗ | 0.11 | | Дата | 2026-09-20 | | Статус | На обсуждении | @@ -191,7 +191,8 @@ с **предыдущим аналогичным периодом** (дельта и проценты). Анимированный **сравнительный** график закрытых задач по бакетам периода (часы / дни недели / дни месяца): текущий и предыдущий период — пары столбиков. **Сетка активности** - «как в гитхабе» за полгода (цвет по закрытым задачам или XP, переключается). + «как в гитхабе» за полгода или год (переключатель диапазона; цвет по закрытым + задачам или XP, переключается). Данные считаются из `xp_events` и дат задач, без новых эндпоинтов. - **Справка «О саде»**: кнопка на странице сада открывает модалку с объяснением механик (XP, уровни, растения и редкости, ачивки, принцип «только позитив»). diff --git a/frontend/src/locales/en.ts b/frontend/src/locales/en.ts index b06fe54..c393162 100644 --- a/frontend/src/locales/en.ts +++ b/frontend/src/locales/en.ts @@ -115,11 +115,14 @@ chartTitle: 'Completed tasks', legendNow: 'Now', legendPrev: 'Previous period', - heatmapTitle: 'Activity over 6 months', + heatmapHalf: 'Activity over 6 months', + heatmapYear: 'Activity over the year', heatTasks: 'Tasks', heatXp: 'XP', heatLess: 'less', heatMore: 'more', + heatHalf: 'Half a year', + heatYear: 'Year', emptyTitle: 'No data yet', emptyText: 'Complete a couple of tasks — dynamics with comparisons will appear here.', metric: { diff --git a/frontend/src/locales/ru.ts b/frontend/src/locales/ru.ts index 5d2cac3..ff5f029 100644 --- a/frontend/src/locales/ru.ts +++ b/frontend/src/locales/ru.ts @@ -116,11 +116,14 @@ chartTitle: 'Закрытые задачи', legendNow: 'Сейчас', legendPrev: 'Предыдущий период', - heatmapTitle: 'Активность за полгода', + heatmapHalf: 'Активность за полгода', + heatmapYear: 'Активность за год', heatTasks: 'Задачи', heatXp: 'XP', heatLess: 'меньше', heatMore: 'больше', + heatHalf: 'Полгода', + heatYear: 'Год', emptyTitle: 'Пока нет данных', emptyText: 'Закройте пару задач — и здесь появится динамика со сравнением.', metric: { diff --git a/frontend/src/locales/uk.ts b/frontend/src/locales/uk.ts index cae4a61..ded89a1 100644 --- a/frontend/src/locales/uk.ts +++ b/frontend/src/locales/uk.ts @@ -115,11 +115,14 @@ chartTitle: 'Виконані завдання', legendNow: 'Зараз', legendPrev: 'Попередній період', - heatmapTitle: 'Активність за півроку', + heatmapHalf: 'Активність за півроку', + heatmapYear: 'Активність за рік', heatTasks: 'Завдання', heatXp: 'XP', heatLess: 'менше', heatMore: 'більше', + heatHalf: 'Півроку', + heatYear: 'Рік', emptyTitle: 'Поки немає даних', emptyText: 'Закрийте пару завдань — і тут з’явиться динаміка з порівнянням.', metric: { diff --git a/frontend/src/views/StatsView.vue b/frontend/src/views/StatsView.vue index d541075..a287b36 100644 --- a/frontend/src/views/StatsView.vue +++ b/frontend/src/views/StatsView.vue @@ -280,17 +280,28 @@ type HeatMode = 'tasks' | 'xp' const heatMode = ref('tasks') -const HEAT_WEEKS = 26 +// Дальность сетки: полгода (26 недель) или год (52 недели) +type HeatRange = 'half' | 'year' +const heatRange = ref('half') const heatItems = computed(() => [ { id: 'tasks', label: t('stats.heatTasks') }, { id: 'xp', label: t('stats.heatXp') }, ]) +const heatRangeItems = computed(() => [ + { id: 'half', label: t('stats.heatHalf') }, + { id: 'year', label: t('stats.heatYear') }, +]) + function setHeatMode(id: string | number) { heatMode.value = id as HeatMode } +function setHeatRange(id: string | number) { + heatRange.value = id as HeatRange +} + // Уровень заливки 0–4 по интенсивности function heatLevel(value: number, mode: HeatMode): number { if (value <= 0) return 0 @@ -312,6 +323,7 @@ } const heatmap = computed(() => { + const heatWeeks = heatRange.value === 'year' ? 52 : 26 const fmt = new Intl.DateTimeFormat(locale.value, { day: 'numeric', month: 'short' }) const perDay = new Map() events.value.forEach((e) => { @@ -322,10 +334,10 @@ perDay.set(key, bucket) }) const first = startOfWeek(new Date()) - first.setDate(first.getDate() - (HEAT_WEEKS - 1) * 7) + first.setDate(first.getDate() - (heatWeeks - 1) * 7) const now = new Date() const weeks: HeatCell[][] = [] - for (let w = 0; w < HEAT_WEEKS; w++) { + for (let w = 0; w < heatWeeks; w++) { const col: HeatCell[] = [] for (let d = 0; d < 7; d++) { const date = new Date(first.getFullYear(), first.getMonth(), first.getDate() + w * 7 + d) @@ -460,10 +472,10 @@

{{ totalLabel }}

- +