import {computed, type ComputedRef, type Ref} from 'vue' export type DayCell = { isoDate: string day: number isCurrentMonth: boolean isToday: boolean } export type WeekRow = { weekNumber: number days: DayCell[] } const toIso = (d: Date): string => { const y = d.getFullYear() const m = String(d.getMonth() + 1).padStart(2, '0') const day = String(d.getDate()).padStart(2, '0') return `${y}-${m}-${day}` } const isoWeek = (d: Date): number => { const target = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate())) const dayNum = target.getUTCDay() || 7 // dimanche = 7 target.setUTCDate(target.getUTCDate() + 4 - dayNum) // jeudi de la semaine const yearStart = new Date(Date.UTC(target.getUTCFullYear(), 0, 1)) return Math.ceil((((target.getTime() - yearStart.getTime()) / 86400000) + 1) / 7) } export function useMonthMatrix( month: Ref, year: Ref, ): {weeks: ComputedRef} { const weeks = computed(() => { const todayIso = toIso(new Date()) const first = new Date(year.value, month.value, 1) // recule jusqu'au lundi (getDay : 0 = dimanche) const offset = (first.getDay() + 6) % 7 const start = new Date(year.value, month.value, 1 - offset) const rows: WeekRow[] = [] const cursor = new Date(start) for (let w = 0; w < 6; w++) { const days: DayCell[] = [] for (let i = 0; i < 7; i++) { const iso = toIso(cursor) days.push({ isoDate: iso, day: cursor.getDate(), isCurrentMonth: cursor.getMonth() === month.value, isToday: iso === todayIso, }) cursor.setDate(cursor.getDate() + 1) } rows.push({weekNumber: isoWeek(new Date(`${days[0].isoDate}T00:00:00`)), days}) } return rows }) return {weeks} }