@@ -10,10 +10,12 @@ import {
1010 HabitSchema ,
1111} from "@/proto/models/v1/models_pb"
1212import { clone , create } from "@bufbuild/protobuf"
13- import { ArrowRight , ArrowUp , Check , Undo2 } from "lucide-react"
14- import type React from "react"
13+ import { ArrowRight , ArrowUp , Check , Plus , Undo2 } from "lucide-react"
14+ import React from "react"
1515import { toast } from "sonner"
1616
17+ import { ManualCompletionDialog } from "./manual-completion-dialog"
18+
1719interface P extends React . ComponentProps < typeof Button > {
1820 options ?: Completion_ButtonOptions
1921 preview ?: boolean
@@ -23,32 +25,33 @@ const defaultOptions = create(Completion_ButtonOptionsSchema, {
2325 kind : { case : "complete" , value : true } ,
2426} )
2527
26- const applyButton = ( completion : Completion , options : Completion_ButtonOptions ) => {
28+ const applyButton = (
29+ completion : Completion ,
30+ options : Completion_ButtonOptions ,
31+ manualValue ?: number ,
32+ ) => {
2733 switch ( options . kind . case ) {
2834 case "delta" :
29- completion . count += options . kind . value
35+ completion . count = manualValue ?? options . kind . value
3036 return
3137 case "percentage" :
32- completion . count += Math . ceil ( ( options . kind . value / 100 ) * completion . target )
38+ completion . count += Math . ceil (
39+ ( ( manualValue ?? options . kind . value ) / 100 ) * completion . target ,
40+ )
3341 return
3442 case "complete" :
3543 completion . count = completion . target
3644 return
3745 case "set" :
38- completion . count = options . kind . value
46+ completion . count = manualValue ?? options . kind . value
3947 return
4048 }
4149}
4250
43- export const CompletionButton : React . FC < P > = ( {
44- options = defaultOptions ,
45- children,
46- preview,
47- ...rest
48- } ) => {
51+ export const CompletionButton : React . FC < P > = ( { options = defaultOptions , preview, ...rest } ) => {
4952 const { habit, color, update } = useHabitContext ( )
5053
51- const handleClick = ( ) => {
54+ const handleClick = ( manualValue ?: number ) => {
5255 if ( preview ) return
5356
5457 const next = clone ( HabitSchema , habit )
@@ -60,7 +63,7 @@ export const CompletionButton: React.FC<P> = ({
6063 const completion =
6164 next . completions [ date ] ?? create ( CompletionSchema , { target : next . dailyTarget } )
6265
63- applyButton ( completion , options )
66+ applyButton ( completion , options , manualValue )
6467 next . completions [ date ] = completion
6568 }
6669
@@ -85,30 +88,78 @@ export const CompletionButton: React.FC<P> = ({
8588 < span > Reset</ span >
8689 </ >
8790 )
88- } else if ( kind . case === "delta" ) {
89- className = cn ( className , "gap-1" )
91+ } else if ( kind . case === "complete" ) {
9092 content = (
9193 < >
92- < ArrowUp />
93- < span > + { kind . value } </ span >
94+ < Check />
95+ Done
9496 </ >
9597 )
96- } else if ( kind . case === "percentage" ) {
98+ } else if ( kind . case === "delta" ) {
99+ if ( kind . value === 0 ) {
100+ return (
101+ < ManualCompletionDialog onSubmit = { handleClick } >
102+ < Button
103+ variant = "ghost"
104+ { ...rest }
105+ className = { className }
106+ disabled = { rest . disabled || update . isPending }
107+ >
108+ < Plus />
109+ Add
110+ </ Button >
111+ </ ManualCompletionDialog >
112+ )
113+ }
114+
97115 className = cn ( className , "gap-1" )
98116 content = (
99117 < >
100- < ArrowUp />
101- < span > + { kind . value } % </ span >
118+ < Plus />
119+ < span > { kind . value } </ span >
102120 </ >
103121 )
104- } else if ( kind . case === "complete" ) {
122+ } else if ( kind . case === "percentage" ) {
123+ className = cn ( className , "gap-1" )
105124 content = (
106125 < >
107- < Check />
108- Done
126+ < Plus />
127+ < span > { kind . value } % </ span >
109128 </ >
110129 )
130+
131+ if ( kind . value === 0 ) {
132+ return (
133+ < ManualCompletionDialog onSubmit = { handleClick } >
134+ < Button
135+ variant = "ghost"
136+ { ...rest }
137+ className = { className }
138+ disabled = { rest . disabled || update . isPending }
139+ >
140+ < Plus />
141+ Add %
142+ </ Button >
143+ </ ManualCompletionDialog >
144+ )
145+ }
111146 } else if ( kind . case === "set" ) {
147+ if ( kind . value === 0 ) {
148+ return (
149+ < ManualCompletionDialog onSubmit = { handleClick } >
150+ < Button
151+ variant = "ghost"
152+ { ...rest }
153+ className = { className }
154+ disabled = { rest . disabled || update . isPending }
155+ >
156+ < ArrowRight />
157+ Set
158+ </ Button >
159+ </ ManualCompletionDialog >
160+ )
161+ }
162+
112163 content = (
113164 < >
114165 < ArrowRight />
@@ -123,9 +174,9 @@ export const CompletionButton: React.FC<P> = ({
123174 { ...rest }
124175 className = { className }
125176 disabled = { rest . disabled || update . isPending }
126- onClick = { handleClick }
177+ onClick = { ( ) => handleClick ( ) }
127178 >
128- { children ?? content }
179+ { content }
129180 </ Button >
130181 )
131182}
0 commit comments