@@ -2,13 +2,14 @@ import React, { useState, useEffect, useRef } from 'react';
22
33const Stopwatch = ( ) => {
44 const [ time , setTime ] = useState ( 0 ) ;
5+ const [ laps , setLaps ] = useState ( [ ] ) ;
56 const [ isRunning , setIsRunning ] = useState ( false ) ;
67 const intervalRef = useRef ( null ) ;
78
89 useEffect ( ( ) => {
910 if ( isRunning ) {
1011 intervalRef . current = setInterval ( ( ) => {
11- setTime ( prevTime => prevTime + 10 ) ; // Update every 10ms for smoother display
12+ setTime ( prevTime => prevTime + 10 ) ;
1213 } , 10 ) ;
1314 } else {
1415 clearInterval ( intervalRef . current ) ;
@@ -20,33 +21,36 @@ const Stopwatch = () => {
2021 const handleStart = ( ) => {
2122 setIsRunning ( true ) ;
2223 } ;
23-
2424 const handleStop = ( ) => {
2525 setIsRunning ( false ) ;
2626 } ;
27-
2827 const handleReset = ( ) => {
2928 setIsRunning ( false ) ;
3029 setTime ( 0 ) ;
30+ setLaps ( [ ] ) ;
31+ } ;
32+ const handleLap = ( ) => {
33+ setLaps ( prevLaps => [ ...prevLaps , time ] ) ;
3134 } ;
3235
33- const formatTime = ( ) => {
34- const milliseconds = `0${ ( time % 1000 ) / 10 } ` . slice ( - 2 ) ;
35- const seconds = `0${ Math . floor ( time / 1000 ) % 60 } ` . slice ( - 2 ) ;
36- const minutes = `0${ Math . floor ( time / 60000 ) % 60 } ` . slice ( - 2 ) ;
37- const hours = `0${ Math . floor ( time / 3600000 ) } ` . slice ( - 2 ) ;
36+ const formatTime = ( timeValue ) => {
37+ const milliseconds = `0${ ( timeValue % 1000 ) / 10 } ` . slice ( - 2 ) ;
38+ const seconds = `0${ Math . floor ( timeValue / 1000 ) % 60 } ` . slice ( - 2 ) ;
39+ const minutes = `0${ Math . floor ( timeValue / 60000 ) % 60 } ` . slice ( - 2 ) ;
40+ const hours = `0${ Math . floor ( timeValue / 3600000 ) } ` . slice ( - 2 ) ;
3841 return `${ hours } :${ minutes } :${ seconds } .${ milliseconds } ` ;
3942 } ;
4043
4144 const buttonStyle = "w-24 px-4 py-2 text-lg font-arvo rounded-md border transition-colors duration-300 ease-in-out" ;
4245 const activeButtonStyle = "bg-green-800/50 border-green-700 text-white hover:bg-green-700/50" ;
4346 const inactiveButtonStyle = "bg-gray-700/50 border-gray-600 text-gray-300 hover:bg-gray-600/50" ;
4447 const stopButtonStyle = "bg-red-800/50 border-red-700 text-white hover:bg-red-700/50" ;
48+ const lapButtonStyle = "bg-blue-800/50 border-blue-700 text-white hover:bg-blue-700/50 disabled:opacity-50 disabled:cursor-not-allowed" ;
4549
4650 return (
47- < div className = "flex flex-col items-center gap-6" >
51+ < div className = "flex flex-col items-center gap-6 w-full max-w-md " >
4852 < div className = "font-mono text-5xl text-gray-100 p-4 rounded-lg bg-gray-900/50 w-full text-center" >
49- { formatTime ( ) }
53+ { formatTime ( time ) }
5054 </ div >
5155 < div className = "flex gap-4" >
5256 { ! isRunning ? (
@@ -58,10 +62,26 @@ const Stopwatch = () => {
5862 Stop
5963 </ button >
6064 ) }
65+ < button onClick = { handleLap } className = { `${ buttonStyle } ${ lapButtonStyle } ` } disabled = { ! isRunning } >
66+ Lap
67+ </ button >
6168 < button onClick = { handleReset } className = { `${ buttonStyle } ${ inactiveButtonStyle } ` } >
6269 Reset
6370 </ button >
6471 </ div >
72+ { laps . length > 0 && (
73+ < div className = "w-full mt-4 p-4 rounded-lg bg-gray-900/50" >
74+ < h3 className = "text-xl font-arvo text-center text-gray-200 mb-2" > Laps</ h3 >
75+ < ul className = "space-y-2 max-h-60 overflow-y-auto" >
76+ { laps . map ( ( lapTime , index ) => (
77+ < li key = { index } className = "flex justify-between font-mono text-gray-300 p-2 bg-gray-800/50 rounded" >
78+ < span > Lap { index + 1 } </ span >
79+ < span > { formatTime ( lapTime ) } </ span >
80+ </ li >
81+ ) ) . reverse ( ) }
82+ </ ul >
83+ </ div >
84+ ) }
6585 </ div >
6686 ) ;
6787} ;
0 commit comments