From d412046627f805823a10f3fb16f6492829827538 Mon Sep 17 00:00:00 2001 From: rathi Date: Sun, 17 Nov 2024 21:12:21 -0500 Subject: [PATCH] working version 2 --- habits.db | Bin 20480 -> 20480 bytes src/App.tsx | 22 ++++++---- src/components/HabitList.tsx | 78 +++++++++++++++++++++++++++-------- src/types.ts | 1 + 4 files changed, 75 insertions(+), 26 deletions(-) diff --git a/habits.db b/habits.db index 9ec18cb7bdff8c160e095f877a22b92ab0571ab2..8276e8b2643cb1930e95b0748a9be8ded4415fa4 100644 GIT binary patch delta 937 zcmZozz}T>Wae_4C{E0HojPo}pEaB&4;lIql|C#?e|2_W8{FgTi3LNCu5as2+%wW#bGMU}L zRf{);H-xu^w}kfy?-t%Ayi<5xcuja!ctvCsCjSP%TbPWx44bAu*QTXP34k&yRK6_?HMPaylV?H|+z6qZ#GozviT;7z=28D0J zXU)v0CrG7JOzXd~-fMW=2JBxCQ2Xx+r`LK0{=F zkf8~m0kVLh5uYhDqoN?(03$vV6uvQ^F^YOqJ|h&q@#ZVG229N6Jie3J9bC0|V|f?y z`tVNR)#A10&Eu`-`Ofo<=PJ(;UP)dKo(7(YJezqI@#ORP^2BXyyv|)Oz{04=h!h=8 zXaeSrXaXh%Vr#fdGNfQb!QK*-3T9-0hHtzjZi0TU}U0b@%v0V4}E z0Sj|90dq6308-rOp$S;j>!OL67@`Rn8Gr?l;>Q$Cz}N&VfUw5Y7)`*~2rR$_k7E-x NumGpg=2O0AOaNbssf+*s delta 119 zcmZozz}T>Wae_2s%tRSy#+Z!>OZa&h1Q;0jU-7@Dp4@pr0}1ggNv8{GJ_KDmC5V|uA3DFI(Ro QncV>-lE%Avldm5W0EM|AW&i*H diff --git a/src/App.tsx b/src/App.tsx index 12b3abf..519f628 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -137,15 +137,21 @@ export default function HabitTracker() { // Prevent negative streaks if (newStreak < 0) return; - // Update in database - await db.habits.update(id, { manualStreak: newStreak }); + try { + // Update in database + await fetch(`http://localhost:5000/api/habits/${id}/streak`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ streak: newStreak }), + }); - // Update state - setHabits(habits.map(habit => - habit.id === id - ? { ...habit, manualStreak: newStreak } - : habit - )); + // Update state + setHabits(habits.map(habit => + habit.id === id ? { ...habit, manualStreak: newStreak } : habit + )); + } catch (error) { + console.error('Error updating streak:', error); + } }; return ( diff --git a/src/components/HabitList.tsx b/src/components/HabitList.tsx index a03fd64..b775b92 100644 --- a/src/components/HabitList.tsx +++ b/src/components/HabitList.tsx @@ -9,35 +9,60 @@ interface HabitListProps { onToggleHabit: (id: number, date: string) => void; onUpdateHabit: (id: number, name: string) => void; onDeleteHabit: (id: number) => void; + onUpdateStreak: (id: number, newStreak: number) => Promise; } -const calculateStreak = (completedDates: string[]): number => { - if (completedDates.length === 0) return 0; +const calculateStreak = (completedDates: string[]): { currentStreak: number; bestStreak: number } => { + if (completedDates.length === 0) return { currentStreak: 0, bestStreak: 0 }; - // Sort dates in ascending order const sortedDates = [...completedDates].sort((a, b) => new Date(a).getTime() - new Date(b).getTime() ); let currentStreak = 1; - let maxStreak = 1; + let bestStreak = 1; + let tempStreak = 1; - // Go through the dates and count consecutive completions + // Check if the last completion was today or yesterday + const lastDate = new Date(sortedDates[sortedDates.length - 1]); + const today = new Date(); + today.setHours(0, 0, 0, 0); + lastDate.setHours(0, 0, 0, 0); + + const diffDays = Math.floor((today.getTime() - lastDate.getTime()) / (24 * 60 * 60 * 1000)); + + // If the last completion was more than a day ago, current streak is 0 + if (diffDays > 1) { + currentStreak = 0; + } + + // Calculate streaks for (let i = 1; i < sortedDates.length; i++) { const prevDate = new Date(sortedDates[i - 1]); const currDate = new Date(sortedDates[i]); + prevDate.setHours(0, 0, 0, 0); + currDate.setHours(0, 0, 0, 0); - // If dates are consecutive or same day, increment streak - if (currDate.getTime() - prevDate.getTime() <= 24 * 60 * 60 * 1000) { - currentStreak++; - maxStreak = Math.max(maxStreak, currentStreak); + const diffTime = currDate.getTime() - prevDate.getTime(); + const diffDays = Math.floor(diffTime / (24 * 60 * 60 * 1000)); + + if (diffDays === 1) { + tempStreak++; + bestStreak = Math.max(bestStreak, tempStreak); + } else if (diffDays === 0) { + // Same day completions don't affect streak + continue; } else { - // Reset streak counter when there's a gap - currentStreak = 1; + tempStreak = 1; } } - return maxStreak; + // Current streak should be the same as tempStreak if the last completion was today or yesterday + if (diffDays <= 1) { + currentStreak = tempStreak; + } + + return { currentStreak, bestStreak }; }; export function HabitList({ @@ -47,6 +72,7 @@ export function HabitList({ onToggleHabit, onUpdateHabit, onDeleteHabit, + onUpdateStreak, }: HabitListProps) { return ( @@ -61,11 +87,11 @@ export function HabitList({ ))} + @@ -78,6 +104,8 @@ export function HabitList({ type="text" value={habit.name} onChange={(e) => onUpdateHabit(habit.id, e.target.value)} + aria-label="Habit name" + placeholder="Enter habit name" className="bg-transparent border-none focus:outline-none focus:ring-2 focus:ring-gray-300 rounded px-2" /> @@ -86,14 +114,28 @@ export function HabitList({ onToggleHabit(habit.id, date)} + onChange={() => { + onToggleHabit(habit.id, date); + const newCompletedDates = habit.completedDates.includes(date) + ? habit.completedDates.filter(d => d !== date) + : [...habit.completedDates, date]; + + const { currentStreak, bestStreak } = calculateStreak(newCompletedDates); + onUpdateStreak(habit.id, bestStreak); + }} + aria-label={`Mark ${habit.name} as completed for ${date}`} className="w-4 h-4 rounded border-gray-300 dark:border-gray-600" /> ))} +
+ Current Streak + Best Streak -
- consecutive completions -
Actions
- {calculateStreak(habit.completedDates)} + {calculateStreak(habit.completedDates).currentStreak} + + + + {calculateStreak(habit.completedDates).bestStreak} @@ -109,4 +151,4 @@ export function HabitList({
); -} \ No newline at end of file +} diff --git a/src/types.ts b/src/types.ts index 4c7b8af..9586860 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,4 +2,5 @@ export interface Habit { id: number; name: string; completedDates: string[]; + bestStreak: number; } \ No newline at end of file