@@ -3,7 +3,18 @@ import { habitsAtom, coinsAtom, settingsAtom } from '@/lib/atoms'
3
3
import { addCoins , removeCoins , saveHabitsData } from '@/app/actions/data'
4
4
import { Habit } from '@/lib/types'
5
5
import { DateTime } from 'luxon'
6
- import { getNowInMilliseconds , getTodayInTimezone , isSameDate , t2d , d2t , getNow , getCompletionsForDate , getISODate , d2s } from '@/lib/utils'
6
+ import {
7
+ getNowInMilliseconds ,
8
+ getTodayInTimezone ,
9
+ isSameDate ,
10
+ t2d ,
11
+ d2t ,
12
+ getNow ,
13
+ getCompletionsForDate ,
14
+ getISODate ,
15
+ d2s ,
16
+ playSound
17
+ } from '@/lib/utils'
7
18
import { toast } from '@/hooks/use-toast'
8
19
import { ToastAction } from '@/components/ui/toast'
9
20
import { Undo2 } from 'lucide-react'
@@ -38,37 +49,46 @@ export function useHabits() {
38
49
// Add new completion
39
50
const updatedHabit = {
40
51
...habit ,
41
- completions : [ ...habit . completions , d2t ( { dateTime : getNow ( { timezone } ) } ) ]
52
+ completions : [ ...habit . completions , d2t ( { dateTime : getNow ( { timezone } ) } ) ] ,
53
+ // Archive the habit if it's a task and we're about to reach the target
54
+ archived : habit . isTask && completionsToday + 1 === target ? true : habit . archived
42
55
}
43
56
44
57
const updatedHabits = habitsData . habits . map ( h =>
45
58
h . id === habit . id ? updatedHabit : h
46
59
)
47
60
48
61
await saveHabitsData ( { habits : updatedHabits } )
49
- setHabitsData ( { habits : updatedHabits } )
50
62
51
63
// Check if we've now reached the target
52
64
const isTargetReached = completionsToday + 1 === target
53
65
if ( isTargetReached ) {
54
66
const updatedCoins = await addCoins ( {
55
67
amount : habit . coinReward ,
56
- description : `Completed habit : ${ habit . name } ` ,
68
+ description : `Completed: ${ habit . name } ` ,
57
69
type : habit . isTask ? 'TASK_COMPLETION' : 'HABIT_COMPLETION' ,
58
70
relatedItemId : habit . id ,
59
71
} )
72
+ isTargetReached && playSound ( )
73
+ toast ( {
74
+ title : "Habit completed!" ,
75
+ description : `You earned ${ habit . coinReward } coins.` ,
76
+ action : < ToastAction altText = "Undo" className = "gap-2" onClick = { ( ) => undoComplete ( updatedHabit ) } >
77
+ < Undo2 className = "h-4 w-4" /> Undo
78
+ </ ToastAction >
79
+ } )
60
80
setCoins ( updatedCoins )
81
+ } else {
82
+ toast ( {
83
+ title : "Progress!" ,
84
+ description : `You've completed ${ completionsToday + 1 } /${ target } times today.` ,
85
+ action : < ToastAction altText = "Undo" className = "gap-2" onClick = { ( ) => undoComplete ( updatedHabit ) } >
86
+ < Undo2 className = "h-4 w-4" /> Undo
87
+ </ ToastAction >
88
+ } )
61
89
}
62
-
63
- toast ( {
64
- title : isTargetReached ? "Habit completed!" : "Progress!" ,
65
- description : isTargetReached
66
- ? `You earned ${ habit . coinReward } coins.`
67
- : `You've completed ${ completionsToday + 1 } /${ target } times today.` ,
68
- action : < ToastAction altText = "Undo" className = "gap-2" onClick = { ( ) => undoComplete ( updatedHabit ) } >
69
- < Undo2 className = "h-4 w-4" /> Undo
70
- </ ToastAction >
71
- } )
90
+ // move atom update at the end of function to improve UI responsiveness
91
+ setHabitsData ( { habits : updatedHabits } )
72
92
73
93
return {
74
94
updatedHabits,
@@ -87,12 +107,13 @@ export function useHabits() {
87
107
)
88
108
89
109
if ( todayCompletions . length > 0 ) {
90
- // Remove the most recent completion
110
+ // Remove the most recent completion and unarchive if needed
91
111
const updatedHabit = {
92
112
...habit ,
93
113
completions : habit . completions . filter (
94
114
( _ , index ) => index !== habit . completions . length - 1
95
- )
115
+ ) ,
116
+ archived : habit . isTask ? undefined : habit . archived // Unarchive if it's a task
96
117
}
97
118
98
119
const updatedHabits = habitsData . habits . map ( h =>
@@ -107,7 +128,7 @@ export function useHabits() {
107
128
if ( todayCompletions . length === target ) {
108
129
const updatedCoins = await removeCoins ( {
109
130
amount : habit . coinReward ,
110
- description : `Undid habit completion: ${ habit . name } ` ,
131
+ description : `Undid completion: ${ habit . name } ` ,
111
132
type : habit . isTask ? 'TASK_UNDO' : 'HABIT_UNDO' ,
112
133
relatedItemId : habit . id ,
113
134
} )
@@ -207,7 +228,7 @@ export function useHabits() {
207
228
if ( isTargetReached ) {
208
229
const updatedCoins = await addCoins ( {
209
230
amount : habit . coinReward ,
210
- description : `Completed habit : ${ habit . name } on ${ d2s ( { dateTime : date , timezone, format : 'yyyy-MM-dd' } ) } ` ,
231
+ description : `Completed: ${ habit . name } on ${ d2s ( { dateTime : date , timezone, format : 'yyyy-MM-dd' } ) } ` ,
211
232
type : habit . isTask ? 'TASK_COMPLETION' : 'HABIT_COMPLETION' ,
212
233
relatedItemId : habit . id ,
213
234
} )
0 commit comments