export function dateKey(date: Date) { const y = date.getFullYear() const m = `${date.getMonth() + 1}`.padStart(2, '0') const d = `${date.getDate()}`.padStart(2, '0') return `${y}-${m}-${d}` } export function habitWeek(now = new Date()) { const monday = new Date(now.getFullYear(), now.getMonth(), now.getDate()) monday.setDate(monday.getDate() - ((monday.getDay() + 6) % 7)) return Array.from({ length: 7 }, (_, index) => { const date = new Date(monday) date.setDate(monday.getDate() + index) return date }) } export function mergePage(page: T[] | { items?: T[]; next_cursor?: string | null }) { if (Array.isArray(page)) return { items: page, nextCursor: null } return { items: page.items ?? [], nextCursor: page.next_cursor ?? null } } export function isTaskView(view: string) { return view === 'tasks' || view === 'today' || view === 'upcoming' } export function isHabitComplete(kind: string | undefined, value: number | boolean | undefined, target = 1) { if (kind === 'numeric') return Number(value ?? 0) >= target return Boolean(value) } export function numericHabitInputValue(input: number | string | undefined) { if (input === undefined || input === '') return null const value = Number(input) return Number.isFinite(value) && value >= 0 ? value : null } export function shouldToggleHabitSwipe(deltaX: number, deltaY: number) { return deltaX >= 64 && Math.abs(deltaY) <= 24 && deltaX > Math.abs(deltaY) * 1.5 }