AnhviNguyen
first commit
b1a388c
Raw
History Blame Contribute Delete
1.64 kB
/**
* src/composables/useHeatmap.js
* ──────────────────────────────
* SRP: Generate calendar heatmap data for current month.
* Returns an array of day objects for rendering.
*/
import { computed } from 'vue'
/**
* @param {Object} activityMap - { 'YYYY-MM-DD': count } from API
*/
export function useHeatmap(activityMap = {}) {
const today = new Date()
const calendarData = computed(() => {
const year = today.getFullYear()
const month = today.getMonth()
const daysInMonth = new Date(year, month + 1, 0).getDate()
const todayDate = today.getDate()
// Day of week for 1st of month (0=Sun → adjust to Mon-start)
let firstDow = new Date(year, month, 1).getDay()
firstDow = firstDow === 0 ? 6 : firstDow - 1 // Mon=0
const days = []
// Empty cells before day 1
for (let i = 0; i < firstDow; i++) {
days.push({ day: null, empty: true, level: 0 })
}
// Day cells
for (let d = 1; d <= daysInMonth; d++) {
const key = `${year}-${String(month + 1).padStart(2, '0')}-${String(d).padStart(2, '0')}`
const count = activityMap[key] ?? 0
let level = 0
if (count >= 3) level = 3
else if (count === 2) level = 2
else if (count === 1) level = 1
days.push({
day: d,
empty: false,
isToday: d === todayDate,
level,
count,
key,
})
}
return days
})
const monthLabel = computed(() => {
return today.toLocaleDateString('vi-VN', { month: 'long', year: 'numeric' })
})
return { calendarData, monthLabel }
}