added habit daily completion target (#26)

This commit is contained in:
Doh
2025-01-05 16:56:04 -05:00
committed by GitHub
parent 86a517a859
commit aaa7e384bc
19 changed files with 577 additions and 132 deletions

View File

@@ -4,7 +4,8 @@ export type Habit = {
description: string
frequency: 'daily' | 'weekly' | 'monthly'
coinReward: number
completions: string[] // Array of ISO date strings
targetCompletions?: number // Optional field, default to 1
completions: string[] // Array of UTC ISO date strings
}
export type WishlistItemType = {

View File

@@ -1,6 +1,7 @@
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
import { DateTime } from "luxon"
import { Habit } from '@/lib/types'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
@@ -55,3 +56,68 @@ export function d2n({ dateTime }: { dateTime: DateTime }) {
export function isSameDate(a: DateTime, b: DateTime) {
return a.hasSame(b, 'day');
}
export function normalizeCompletionDate(date: string, timezone: string): string {
// If already in ISO format, return as is
if (date.includes('T')) {
return date;
}
// Convert from yyyy-MM-dd to ISO format
return DateTime.fromFormat(date, 'yyyy-MM-dd', { zone: timezone }).toUTC().toISO()!;
}
export function getCompletionsForDate({
habit,
date,
timezone
}: {
habit: Habit,
date: DateTime | string,
timezone: string
}): number {
const dateObj = typeof date === 'string' ? DateTime.fromISO(date) : date
return habit.completions.filter((completion: string) =>
isSameDate(t2d({ timestamp: completion, timezone }), dateObj)
).length
}
export function getCompletedHabitsForDate({
habits,
date,
timezone
}: {
habits: Habit[],
date: DateTime | string,
timezone: string
}): Habit[] {
return habits.filter(habit => {
const completionsToday = getCompletionsForDate({ habit, date, timezone })
const target = habit.targetCompletions || 1
return completionsToday >= target
})
}
export function isHabitCompletedToday({
habit,
timezone
}: {
habit: Habit,
timezone: string
}): boolean {
const today = getTodayInTimezone(timezone)
const completionsToday = getCompletionsForDate({ habit, date: today, timezone })
return completionsToday >= (habit.targetCompletions || 1)
}
export function getHabitProgress({
habit,
timezone
}: {
habit: Habit,
timezone: string
}): number {
const today = getTodayInTimezone(timezone)
const completionsToday = getCompletionsForDate({ habit, date: today, timezone })
const target = habit.targetCompletions || 1
return Math.min(100, (completionsToday / target) * 100)
}