[Linear & Circular] Dynamic Progress Bar with Timer in React


import { Box, CircularProgress, Typography } from “@mui/material”;

import moment from “moment”;

import { useState, useRef, useEffect } from “react”;

const CircularProgressBar = (props) => {

const initialTime = 10; // in seconds

const [timeLeft, setTimeLeft] = useState(initialTime);

const [progressBarPercent, setProgressBarPercent] = useState(0);

const timerId = useRef();

useEffect(() => {

if (initialTime) {

timerId.current = window.setInterval(() => {

setTimeLeft((prevProgress) => prevProgress 1);

}, 1000);

return () => {

clearInterval(timerId.current);

};

}

}, []);

useEffect(() => {

if (initialTime) {

if (progressBarPercent < 100) {

let updateProgressPercent = Math.round(

((initialTime (timeLeft 1)) / initialTime) * 100

);

setProgressBarPercent(updateProgressPercent);

}

if (timeLeft === 0 && timerId.current) {

clearInterval(timerId.current);

return;

}

}

}, [timeLeft]);

return (

<Box

sx={{

display: “flex”,

alignItems: “center”,

justifyContent: “center”,

boxShadow: “0px 2px 10px rgba(0, 0, 0, 0.15)”,

width: “100%”,

padding: “20px”

}}

>

<Box sx={{ position: “relative”, display: “inline-flex” }}>

<CircularProgress

variant=“determinate”

size=“20rem”

value={progressBarPercent}

sx={{

color: progressBarPercent > 90 ? `red` : “blue”

}}

/>

<Box

sx={{

top: 0,

left: 0,

bottom: 0,

right: 0,

position: “absolute”,

display: “flex”,

alignItems: “center”,

justifyContent: “center”

}}

>

<Typography sx={{ fontWeight: 400, fontSize: “25px” }}>

Time left:

</Typography>

<Typography sx={{ fontWeight: 700, fontSize: “25px”, ml: 1 }}>

{moment

.utc(1000 * timeLeft)

.format(

`${timeLeft > 3600 ? “HH[h]:mm[m]:ss[s]” : “mm[m]:ss[s]”} `

)}

</Typography>

</Box>

</Box>

</Box>

);

};

export default CircularProgressBar;



Technology

Another Tech Information

Comments are closed, but trackbacks and pingbacks are open.