@@ -57,19 +57,51 @@ export default function Countdown({
5757 const hourRef = useRef ( null ) ;
5858 const minRef = useRef ( null ) ;
5959
60- const remainingHours = moment . duration ( remaining ) . hours ( ) ;
61- const remainingMinutes = moment . duration ( remaining ) . minutes ( ) ;
62- const remainingSeconds = moment . duration ( remaining ) . seconds ( ) ;
60+ const remainingDuration = moment . duration ( remaining ) ;
61+ const remainingHours = Math . floor ( remainingDuration . asHours ( ) ) ;
62+ const remainingMinutes = remainingDuration . minutes ( ) ;
63+ const remainingSeconds = remainingDuration . seconds ( ) ;
6364
6465 const remainingHoursDisplay = remainingHours . toString ( ) . padStart ( 2 , '0' ) ;
6566 const remainingMinutesDisplay = remainingMinutes . toString ( ) . padStart ( 2 , '0' ) ;
6667 const remainingSecondsDisplay = remainingSeconds . toString ( ) . padStart ( 2 , '0' ) ;
6768
69+ const goalDuration = moment . duration ( goal ) ;
70+ const goalHoursDisplay = Math . floor ( goalDuration . asHours ( ) ) . toString ( ) ;
71+ const goalMinutesDisplay = goalDuration
72+ . minutes ( )
73+ . toString ( )
74+ . padStart ( 2 , '0' ) ;
75+ const goalSecondsDisplay = goalDuration
76+ . seconds ( )
77+ . toString ( )
78+ . padStart ( 2 , '0' ) ;
79+
80+ const elapsedMs = Math . max ( goal - remaining , 0 ) ;
81+ const elapsedDuration = moment . duration ( elapsedMs ) ;
82+ const elapsedHoursDisplay = Math . floor ( elapsedDuration . asHours ( ) ) . toString ( ) ;
83+ const elapsedMinutesDisplay = elapsedDuration
84+ . minutes ( )
85+ . toString ( )
86+ . padStart ( 2 , '0' ) ;
87+ const elapsedSecondsDisplay = elapsedDuration
88+ . seconds ( )
89+ . toString ( )
90+ . padStart ( 2 , '0' ) ;
91+
6892 const shouldDisplay = {
6993 hour : true ,
7094 minute : true ,
7195 } ;
7296
97+ const minGoalMs = MIN_MINS * 60 * 1000 ;
98+ const maxGoalMs = MAX_HOURS * 60 * 60 * 1000 ;
99+
100+ const canSubtract15 = goal - 15 * 60 * 1000 >= minGoalMs ;
101+ const canAdd15 = goal + 15 * 60 * 1000 <= maxGoalMs && checkBtnAvail ( 15 ) ;
102+ const canAdd30 = goal + 30 * 60 * 1000 <= maxGoalMs && checkBtnAvail ( 30 ) ;
103+ const canAdd60 = goal + 60 * 60 * 1000 <= maxGoalMs && checkBtnAvail ( 60 ) ;
104+
73105 const forceMinMax = ( event , ref ) => {
74106 const { value, min, max } = event . target ;
75107 const updatedValue = Math . max ( Number ( min ) , Math . min ( Number ( max ) , Number ( value ) ) ) ;
@@ -120,8 +152,8 @@ export default function Countdown({
120152 }
121153 } ;
122154
123- const handleInitialMinuteChange = amout => {
124- const newMin = initialMinutes + amout ;
155+ const handleInitialMinuteChange = amount => {
156+ const newMin = initialMinutes + amount ;
125157 switch ( true ) {
126158 case initialHours === 0 && newMin < MIN_MINS :
127159 toast . error ( `Timer cannot be set less than ${ MIN_MINS } minutes!` ) ;
@@ -150,15 +182,12 @@ export default function Countdown({
150182 onClick = { toggleTimer }
151183 title = "close timer dropdown"
152184 />
185+
153186 < div className = { css . infoDisplay } >
154- < h4 > { `Goal: ${ moment . utc ( goal ) . format ( 'HH:mm:ss' ) } ` } </ h4 >
155- < h6 >
156- { `Elapsed: ${ moment
157- . utc ( goal )
158- . subtract ( remaining )
159- . format ( 'HH:mm:ss' ) } `}
160- </ h6 >
187+ < h4 > { `Goal: ${ goalHoursDisplay } :${ goalMinutesDisplay } :${ goalSecondsDisplay } ` } </ h4 >
188+ < h6 > { `Elapsed: ${ elapsedHoursDisplay } :${ elapsedMinutesDisplay } :${ elapsedSecondsDisplay } ` } </ h6 >
161189 </ div >
190+
162191 < div className = { css . countdownCircle } >
163192 < CircularProgressbarWithChildren
164193 value = { started ? ( moment . duration ( remaining ) . asMilliseconds ( ) / goal ) * 100 : 100 }
@@ -181,7 +210,9 @@ export default function Countdown({
181210 title = "Reset timer"
182211 />
183212 ) }
213+
184214 < span > Time Remaining</ span >
215+
185216 < div className = { css . remainingTime } >
186217 { shouldDisplay . hour && (
187218 < >
@@ -192,6 +223,7 @@ export default function Countdown({
192223 < div className = { css . timeColon } > :</ div >
193224 </ >
194225 ) }
226+
195227 { shouldDisplay . minute && (
196228 < >
197229 < div >
@@ -201,11 +233,13 @@ export default function Countdown({
201233 < div className = { css . timeColon } > :</ div >
202234 </ >
203235 ) }
236+
204237 < div >
205238 < div className = { css . timeDisplay } > { remainingSecondsDisplay } </ div >
206239 < div className = { css . label } > seconds</ div >
207240 </ div >
208241 </ div >
242+
209243 < div className = { css . operators } >
210244 { running ? (
211245 < button type = "button" onClick = { sendPause } aria-label = "Pause timer" >
@@ -228,6 +262,7 @@ export default function Countdown({
228262 />
229263 </ button >
230264 ) }
265+
231266 { started && (
232267 < button
233268 type = "button"
@@ -245,40 +280,48 @@ export default function Countdown({
245280 </ div >
246281 </ CircularProgressbarWithChildren >
247282 </ div >
283+
248284 < div className = { css . bottom } >
249285 { started ? (
250286 < div className = { cs ( css . addGrid , css . transitionColor ) } >
251287 < button
252288 size = "sm"
253289 type = "button"
254290 aria-label = "remove 15 minutes"
255- onClick = { ( ) => handleSubtractButton ( 15 ) }
291+ onClick = { ( ) => canSubtract15 && handleSubtractButton ( 15 ) }
292+ disabled = { ! canSubtract15 }
256293 >
257- < span className = { cs ( css . btn , checkBtnAvail ( - 15 ) ? '' : css . btnDisabled ) } > -15 m</ span >
294+ < span className = { cs ( css . btn , canSubtract15 ? '' : css . btnDisabled ) } > -15 m</ span >
258295 </ button >
296+
259297 < button
260298 size = "sm"
261299 type = "button"
262300 aria-label = "add 15 minutes"
263- onClick = { ( ) => handleAddButton ( 15 ) }
301+ onClick = { ( ) => canAdd15 && handleAddButton ( 15 ) }
302+ disabled = { ! canAdd15 }
264303 >
265- < span className = { cs ( css . btn , checkBtnAvail ( 15 ) ? '' : css . btnDisabled ) } > +15 m</ span >
304+ < span className = { cs ( css . btn , canAdd15 ? '' : css . btnDisabled ) } > +15 m</ span >
266305 </ button >
306+
267307 < button
268308 size = "sm"
269309 type = "button"
270310 aria-label = "add 30 minutes"
271- onClick = { ( ) => handleAddButton ( 30 ) }
311+ onClick = { ( ) => canAdd30 && handleAddButton ( 30 ) }
312+ disabled = { ! canAdd30 }
272313 >
273- < span className = { cs ( css . btn , checkBtnAvail ( 30 ) ? '' : css . btnDisabled ) } > +30 m</ span >
314+ < span className = { cs ( css . btn , canAdd30 ? '' : css . btnDisabled ) } > +30 m</ span >
274315 </ button >
316+
275317 < button
276318 size = "sm"
277319 type = "button"
278320 aria-label = "add 1 hour"
279- onClick = { ( ) => handleAddButton ( 60 ) }
321+ onClick = { ( ) => canAdd60 && handleAddButton ( 60 ) }
322+ disabled = { ! canAdd60 }
280323 >
281- < span className = { cs ( css . btn , checkBtnAvail ( 60 ) ? '' : css . btnDisabled ) } > +1 h</ span >
324+ < span className = { cs ( css . btn , canAdd60 ? '' : css . btnDisabled ) } > +1 h</ span >
282325 </ button >
283326 </ div >
284327 ) : (
@@ -292,6 +335,7 @@ export default function Countdown({
292335 onClick = { ( ) => handleInitialHourChange ( 1 ) }
293336 />
294337 ) }
338+
295339 < Input
296340 type = "number"
297341 className = { editing ? css . editing : '' }
@@ -302,14 +346,17 @@ export default function Countdown({
302346 disabled = { ! editing }
303347 innerRef = { hourRef }
304348 />
349+
305350 { editing && (
306351 < FaAngleDown
307352 className = { cs ( css . transitionColor , css . down ) }
308353 onClick = { ( ) => handleInitialHourChange ( - 1 ) }
309354 />
310355 ) }
311356 </ div >
357+
312358 < span className = { css . timeColon } > :</ span >
359+
313360 < div className = { css . numberWrapper } >
314361 { editing && (
315362 < FaAngleUp
@@ -319,6 +366,7 @@ export default function Countdown({
319366 }
320367 />
321368 ) }
369+
322370 < Input
323371 type = "number"
324372 min = { 0 }
@@ -330,6 +378,7 @@ export default function Countdown({
330378 disabled = { ! editing }
331379 innerRef = { minRef }
332380 />
381+
333382 { editing && (
334383 < FaAngleDown
335384 className = { cs ( css . transitionColor , css . down ) }
@@ -341,6 +390,7 @@ export default function Countdown({
341390 />
342391 ) }
343392 </ div >
393+
344394 { editing ? (
345395 < FaSave
346396 className = { cs ( css . transitionColor , css . goalBtn ) }
0 commit comments