Countdown timer

DEMO

00:05

CountdownTimer.jsx

const Timer = () => {
  const [isPlaying, setIsPlaying] = useState(false);
  const [isEditing, setIsEditing] = useState(false);
  const [totalTime, setTotalTime] = useState(5);
  const [timeRemaining, setTimeRemaining] = useState(totalTime);
  const hours = Math.floor(timeRemaining / 3600);
  const formattedTime = new Date(timeRemaining * 1000)
    .toISOString()
    .substring(hours > 0 ? 11 : 14, 19);

  const timer = useRef();
  useEffect(() => {
    if (isPlaying) {
      timer.current = setInterval(() => {
        setTimeRemaining((timeRemaining) => timeRemaining - 1);
      }, 1000);
      return () => {
        clearInterval(timer.current);
      };
    }
  }, [isPlaying]);

  useEffect(() => {
    if (timeRemaining === 0) {
      setIsPlaying(false);
      setTimeout(() => setTimeRemaining(totalTime), 1000);
    }
  }, [timeRemaining]);

  useEffect(() => {
    setTimeRemaining(totalTime);
  }, [totalTime]);

  return (
    <>
      <CircleProgress progress={timeRemaining/totalTime * 100}/>
      {!isEditing ? (
        <Time
          onClick={() => {
            setIsEditing(true);
            setIsPlaying(false);
          }}
        >
          {formattedTime}
        </Time>
      ) : (
        <EditTimeForm
          onSubmit={(e) => {
            e.preventDefault();
            setIsPlaying(true);
            setIsEditing(false);
          }}
        >
          <EditTimeInput
            type="number"
            onChange={(e) => {
              let val = e.target.value;
              if (val === "") setTotalTime("");
              if (isNaN(val)) return;
              setTotalTime(val * 60);
            }}
          />
          minutes
        </EditTimeForm>
      )}
      <PlayBtn>
        {isPlaying ? (
          <BsPauseCircleFill
            onClick={() => {
              setIsPlaying(false);
            }}
            size="2em"
            color="white"
          />
        ) : (
          <BsPlayCircleFill
            onClick={() => {
              setIsPlaying(true);
              setIsEditing(false);
            }}
            size="2em"
            color="white"
          />
        )}
      </PlayBtn>
    </>
  );
}; 

Note: Code snippets do not include styling details unless they are the focus of the exercise.

Copyright © 2022 Explore React