Repository: Sunbird-ALL/all-learner-ai-app
Pull request #337: Fixed audio issues
Author: login: Ayansaha20
Created: 2025-04-21T07:41:40Z | Merged: 2025-04-22T05:30:42Z



<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Bug Fixes**
  - Ensured ongoing audio or speech playback is properly stopped and reset before advancing in various practice activities.
  - Prevented potential errors by safely handling undefined task data.
  - Improved UI layout and alignment in the zoom modal.
  - Adjusted audio icon size for consistency.
  - Set a fixed height for confetti animations to enhance visual consistency.

- **New Features**
  - Added functionality to reset recorded audio when starting a new recording in practice activities.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/src/components/Layouts.jsx/MainLayout.jsx b/src/components/Layouts.jsx/MainLayout.jsx
index 623e83e0..b51e34c2 100644
--- a/src/components/Layouts.jsx/MainLayout.jsx
+++ b/src/components/Layouts.jsx/MainLayout.jsx
@@ -800,519 +800,533 @@ const MainLayout = (props) => {
                 </Box>
               </Card>
             )}
-          {((isShowCase && !startShowCase) || gameOverData) && (
-            <Card
-              sx={{
-                width: "85vw",
-                minHeight: "80vh",
-                borderRadius: "20px",
-                display: "flex",
-                flexDirection: "column",
-                justifyContent: "space-between",
-                backgroundImage: `url(${cardBackground || textureImage})`,
-                backgroundSize: "contain",
-                backgroundRepeat: "round",
-                boxShadow: "0px 4px 20px -1px rgba(0, 0, 0, 0.00)",
-                backdropFilter: "blur(25px)",
-                mt: "50px",
-              }}
-            >
-              <Box>{shake && <Confetti width={width} height={"602px"} />}</Box>
-              <CardContent
+          {((isShowCase && !startShowCase) || gameOverData) &&
+            !allCompleted && (
+              <Card
                 sx={{
-                  width: "82vw",
-                  minHeight: "100%",
-                  opacity: disableScreen ? 0.25 : 1,
-                  pointerEvents: disableScreen ? "none" : "initial",
+                  width: "85vw",
+                  minHeight: "80vh",
+                  borderRadius: "20px",
+                  display: "flex",
+                  flexDirection: "column",
+                  justifyContent: "space-between",
+                  backgroundImage: `url(${cardBackground || textureImage})`,
+                  backgroundSize: "contain",
+                  backgroundRepeat: "round",
+                  boxShadow: "0px 4px 20px -1px rgba(0, 0, 0, 0.00)",
+                  backdropFilter: "blur(25px)",
+                  mt: "50px",
                 }}
               >
-                {isShowCase && !startShowCase && !gameOverData && (
-                  <>
-                    <Typography
-                      className="successHeader"
-                      sx={{
-                        textAlign: "center",
-                      }}
-                    >
-                      Hurray!!!
-                    </Typography>
-                    <Typography
-                      sx={{
-                        mb: 1,
-                        mt: 1,
-                        textAlign: "center",
-                      }}
-                    >
-                      <span
-                        style={{
-                          color: "#50507D",
-                          fontWeight: 600,
-                          fontSize: "20px",
-                          lineHeight: "37px",
-                          letterSpacing: "2%",
-                          fontFamily: "Quicksand",
+                <Box>
+                  {shake && <Confetti width={width} height={"602px"} />}
+                </Box>
+                <CardContent
+                  sx={{
+                    width: "82vw",
+                    minHeight: "100%",
+                    opacity: disableScreen ? 0.25 : 1,
+                    pointerEvents: disableScreen ? "none" : "initial",
+                  }}
+                >
+                  {isShowCase && !startShowCase && !gameOverData && (
+                    <>
+                      <Typography
+                        className="successHeader"
+                        sx={{
+                          textAlign: "center",
                         }}
                       >
-                        {"Ready for Challenge?"}
-                      </span>
-                    </Typography>
-                  </>
-                )}
-                {gameOverData && (
-                  <>
-                    <Box
-                      sx={{
-                        position: "absolute",
-                        top: "-120px",
-                        left: "-70px",
-                      }}
-                    >
-                      {!gameOverData?.userWon && (
-                        <img
-                          src={clouds}
-                          alt="clouds"
-                          style={{ zIndex: -999 }}
-                        />
-                      )}
-                    </Box>
-                    <Box
-                      sx={{
-                        display: "flex",
-                        justifyContent: "center",
-                        position: "relative",
-                        zIndex: "100",
-                      }}
-                    >
-                      {gameOverData?.userWon ? (
-                        <img
-                          src={gameWon}
-                          alt="gameWon"
-                          style={{ zIndex: 9999, height: 340 }}
-                        />
-                      ) : (
-                        <Stack
-                          justifyContent="center"
-                          alignItems="center"
-                          direction={"row"}
-                          zIndex={100}
+                        Hurray!!!
+                      </Typography>
+                      <Typography
+                        sx={{
+                          mb: 1,
+                          mt: 1,
+                          textAlign: "center",
+                        }}
+                      >
+                        <span
+                          style={{
+                            color: "#50507D",
+                            fontWeight: 600,
+                            fontSize: "20px",
+                            lineHeight: "37px",
+                            letterSpacing: "2%",
+                            fontFamily: "Quicksand",
+                          }}
                         >
-                          <Stack justifyContent="center" alignItems="center">
-                            <img
-                              src={`https://raw.githubusercontent.com/Sunbird-ALL/all-learner-ai-app/refs/heads/all-1.3/src/assets/images/gameLost.svg`}
-                              alt="gameLost"
-                              style={{ height: 340 }}
-                            />
-                            <Typography
-                              sx={{ mb: 1, mt: 1, textAlign: "center" }}
-                            >
-                              {!props.pageName === "m8" && (
-                                <span
-                                  style={{
-                                    fontWeight: 600,
-                                    fontSize: "24px",
-                                    lineHeight: "1.5",
-                                    letterSpacing: "1px",
-                                    fontFamily: "Quicksand",
-                                    backgroundColor: "rgb(237, 134, 0)",
-                                    padding: "6px 12px",
-                                    color: "#fff",
-                                    borderRadius: "20px",
-                                    boxShadow: "0px 2px 4px rgba(0, 0, 0, 0.1)",
-                                    textShadow:
-                                      "1px 1px 2px rgba(0, 0, 0, 0.5)",
-                                  }}
-                                >
-                                  {percentage <= 0 ? 0 : percentage}/100
-                                </span>
-                              )}
-                              <br />
-
-                              {!fluency ? (
-                                <Typography textAlign="center" sx={{ mt: 2 }}>
-                                  Good try! Need more speed.
-                                </Typography>
-                              ) : (
-                                <Typography textAlign="center" sx={{ mt: 2 }}>
-                                  You need{" "}
-                                  <span style={{ fontWeight: "bold" }}>
-                                    {Math.abs(70 - percentage)}
-                                  </span>{" "}
-                                  more.
-                                </Typography>
-                              )}
-                            </Typography>
-                          </Stack>
-                          {/* second stack below*/}
+                          {"Ready for Challenge?"}
+                        </span>
+                      </Typography>
+                    </>
+                  )}
+                  {gameOverData && (
+                    <>
+                      <Box
+                        sx={{
+                          position: "absolute",
+                          top: "-120px",
+                          left: "-70px",
+                        }}
+                      >
+                        {!gameOverData?.userWon && (
+                          <img
+                            src={clouds}
+                            alt="clouds"
+                            style={{ zIndex: -999 }}
+                          />
+                        )}
+                      </Box>
+                      <Box
+                        sx={{
+                          display: "flex",
+                          justifyContent: "center",
+                          position: "relative",
+                          zIndex: "100",
+                        }}
+                      >
+                        {gameOverData?.userWon ? (
+                          <img
+                            src={gameWon}
+                            alt="gameWon"
+                            style={{ zIndex: 9999, height: 340 }}
+                          />
+                        ) : (
                           <Stack
-                            direction={"column"}
+                            justifyContent="center"
                             alignItems="center"
-                            spacing={2}
-                            marginLeft={"10px"}
+                            direction={"row"}
+                            zIndex={100}
                           >
+                            <Stack justifyContent="center" alignItems="center">
+                              <img
+                                src={`https://raw.githubusercontent.com/Sunbird-ALL/all-learner-ai-app/refs/heads/all-1.3/src/assets/images/gameLost.svg`}
+                                alt="gameLost"
+                                style={{ height: 340 }}
+                              />
+                              <Typography
+                                sx={{ mb: 1, mt: 1, textAlign: "center" }}
+                              >
+                                {!props.pageName === "m8" && (
+                                  <span
+                                    style={{
+                                      fontWeight: 600,
+                                      fontSize: "24px",
+                                      lineHeight: "1.5",
+                                      letterSpacing: "1px",
+                                      fontFamily: "Quicksand",
+                                      backgroundColor: "rgb(237, 134, 0)",
+                                      padding: "6px 12px",
+                                      color: "#fff",
+                                      borderRadius: "20px",
+                                      boxShadow:
+                                        "0px 2px 4px rgba(0, 0, 0, 0.1)",
+                                      textShadow:
+                                        "1px 1px 2px rgba(0, 0, 0, 0.5)",
+                                    }}
+                                  >
+                                    {percentage <= 0 ? 0 : percentage}/100
+                                  </span>
+                                )}
+                                <br />
+
+                                {!fluency ? (
+                                  <Typography textAlign="center" sx={{ mt: 2 }}>
+                                    Good try! Need more speed.
+                                  </Typography>
+                                ) : (
+                                  <Typography textAlign="center" sx={{ mt: 2 }}>
+                                    You need{" "}
+                                    <span style={{ fontWeight: "bold" }}>
+                                      {Math.abs(70 - percentage)}
+                                    </span>{" "}
+                                    more.
+                                  </Typography>
+                                )}
+                              </Typography>
+                            </Stack>
+                            {/* second stack below*/}
                             <Stack
-                              sx={{
-                                boxShadow: "rgba(0, 0, 0, 0.24) 0px 3px 8px;",
-                                paddingY: "49px",
-                                paddingX: "30px",
-                                borderRadius: "13px",
-                                marginLeft: "80px",
-                                bgcolor: "#FFFFFF",
-                                zIndex: 100,
-                              }}
-                              direction={"row"}
+                              direction={"column"}
+                              alignItems="center"
+                              spacing={2}
+                              marginLeft={"10px"}
                             >
                               <Stack
                                 sx={{
-                                  paddingRight:
-                                    (props.pageName === "wordsorimage" ||
-                                      props.pageName === "m5") &&
-                                    !fluency
-                                      ? "20px"
-                                      : "0px",
-                                  borderRight:
-                                    (props.pageName === "wordsorimage" ||
-                                      props.pageName === "m5") &&
-                                    !fluency
-                                      ? "1px dashed grey"
-                                      : "none",
+                                  boxShadow: "rgba(0, 0, 0, 0.24) 0px 3px 8px;",
+                                  paddingY: "49px",
+                                  paddingX: "30px",
+                                  borderRadius: "13px",
+                                  marginLeft: "80px",
+                                  bgcolor: "#FFFFFF",
+                                  zIndex: 100,
                                 }}
+                                direction={"row"}
                               >
-                                {(props.pageName === "wordsorimage" ||
-                                  props.pageName === "m5") &&
-                                  storedData?.map((elem, index) => (
-                                    <Stack
-                                      key={index}
-                                      justifyContent={"start"}
-                                      alignItems={"center"}
-                                      direction={"row"}
-                                      mt={index > 0 ? "25px" : 0}
-                                    >
-                                      <Box
-                                        sx={{
-                                          marginLeft: "35px",
-                                          marginRight: "5px",
-                                        }}
-                                      >
-                                        {elem?.audioUrl ? (
-                                          <button
-                                            onClick={() =>
-                                              handleAudioPlay(index)
-                                            }
-                                            style={{
-                                              height: "30px",
-                                              cursor: "pointer",
-                                              background: "none",
-                                              border: "none",
-                                              padding: "0",
-                                            }}
-                                            aria-label={
-                                              audioPlaying === index
-                                                ? "Pause audio"
-                                                : "Play audio"
-                                            }
-                                          >
-                                            <img
-                                              src={
-                                                audioPlaying === index
-                                                  ? pauseButton
-                                                  : playButton
-                                              }
-                                              alt={
-                                                audioPlaying === index
-                                                  ? "Pause"
-                                                  : "Play"
-                                              }
-                                              style={{ height: "30px" }}
-                                            />
-                                          </button>
-                                        ) : (
-                                          <Box></Box>
-                                        )}
-                                        <audio
-                                          ref={(el) =>
-                                            (audioRefs.current[index] = el)
-                                          }
-                                          src={elem?.audioUrl}
-                                        />
-                                      </Box>
-
-                                      {elem?.correctAnswer === false ? (
-                                        <img
-                                          src="https://raw.githubusercontent.com/Sunbird-ALL/all-learner-ai-app/refs/heads/all-1.2-tn-dev/src/assets/wrong.svg"
-                                          alt="wrongImage"
-                                        />
-                                      ) : (
-                                        <img
-                                          src="https://raw.githubusercontent.com/Sunbird-ALL/all-learner-ai-app/refs/heads/all-1.2-tn-dev/src/assets/correct.svg"
-                                          alt="correctImage"
-                                        />
-                                      )}
-                                      <span
-                                        style={{
-                                          marginLeft: "8px",
-                                          color: "#1E2937",
-                                          fontWeight: 700,
-                                          lineHeight: "30px",
-                                          fontSize: "15px",
-                                          fontFamily: "Quicksand",
-                                          minWidth: "100px",
-                                        }}
-                                      >
-                                        {elem.selectedAnswer || "Binocular"}
-                                      </span>
-                                    </Stack>
-                                  ))}
-                              </Stack>
-                              {(fluency ||
-                                [10, 11, 12, 13, 14, 15].includes(LEVEL)) && (
                                 <Stack
                                   sx={{
-                                    paddingLeft:
+                                    paddingRight:
                                       (props.pageName === "wordsorimage" ||
                                         props.pageName === "m5") &&
                                       !fluency
                                         ? "20px"
                                         : "0px",
+                                    borderRight:
+                                      (props.pageName === "wordsorimage" ||
+                                        props.pageName === "m5") &&
+                                      !fluency
+                                        ? "1px dashed grey"
+                                        : "none",
                                   }}
-                                  justifyContent={"center"}
-                                  alignItems={"center"}
                                 >
-                                  <img
-                                    src="https://raw.githubusercontent.com/Sunbird-ALL/all-learner-ai-app/refs/heads/all-1.2-tn-dev/src/assets/turtle.svg"
-                                    alt="turtleImage"
-                                  />
-                                  <span
-                                    style={{
-                                      marginTop: "12px",
-                                      color: "#1E2937",
-                                      fontWeight: 700,
-                                      lineHeight: "25px",
-                                      fontSize: "20px",
-                                      fontFamily: "Quicksand",
+                                  {(props.pageName === "wordsorimage" ||
+                                    props.pageName === "m5") &&
+                                    storedData?.map((elem, index) => (
+                                      <Stack
+                                        key={index}
+                                        justifyContent={"start"}
+                                        alignItems={"center"}
+                                        direction={"row"}
+                                        mt={index > 0 ? "25px" : 0}
+                                      >
+                                        <Box
+                                          sx={{
+                                            marginLeft: "35px",
+                                            marginRight: "5px",
+                                          }}
+                                        >
+                                          {elem?.audioUrl ? (
+                                            <button
+                                              onClick={() =>
+                                                handleAudioPlay(index)
+                                              }
+                                              style={{
+                                                height: "30px",
+                                                cursor: "pointer",
+                                                background: "none",
+                                                border: "none",
+                                                padding: "0",
+                                              }}
+                                              aria-label={
+                                                audioPlaying === index
+                                                  ? "Pause audio"
+                                                  : "Play audio"
+                                              }
+                                            >
+                                              <img
+                                                src={
+                                                  audioPlaying === index
+                                                    ? pauseButton
+                                                    : playButton
+                                                }
+                                                alt={
+                                                  audioPlaying === index
+                                                    ? "Pause"
+                                                    : "Play"
+                                                }
+                                                style={{ height: "30px" }}
+                                              />
+                                            </button>
+                                          ) : (
+                                            <Box></Box>
+                                          )}
+                                          <audio
+                                            ref={(el) =>
+                                              (audioRefs.current[index] = el)
+                                            }
+                                            src={elem?.audioUrl}
+                                          />
+                                        </Box>
+
+                                        {elem?.correctAnswer === false ? (
+                                          <img
+                                            src="https://raw.githubusercontent.com/Sunbird-ALL/all-learner-ai-app/refs/heads/all-1.2-tn-dev/src/assets/wrong.svg"
+                                            alt="wrongImage"
+                                          />
+                                        ) : (
+                                          <img
+                                            src="https://raw.githubusercontent.com/Sunbird-ALL/all-learner-ai-app/refs/heads/all-1.2-tn-dev/src/assets/correct.svg"
+                                            alt="correctImage"
+                                          />
+                                        )}
+                                        <span
+                                          style={{
+                                            marginLeft: "8px",
+                                            color: "#1E2937",
+                                            fontWeight: 700,
+                                            lineHeight: "30px",
+                                            fontSize: "15px",
+                                            fontFamily: "Quicksand",
+                                            minWidth: "100px",
+                                          }}
+                                        >
+                                          {elem.selectedAnswer || "Binocular"}
+                                        </span>
+                                      </Stack>
+                                    ))}
+                                </Stack>
+                                {(fluency ||
+                                  [10, 11, 12, 13, 14, 15].includes(LEVEL)) && (
+                                  <Stack
+                                    sx={{
+                                      paddingLeft:
+                                        (props.pageName === "wordsorimage" ||
+                                          props.pageName === "m5") &&
+                                        !fluency
+                                          ? "20px"
+                                          : "0px",
                                     }}
+                                    justifyContent={"center"}
+                                    alignItems={"center"}
                                   >
-                                    {"Oops, a bit slow!"}
-                                  </span>
-                                </Stack>
-                              )}
-                            </Stack>
-                            <Stack
-                              direction="row"
-                              alignItems="center"
-                              spacing={2}
-                              sx={{
-                                backgroundColor: "#F8EAD2",
-                                border: "2px solid yellow",
-                                borderRadius: "40px",
-                                padding: "10px 20px",
-                                //maxWidth: "100%",
-                              }}
-                            >
-                              <img
-                                src={Assets.starNewImg}
-                                alt="Star"
-                                style={{
-                                  width: "100px",
-                                  height: "100px",
-                                  flexShrink: 0,
-                                }}
-                              />
-                              <Typography
-                                variant="body1"
+                                    <img
+                                      src="https://raw.githubusercontent.com/Sunbird-ALL/all-learner-ai-app/refs/heads/all-1.2-tn-dev/src/assets/turtle.svg"
+                                      alt="turtleImage"
+                                    />
+                                    <span
+                                      style={{
+                                        marginTop: "12px",
+                                        color: "#1E2937",
+                                        fontWeight: 700,
+                                        lineHeight: "25px",
+                                        fontSize: "20px",
+                                        fontFamily: "Quicksand",
+                                      }}
+                                    >
+                                      {"Oops, a bit slow!"}
+                                    </span>
+                                  </Stack>
+                                )}
+                              </Stack>
+                              <Stack
+                                direction="row"
+                                alignItems="center"
+                                spacing={2}
                                 sx={{
-                                  wordWrap: "break-word",
-                                  whiteSpace: "normal",
-                                  maxWidth: "150px",
-                                  fontWeight: "700",
-                                  fontSize: "16px",
-                                  fontFamily: "Quicksand",
+                                  backgroundColor: "#F8EAD2",
+                                  border: "2px solid yellow",
+                                  borderRadius: "40px",
+                                  padding: "10px 20px",
+                                  //maxWidth: "100%",
                                 }}
                               >
-                                Let’s practice more
-                              </Typography>
+                                <img
+                                  src={Assets.starNewImg}
+                                  alt="Star"
+                                  style={{
+                                    width: "100px",
+                                    height: "100px",
+                                    flexShrink: 0,
+                                  }}
+                                />
+                                <Typography
+                                  variant="body1"
+                                  sx={{
+                                    wordWrap: "break-word",
+                                    whiteSpace: "normal",
+                                    maxWidth: "150px",
+                                    fontWeight: "700",
+                                    fontSize: "16px",
+                                    fontFamily: "Quicksand",
+                                  }}
+                                >
+                                  Let’s practice more
+                                </Typography>
+                              </Stack>
                             </Stack>
                           </Stack>
-                        </Stack>
-                      )}
-                    </Box>
-                  </>
-                )}
-              </CardContent>
-              <Box sx={{ height: "120px", position: "relative" }}>
-                <Box
-                  sx={{
-                    borderBottom: "1.5px solid rgba(51, 63, 97, 0.15)",
-                    width: "100%",
-                  }}
-                ></Box>
-                <Box
-                  sx={{
-                    display: "flex",
-                    justifyContent: currentPracticeStep ? "center" : "right",
-                    alignItems: "center",
-                    width: "100%",
-                    height: "100%",
-                  }}
-                >
-                  {
-                    <Box
-                      sx={{
-                        display: "flex",
-                        justifyContent: currentPracticeStep
-                          ? "center"
-                          : "right",
-                        alignItems: "center",
-                        width: "100%",
-                        height: "100%",
-                      }}
-                    >
-                      {showProgress && (
-                        <Box
-                          sx={{
-                            display: "flex",
-                            justifyContent: "center",
-                            width: "100%",
-                          }}
-                        >
+                        )}
+                      </Box>
+                    </>
+                  )}
+                </CardContent>
+                <Box sx={{ height: "120px", position: "relative" }}>
+                  <Box
+                    sx={{
+                      borderBottom: "1.5px solid rgba(51, 63, 97, 0.15)",
+                      width: "100%",
+                    }}
+                  ></Box>
+                  <Box
+                    sx={{
+                      display: "flex",
+                      justifyContent: currentPracticeStep ? "center" : "right",
+                      alignItems: "center",
+                      width: "100%",
+                      height: "100%",
+                    }}
+                  >
+                    {
+                      <Box
+                        sx={{
+                          display: "flex",
+                          justifyContent: currentPracticeStep
+                            ? "center"
+                            : "right",
+                          alignItems: "center",
+                          width: "100%",
+                          height: "100%",
+                        }}
+                      >
+                        {showProgress && (
                           <Box
                             sx={{
                               display: "flex",
                               justifyContent: "center",
-                              flexDirection: "column",
+                              width: "100%",
                             }}
                           >
-                            {" "}
                             <Box
                               sx={{
                                 display: "flex",
                                 justifyContent: "center",
-                                alignItems: "center",
-                                height: "48px",
-                                border: "1.5px solid rgba(51, 63, 97, 0.15)",
-                                ml: {
-                                  lg: 25,
-                                  md: 18,
-                                },
-                                borderRadius: "30px",
-                                background: "white",
+                                flexDirection: "column",
                               }}
                             >
-                              {practiceSteps.map((elem, i) => {
-                                return (
-                                  <Box
-                                    key={i}
-                                    sx={{
-                                      width: {
-                                        md: "28px",
-                                        lg: "36px",
-                                      },
-                                      height: {
-                                        md: "28px",
-                                        lg: "36px",
-                                      },
-                                      background:
-                                        currentPracticeStep > i
-                                          ? "linear-gradient(90deg, rgba(132, 246, 48, 0.1) 0%, rgba(64, 149, 0, 0.1) 95%)"
-                                          : currentPracticeStep === i
-                                          ? "linear-gradient(90deg, #FF4BC2 0%, #C20281 95%)"
-                                          : "rgba(0, 0, 0, 0.04)",
-                                      ml: {
-                                        md: 1.5,
-                                        lg: 2,
-                                      },
-                                      mr:
-                                        i === practiceSteps?.length - 1 ? 2 : 0,
-                                      borderRadius: "30px",
-                                      display: "flex",
-                                      justifyContent: "center",
-                                      alignItems: "center",
-                                    }}
-                                  >
-                                    {currentPracticeStep > i ? (
-                                      <GreenTick />
-                                    ) : (
-                                      <span
-                                        style={{
-                                          color:
-                                            currentPracticeStep === i
-                                              ? "white"
-                                              : "#1E2937",
-                                          fontWeight: 600,
-                                          lineHeight: "20px",
-                                          fontSize: "16px",
-                                          fontFamily: "Quicksand",
-                                        }}
-                                      >
-                                        {LEVEL === 1 ? elem.title : elem.name}
-                                      </span>
-                                    )}
-                                  </Box>
-                                );
-                              })}
+                              {" "}
+                              <Box
+                                sx={{
+                                  display: "flex",
+                                  justifyContent: "center",
+                                  alignItems: "center",
+                                  height: "48px",
+                                  border: "1.5px solid rgba(51, 63, 97, 0.15)",
+                                  ml: {
+                                    lg: 25,
+                                    md: 18,
+                                  },
+                                  borderRadius: "30px",
+                                  background: "white",
+                                }}
+                              >
+                                {practiceSteps.map((elem, i) => {
+                                  return (
+                                    <Box
+                                      key={i}
+                                      sx={{
+                                        width: {
+                                          md: "28px",
+                                          lg: "36px",
+                                        },
+                                        height: {
+                                          md: "28px",
+                                          lg: "36px",
+                                        },
+                                        background:
+                                          currentPracticeStep > i
+                                            ? "linear-gradient(90deg, rgba(132, 246, 48, 0.1) 0%, rgba(64, 149, 0, 0.1) 95%)"
+                                            : currentPracticeStep === i
+                                            ? "linear-gradient(90deg, #FF4BC2 0%, #C20281 95%)"
+                                            : "rgba(0, 0, 0, 0.04)",
+                                        ml: {
+                                          md: 1.5,
+                                          lg: 2,
+                                        },
+                                        mr:
+                                          i === practiceSteps?.length - 1
+                                            ? 2
+                                            : 0,
+                                        borderRadius: "30px",
+                                        display: "flex",
+                                        justifyContent: "center",
+                                        alignItems: "center",
+                                      }}
+                                    >
+                                      {currentPracticeStep > i ? (
+                                        <GreenTick />
+                                      ) : (
+                                        <span
+                                          style={{
+                                            color:
+                                              currentPracticeStep === i
+                                                ? "white"
+                                                : "#1E2937",
+                                            fontWeight: 600,
+                                            lineHeight: "20px",
+                                            fontSize: "16px",
+                                            fontFamily: "Quicksand",
+                                          }}
+                                        >
+                                          {LEVEL === 1 ? elem.title : elem.name}
+                                        </span>
+                                      )}
+                                    </Box>
+                                  );
+                                })}
+                              </Box>
                             </Box>
                           </Box>
-                        </Box>
-                      )}
-                      <Box
-                        sx={{ display: "flex", justifyContent: "right", mr: 4 }}
-                      >
+                        )}
                         <Box
                           sx={{
-                            cursor: "pointer",
-                            background:
-                              "linear-gradient(90deg, rgba(255,144,80,1) 0%, rgba(225,84,4,1) 85%)",
-                            minWidth: "160px",
-                            height: "55px",
-                            borderRadius: "10px",
                             display: "flex",
-                            justifyContent: "center",
-                            alignItems: "center",
-                            padding: "0px 24px 0px 20px",
-                          }}
-                          onClick={() => {
-                            if (
-                              ((LEVEL === 1 || LEVEL === 2) &&
-                                mFlow === true) ||
-                              mFlow === "true"
-                            ) {
-                              console.log("mFlow value:", mFlow);
-                              setLocalData("rFlow", true);
-                            }
-                            if (
-                              props.pageName === "wordsorimage" ||
-                              props.pageName === "m5"
-                            ) {
-                              resetStoredData();
-                            }
-                            if (isShowCase && !startShowCase && !gameOverData) {
-                              setStartShowCase(true);
-                            }
-                            if (gameOverData) {
-                              gameOverData.link
-                                ? navigate(gameOverData.link)
-                                : navigate("/_practice");
-                            }
+                            justifyContent: "right",
+                            mr: 4,
                           }}
                         >
-                          <Typography
-                            style={{
-                              color: "#FFFFFF",
-                              fontWeight: 600,
-                              fontSize: "20px",
-                              fontFamily: "Quicksand",
+                          <Box
+                            sx={{
+                              cursor: "pointer",
+                              background:
+                                "linear-gradient(90deg, rgba(255,144,80,1) 0%, rgba(225,84,4,1) 85%)",
+                              minWidth: "160px",
+                              height: "55px",
+                              borderRadius: "10px",
+                              display: "flex",
+                              justifyContent: "center",
+                              alignItems: "center",
+                              padding: "0px 24px 0px 20px",
+                            }}
+                            onClick={() => {
+                              if (
+                                ((LEVEL === 1 || LEVEL === 2) &&
+                                  mFlow === true) ||
+                                mFlow === "true"
+                              ) {
+                                console.log("mFlow value:", mFlow);
+                                setLocalData("rFlow", true);
+                              }
+                              if (
+                                props.pageName === "wordsorimage" ||
+                                props.pageName === "m5"
+                              ) {
+                                resetStoredData();
+                              }
+                              if (
+                                isShowCase &&
+                                !startShowCase &&
+                                !gameOverData
+                              ) {
+                                setStartShowCase(true);
+                              }
+                              if (gameOverData) {
+                                gameOverData.link
+                                  ? navigate(gameOverData.link)
+                                  : navigate("/_practice");
+                              }
                             }}
-                            fontSize={{ md: "14px", xs: "10px" }}
                           >
-                            {!gameOverData ? "Start Game ➜" : "Practice ➜"}
-                          </Typography>
+                            <Typography
+                              style={{
+                                color: "#FFFFFF",
+                                fontWeight: 600,
+                                fontSize: "20px",
+                                fontFamily: "Quicksand",
+                              }}
+                              fontSize={{ md: "14px", xs: "10px" }}
+                            >
+                              {!gameOverData ? "Start Game ➜" : "Practice ➜"}
+                            </Typography>
+                          </Box>
                         </Box>
                       </Box>
-                    </Box>
-                  }
+                    }
+                  </Box>
                 </Box>
-              </Box>
-            </Card>
-          )}
+              </Card>
+            )}
           {LEVEL === 15 && allCompleted && (
             <Card
               sx={{
diff --git a/src/components/Practice/AnouncementFlow.jsx b/src/components/Practice/AnouncementFlow.jsx
index d7a7cc3a..56cdc23d 100644
--- a/src/components/Practice/AnouncementFlow.jsx
+++ b/src/components/Practice/AnouncementFlow.jsx
@@ -236,6 +236,12 @@ const AnouncementFlow = ({
   // };
 
   const handleHintClick = () => {
+    if (isPlaying) {
+      // If already playing, stop the audio
+      audioInstance.pause();
+      audioInstance.currentTime = 0;
+      setIsPlaying(false);
+    }
     setStep("start");
     setIsPressedOnce(true);
   };
@@ -496,6 +502,12 @@ const AnouncementFlow = ({
   };
 
   const handleNextClick = () => {
+    if (isPlaying) {
+      // If already playing, stop the audio
+      audioInstance.pause();
+      audioInstance.currentTime = 0;
+      setIsPlaying(false);
+    }
     setShowQuestion(true);
     setIsPressedOnce(false);
   };
@@ -550,6 +562,12 @@ const AnouncementFlow = ({
   };
 
   const loadNextTask = async () => {
+    if (isPlaying) {
+      // If already playing, stop the audio
+      audioInstance.pause();
+      audioInstance.currentTime = 0;
+      setIsPlaying(false);
+    }
     setIsLoading(true);
 
     if (currentLevel === "S1" || currentLevel === "S2") {
@@ -824,7 +842,7 @@ const AnouncementFlow = ({
             />
           </div>
         )}
-        {showConfetti && <Confetti />}
+        {showConfetti && <Confetti height={"350px"} />}
         <div style={styles.innerContainer}>
           {!showQuestion ? (
             <div
@@ -1083,8 +1101,8 @@ const AnouncementFlow = ({
                   src={isPlaying ? spinnerStop : listenImg2}
                   alt="Audio"
                   style={{
-                    height: "50px",
-                    width: "50px",
+                    height: "45px",
+                    width: "45px",
                     cursor: "pointer",
                     //: "5px",
                   }}
diff --git a/src/components/Practice/ArrangePicture.jsx b/src/components/Practice/ArrangePicture.jsx
index 72a4d250..c5930e6b 100644
--- a/src/components/Practice/ArrangePicture.jsx
+++ b/src/components/Practice/ArrangePicture.jsx
@@ -151,6 +151,13 @@ function ArrangePicture({
   const allTexts = conversation?.audioData?.[audioIndex]?.text;
 
   const handleNextStep = () => {
+    if (isReadAloudPlaying) {
+      window.speechSynthesis.cancel();
+      utteranceRef.current = null;
+      setHighlightedWord(null);
+      setIsReadAloudPlaying(false);
+      //return;
+    }
     if (audioIndex < conversation?.audioData?.length - 1) {
       setAudioIndex(audioIndex + 1);
       setIsPressedOnce(false);
@@ -160,6 +167,13 @@ function ArrangePicture({
   };
 
   const handleNextTask = () => {
+    if (isReadAloudPlaying) {
+      window.speechSynthesis.cancel();
+      utteranceRef.current = null;
+      setHighlightedWord(null);
+      setIsReadAloudPlaying(false);
+      //return;
+    }
     handleNext();
     setPlacedImages([null, null, null, null, null]);
     setWrongAttempts([false, false, false, false, false]);
diff --git a/src/components/Practice/AskMoreM14.jsx b/src/components/Practice/AskMoreM14.jsx
index bdeefa6d..7aad5059 100644
--- a/src/components/Practice/AskMoreM14.jsx
+++ b/src/components/Practice/AskMoreM14.jsx
@@ -170,9 +170,9 @@ const AskMoreM14 = ({
   };
 
   const stopCompleteAudio = () => {
-    if (audioRef.current) {
-      audioRef.current.pause();
-      audioRef.current.currentTime = 0;
+    if (isPlaying) {
+      audioInstance.pause();
+      audioInstance.currentTime = 0;
       setIsPlaying(false);
     }
   };
@@ -368,6 +368,11 @@ const AskMoreM14 = ({
   const cloudPositions = generateCloudPositions();
 
   const handlePauseClick = async () => {
+    if (isPlaying) {
+      audioInstance.pause();
+      audioInstance.currentTime = 0;
+      setIsPlaying(false);
+    }
     setIsLoading(true);
 
     if (currentLevel === "S1" || currentLevel === "S2") {
diff --git a/src/components/Practice/JumbledWord.jsx b/src/components/Practice/JumbledWord.jsx
index 3afe1809..9cedef37 100644
--- a/src/components/Practice/JumbledWord.jsx
+++ b/src/components/Practice/JumbledWord.jsx
@@ -212,6 +212,7 @@ const JumbledWord = ({
   };
 
   const goToNextStep = () => {
+    stopCompleteAudio();
     handleNext();
     resetStates();
   };
diff --git a/src/components/Practice/McqFlow.jsx b/src/components/Practice/McqFlow.jsx
index 4e116cfd..37c9ec55 100644
--- a/src/components/Practice/McqFlow.jsx
+++ b/src/components/Practice/McqFlow.jsx
@@ -96,6 +96,10 @@ const McqFlow = ({
     }
   };
 
+  const handleStartRecording = () => {
+    setRecAudio(null);
+  };
+
   const playAudioCorrect = () => {
     const audio = new Audio(correctSound);
     audio.play();
@@ -293,7 +297,7 @@ const McqFlow = ({
             onClose={() => setZoomOpen(false)}
             sx={{
               display: "flex",
-              alignItems: "center",
+              alignItems: "flex-start",
               justifyContent: "center",
               zIndex: "99999",
             }}
@@ -303,7 +307,8 @@ const McqFlow = ({
                 position: "relative",
                 outline: "none",
                 height: "500px",
-                width: "500px",
+                marginTop: "30px",
+                //width: "500px",
               }}
             >
               {/* Subtle gradient overlay at the top of the zoomed image */}
@@ -353,7 +358,8 @@ const McqFlow = ({
                 style={{
                   // maxWidth: "90vw",
                   // maxHeight: "90vh",
-                  width: "100%",
+                  height: "90%",
+                  //width: "100%",
                   borderRadius: "8px",
                 }}
               />
@@ -387,7 +393,7 @@ const McqFlow = ({
             ) : null}
 
             <div>
-              {conversation?.tasks[currentStep - 1]?.options.map((option) => (
+              {conversation?.tasks?.[currentStep - 1]?.options.map((option) => (
                 <div
                   key={option.id}
                   style={{
@@ -459,6 +465,8 @@ const McqFlow = ({
               originalText={parentWords}
               audioLink={audio ? audio : completeAudio}
               buttonAnimation={selectedOption}
+              handleStartRecording={handleStartRecording}
+              //handleStopRecording={handleStopRecording}
               {...{
                 contentId,
                 contentType,
diff --git a/src/components/Practice/PhoneConversation.jsx b/src/components/Practice/PhoneConversation.jsx
index d24e86a0..108ebe6c 100644
--- a/src/components/Practice/PhoneConversation.jsx
+++ b/src/components/Practice/PhoneConversation.jsx
@@ -251,6 +251,13 @@ const PhoneConversation = ({
   };
 
   const handleNextClick = () => {
+    if (isPlaying) {
+      // If already playing, stop the audio
+      audioInstance.pause();
+      audioInstance.currentTime = 0;
+      setIsPlaying(false);
+      setAudioInstance(null);
+    }
     setShowQuestion(true);
   };
 
@@ -296,6 +303,13 @@ const PhoneConversation = ({
   };
 
   const loadNextTask = async () => {
+    if (isPlaying) {
+      // If already playing, stop the audio
+      audioInstance.pause();
+      audioInstance.currentTime = 0;
+      setIsPlaying(false);
+      setAudioInstance(null);
+    }
     setIsLoading(true);
 
     if (currentLevel === "S1" || currentLevel === "S2") {
@@ -620,7 +634,7 @@ const PhoneConversation = ({
       }}
     >
       <div style={styles.mainContainer}>
-        {showConfetti && <Confetti />}
+        {showConfetti && <Confetti height={"350px"} />}
         <div style={styles.innerContainer}>
           {!showQuestion ? (
             <>
diff --git a/src/components/Practice/R3.jsx b/src/components/Practice/R3.jsx
index 0616e7d4..90b7f34f 100644
--- a/src/components/Practice/R3.jsx
+++ b/src/components/Practice/R3.jsx
@@ -149,6 +149,7 @@ const R3 = ({
   const [showReset, setShowReset] = useState(false);
   const [progress, setProgress] = React.useState(0);
   const [activeIndex, setActiveIndex] = useState(0);
+  const [audioInstance, setAudioInstance] = useState(null);
   const {
     transcript,
     interimTranscript,
@@ -239,6 +240,12 @@ const R3 = ({
   };
 
   const handleNextClick = () => {
+    if (isAudioPlaying) {
+      // If already playing, stop the audio
+      audioInstance.pause();
+      audioInstance.currentTime = 0;
+      setIsAudioPlaying(false);
+    }
     if (selectedCheckbox) {
       handleAudioClick(selectedCheckbox);
       setShowNextButton(false);
@@ -274,11 +281,18 @@ const R3 = ({
   };
 
   const playAudio = (audioKey) => {
+    if (isAudioPlaying) {
+      // If already playing, stop the audio
+      audioInstance.pause();
+      audioInstance.currentTime = 0;
+      setIsAudioPlaying(false);
+    }
     if (getAssetAudioUrl(s3Assets[audioKey]) || Assets[audioKey]) {
       const audioElement = new Audio(
         getAssetAudioUrl(s3Assets[audioKey]) || Assets[audioKey]
       );
       audioElement.play();
+      setAudioInstance(audioElement);
       setIsAudioPlaying(true);
       audioElement.onended = () => setIsAudioPlaying(false);
     } else {


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 0**

<details>
<summary>🧹 Nitpick comments (3)</summary><blockquote>

<details>
<summary>src/components/Practice/McqFlow.jsx (3)</summary><blockquote>

`468-469`: **Good integration with VoiceAnalyser component**

Passing the `handleStartRecording` function as a prop to the VoiceAnalyser component ensures proper audio state management when starting a new recording.


Consider removing the commented-out `handleStopRecording` prop if it's no longer needed, or implementing it if it's required.

---

`157-157`: **Remove console.log statement**

Console statements should be removed in production code to improve performance and prevent potential security issues.

```diff
-  console.log("mcqFlow", conversation, currentStep);
```

---

`234-238`: **Consider cleaning up commented code blocks**

There are several blocks of commented-out code in the file. Consider removing these to improve code readability and maintainability.



Also applies to: 273-276, 333-343

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: .coderabbit.yaml**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 4533c968cddeacc125d2a31457b889ae4dcb6226 and abf8ed6cdb33680023574e20e7bfe01c14401618.

</details>

<details>
<summary>📒 Files selected for processing (7)</summary>

* `src/components/Practice/AnouncementFlow.jsx` (3 hunks)
* `src/components/Practice/ArrangePicture.jsx` (2 hunks)
* `src/components/Practice/AskMoreM14.jsx` (2 hunks)
* `src/components/Practice/JumbledWord.jsx` (1 hunks)
* `src/components/Practice/McqFlow.jsx` (6 hunks)
* `src/components/Practice/PhoneConversation.jsx` (2 hunks)
* `src/components/Practice/R3.jsx` (3 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Graph Analysis (4)</summary>

<details>
<summary>src/components/Practice/JumbledWord.jsx (1)</summary><blockquote>

<details>
<summary>src/components/Practice/AskMoreM14.jsx (1)</summary>

* `stopCompleteAudio` (172-178)

</details>

</blockquote></details>
<details>
<summary>src/components/Practice/AnouncementFlow.jsx (3)</summary><blockquote>

<details>
<summary>src/components/Practice/ArrangePicture.jsx (2)</summary>

* `isPlaying` (118-118)
* `audioInstance` (119-119)

</details>
<details>
<summary>src/components/Practice/PhoneConversation.jsx (2)</summary>

* `isPlaying` (90-90)
* `audioInstance` (91-91)

</details>
<details>
<summary>src/components/Practice/JumbledWord.jsx (1)</summary>

* `audioInstance` (89-89)

</details>

</blockquote></details>
<details>
<summary>src/components/Practice/McqFlow.jsx (3)</summary><blockquote>

<details>
<summary>src/components/Practice/AnouncementFlow.jsx (1)</summary>

* `handleStartRecording` (198-210)

</details>
<details>
<summary>src/components/Practice/PhoneConversation.jsx (1)</summary>

* `handleStartRecording` (222-234)

</details>
<details>
<summary>src/components/Practice/ActOutM13.jsx (1)</summary>

* `handleStartRecording` (342-353)

</details>

</blockquote></details>
<details>
<summary>src/components/Practice/R3.jsx (7)</summary><blockquote>

<details>
<summary>src/components/Practice/ArrangePicture.jsx (1)</summary>

* `audioInstance` (119-119)

</details>
<details>
<summary>src/components/Practice/JumbledWord.jsx (3)</summary>

* `audioInstance` (89-89)
* `isAudioPlaying` (82-82)
* `audioElement` (143-145)

</details>
<details>
<summary>src/components/Practice/AskMoreM14.jsx (1)</summary>

* `audioInstance` (128-128)

</details>
<details>
<summary>src/components/Practice/AnouncementFlow.jsx (1)</summary>

* `audioInstance` (93-93)

</details>
<details>
<summary>src/components/Practice/PhoneConversation.jsx (1)</summary>

* `audioInstance` (91-91)

</details>
<details>
<summary>src/RFlow/R2.jsx (1)</summary>

* `isAudioPlaying` (756-756)

</details>
<details>
<summary>src/utils/s3Links.js (2)</summary>

* `getAssetAudioUrl` (6-9)
* `getAssetAudioUrl` (6-9)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>🔇 Additional comments (18)</summary><blockquote>

<details>
<summary>src/components/Practice/McqFlow.jsx (5)</summary>

`99-101`: **Good addition of the handleStartRecording function**

This function properly resets the recorded audio state by setting `recAudio` to `null`, which aligns with the audio management improvements seen across other practice components. This helps prevent issues with overlapping recordings.

---

`300-300`: **Good UI improvement for the zoom modal**

Changing the alignment from center to flex-start provides a better viewing experience by positioning the zoomed content at the top of the screen instead of centering it vertically.

---

`310-311`: **Good responsive design approach**

Replacing fixed width with a top margin and commenting out the width constraint allows the zoom container to size based on content rather than being restricted to a fixed width.

---

`361-362`: **Good image sizing approach**

Setting a percentage height while commenting out the width constraint allows the zoomed image to maintain its aspect ratio while fitting within the container height.

---

`396-396`: **Good addition of safe navigation operator**

Adding the optional chaining operator (`?.`) when accessing `tasks` prevents potential runtime errors if `tasks` is undefined, improving the robustness of the component.

</details>
<details>
<summary>src/components/Practice/AnouncementFlow.jsx (3)</summary>

`238-244`: **Clean audio handling before hint display.**

The added code properly stops any playing audio before showing the hint, which prevents audio overlap and provides a better user experience.

---

`504-510`: **Good audio cleanup before proceeding to next step.**

This ensures any active audio playback is properly stopped before showing the question, preventing potential audio overlap issues.

---

`564-570`: **Consistent audio stopping before loading next task.**

This change maintains the same audio stopping pattern used elsewhere in the component, ensuring a consistent audio experience throughout the flow.

</details>
<details>
<summary>src/components/Practice/PhoneConversation.jsx (2)</summary>

`253-260`: **Good cleanup of audio before navigation.**

The added code properly stops any playing audio and cleans up references before showing the question screen, preventing audio overlap issues.

---

`305-312`: **Consistent audio stopping before task transition.**

This change ensures audio is properly stopped and cleaned up before loading the next task, maintaining a clean audio experience throughout the flow.

</details>
<details>
<summary>src/components/Practice/ArrangePicture.jsx (2)</summary>

`153-160`: **Properly cancel speech synthesis before step transition.**

Good addition to stop the text-to-speech playback before moving to the next step, preventing overlapping audio experiences for the user.

---

`169-176`: **Clean speech synthesis cancellation before task change.**

The added code ensures that any ongoing speech synthesis is properly stopped before transitioning to a new task, providing a better user experience.

</details>
<details>
<summary>src/components/Practice/R3.jsx (3)</summary>

`152-152`: **Added audio instance state for better audio management.**

This state addition allows for proper tracking and control of the audio element throughout the component.

---

`243-248`: **Good audio cleanup before handling next action.**

The added code ensures that any playing audio is properly stopped before proceeding with the next interaction, preventing audio overlap.

---

`284-289`: **Improved audio playback handling with state management.**

The enhanced playback function now properly handles stopping current audio before starting new audio, and tracks the audio instance for future reference. This creates a more consistent audio experience.



Also applies to: 295-295

</details>
<details>
<summary>src/components/Practice/JumbledWord.jsx (1)</summary>

`214-218`: **Improved audio handling before navigation.**

The addition of `stopCompleteAudio()` at the beginning of `goToNextStep` ensures that any currently playing audio is properly stopped and reset before proceeding to the next step. This prevents audio overlap between steps and creates a cleaner user experience.

</details>
<details>
<summary>src/components/Practice/AskMoreM14.jsx (2)</summary>

`172-178`: **Improved audio management with state-based approach.**

The implementation now properly uses the state variable `isPlaying` to check playback status instead of directly checking the DOM element. This follows React best practices by relying on component state rather than DOM references.

The code also now uses the `audioInstance` state variable instead of `audioRef.current` for controlling playback, which is more consistent with React's state management patterns.

---

`370-375`: **Added audio cleanup before processing user input.**

This addition ensures that any playing audio is properly stopped before proceeding with loading states and API calls. This prevents potential audio overlap issues and provides a more consistent user experience when transitioning between interaction states.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-21T07:43:25Z
user: login: coderabbitai[bot]
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-21T07:43:28Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 2**

<details>
<summary>🧹 Nitpick comments (2)</summary><blockquote>

<details>
<summary>src/components/Layouts.jsx/MainLayout.jsx (2)</summary><blockquote>

`904-907`: **Avoid hard‑coding GitHub raw URLs for production assets**

Images such as `gameLost.svg` are fetched directly from GitHub’s raw CDN. These links are rate‑limited, carry no cache‑busting strategy, and may trigger CORS errors, breaking the UI at runtime. Move the assets into the app’s static bundle (e.g. `src/assets/`) and import them just like the other images already present in this component.  



Also applies to: 1000-1017

---

`1189-1258`: **Duplicate progress‑bar markup – extract a reusable component**

The progress‑bar rendering logic appears twice (standard view vs. showcase view) with nearly identical code. Duplications of 60+ lines increase maintenance cost and the risk of divergence.

Create a small `<PracticeProgressBar>` component that accepts `practiceSteps`, `currentPracticeStep`, and `level` to centralise the logic and styling.

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: .coderabbit.yaml**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 558e0910dc2d86f46614d3d70041cd10b8f769f7 and 666e186a38dbe0755e862ab57e216766ef03a7cd.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `src/components/Layouts.jsx/MainLayout.jsx` (1 hunks)

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-21T13:03:20Z
user: login: swayangjit
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-22T05:30:35Z

Review comments:
diff_hunk: @@ -800,519 +800,533 @@ const MainLayout = (props) => {
                 </Box>
               </Card>
             )}
-          {((isShowCase && !startShowCase) || gameOverData) && (
-            <Card
-              sx={{
-                width: "85vw",
-                minHeight: "80vh",
-                borderRadius: "20px",
-                display: "flex",
-                flexDirection: "column",
-                justifyContent: "space-between",
-                backgroundImage: `url(${cardBackground || textureImage})`,
-                backgroundSize: "contain",
-                backgroundRepeat: "round",
-                boxShadow: "0px 4px 20px -1px rgba(0, 0, 0, 0.00)",
-                backdropFilter: "blur(25px)",
-                mt: "50px",
-              }}
-            >
-              <Box>{shake && <Confetti width={width} height={"602px"} />}</Box>
-              <CardContent
+          {((isShowCase && !startShowCase) || gameOverData) &&
+            !allCompleted && (
+              <Card
                 sx={{
-                  width: "82vw",
-                  minHeight: "100%",
-                  opacity: disableScreen ? 0.25 : 1,
-                  pointerEvents: disableScreen ? "none" : "initial",
+                  width: "85vw",
+                  minHeight: "80vh",
+                  borderRadius: "20px",
+                  display: "flex",
+                  flexDirection: "column",
+                  justifyContent: "space-between",
+                  backgroundImage: `url(${cardBackground || textureImage})`,
+                  backgroundSize: "contain",
+                  backgroundRepeat: "round",
+                  boxShadow: "0px 4px 20px -1px rgba(0, 0, 0, 0.00)",
+                  backdropFilter: "blur(25px)",
+                  mt: "50px",
                 }}
path: src/components/Layouts.jsx/MainLayout.jsx
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Fixed width breaks responsiveness on mobile**

`width: "85vw"` is applied for every breakpoint, unlike the earlier card that falls back to `100%` on extra‑small screens. On phones this will overflow the viewport and introduce horizontal scrolling.

```diff
- width: "85vw",
+ width: { xs: "100%", md: "85vw" },
```

This restores the responsive behaviour seen in the primary card.  



<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
          {((isShowCase && !startShowCase) || gameOverData) &&
            !allCompleted && (
              <Card
                sx={{
                  width: { xs: "100%", md: "85vw" },
                  minHeight: "80vh",
                  borderRadius: "20px",
                  display: "flex",
                  flexDirection: "column",
                  justifyContent: "space-between",
                  backgroundImage: `url(${cardBackground || textureImage})`,
                  backgroundSize: "contain",
                  backgroundRepeat: "round",
                  boxShadow: "0px 4px 20px -1px rgba(0, 0, 0, 0.00)",
                  backdropFilter: "blur(25px)",
                  mt: "50px",
                }}
              >
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-21T13:03:17Z
author_association: CONTRIBUTOR
diff_hunk: @@ -800,519 +800,533 @@ const MainLayout = (props) => {
                 </Box>
               </Card>
             )}
-          {((isShowCase && !startShowCase) || gameOverData) && (
-            <Card
-              sx={{
-                width: "85vw",
-                minHeight: "80vh",
-                borderRadius: "20px",
-                display: "flex",
-                flexDirection: "column",
-                justifyContent: "space-between",
-                backgroundImage: `url(${cardBackground || textureImage})`,
-                backgroundSize: "contain",
-                backgroundRepeat: "round",
-                boxShadow: "0px 4px 20px -1px rgba(0, 0, 0, 0.00)",
-                backdropFilter: "blur(25px)",
-                mt: "50px",
-              }}
-            >
-              <Box>{shake && <Confetti width={width} height={"602px"} />}</Box>
-              <CardContent
+          {((isShowCase && !startShowCase) || gameOverData) &&
+            !allCompleted && (
+              <Card
                 sx={{
-                  width: "82vw",
-                  minHeight: "100%",
-                  opacity: disableScreen ? 0.25 : 1,
-                  pointerEvents: disableScreen ? "none" : "initial",
+                  width: "85vw",
+                  minHeight: "80vh",
+                  borderRadius: "20px",
+                  display: "flex",
+                  flexDirection: "column",
+                  justifyContent: "space-between",
+                  backgroundImage: `url(${cardBackground || textureImage})`,
+                  backgroundSize: "contain",
+                  backgroundRepeat: "round",
+                  boxShadow: "0px 4px 20px -1px rgba(0, 0, 0, 0.00)",
+                  backdropFilter: "blur(25px)",
+                  mt: "50px",
                 }}
               >
-                {isShowCase && !startShowCase && !gameOverData && (
-                  <>
-                    <Typography
-                      className="successHeader"
-                      sx={{
-                        textAlign: "center",
-                      }}
-                    >
-                      Hurray!!!
-                    </Typography>
-                    <Typography
-                      sx={{
-                        mb: 1,
-                        mt: 1,
-                        textAlign: "center",
-                      }}
-                    >
-                      <span
-                        style={{
-                          color: "#50507D",
-                          fontWeight: 600,
-                          fontSize: "20px",
-                          lineHeight: "37px",
-                          letterSpacing: "2%",
-                          fontFamily: "Quicksand",
+                <Box>
+                  {shake && <Confetti width={width} height={"602px"} />}
+                </Box>
+                <CardContent
+                  sx={{
+                    width: "82vw",
+                    minHeight: "100%",
+                    opacity: disableScreen ? 0.25 : 1,
+                    pointerEvents: disableScreen ? "none" : "initial",
+                  }}
+                >
+                  {isShowCase && !startShowCase && !gameOverData && (
+                    <>
+                      <Typography
+                        className="successHeader"
+                        sx={{
+                          textAlign: "center",
                         }}
                       >
-                        {"Ready for Challenge?"}
-                      </span>
-                    </Typography>
-                  </>
-                )}
-                {gameOverData && (
-                  <>
-                    <Box
-                      sx={{
-                        position: "absolute",
-                        top: "-120px",
-                        left: "-70px",
-                      }}
-                    >
-                      {!gameOverData?.userWon && (
-                        <img
-                          src={clouds}
-                          alt="clouds"
-                          style={{ zIndex: -999 }}
-                        />
-                      )}
-                    </Box>
-                    <Box
-                      sx={{
-                        display: "flex",
-                        justifyContent: "center",
-                        position: "relative",
-                        zIndex: "100",
-                      }}
-                    >
-                      {gameOverData?.userWon ? (
-                        <img
-                          src={gameWon}
-                          alt="gameWon"
-                          style={{ zIndex: 9999, height: 340 }}
-                        />
-                      ) : (
-                        <Stack
-                          justifyContent="center"
-                          alignItems="center"
-                          direction={"row"}
-                          zIndex={100}
+                        Hurray!!!
+                      </Typography>
+                      <Typography
+                        sx={{
+                          mb: 1,
+                          mt: 1,
+                          textAlign: "center",
+                        }}
+                      >
+                        <span
+                          style={{
+                            color: "#50507D",
+                            fontWeight: 600,
+                            fontSize: "20px",
+                            lineHeight: "37px",
+                            letterSpacing: "2%",
+                            fontFamily: "Quicksand",
+                          }}
                         >
-                          <Stack justifyContent="center" alignItems="center">
-                            <img
-                              src={`https://raw.githubusercontent.com/Sunbird-ALL/all-learner-ai-app/refs/heads/all-1.3/src/assets/images/gameLost.svg`}
-                              alt="gameLost"
-                              style={{ height: 340 }}
-                            />
-                            <Typography
-                              sx={{ mb: 1, mt: 1, textAlign: "center" }}
-                            >
-                              {!props.pageName === "m8" && (
-                                <span
-                                  style={{
-                                    fontWeight: 600,
-                                    fontSize: "24px",
-                                    lineHeight: "1.5",
-                                    letterSpacing: "1px",
-                                    fontFamily: "Quicksand",
-                                    backgroundColor: "rgb(237, 134, 0)",
-                                    padding: "6px 12px",
-                                    color: "#fff",
-                                    borderRadius: "20px",
-                                    boxShadow: "0px 2px 4px rgba(0, 0, 0, 0.1)",
-                                    textShadow:
-                                      "1px 1px 2px rgba(0, 0, 0, 0.5)",
-                                  }}
-                                >
-                                  {percentage <= 0 ? 0 : percentage}/100
-                                </span>
-                              )}
-                              <br />
-
-                              {!fluency ? (
-                                <Typography textAlign="center" sx={{ mt: 2 }}>
-                                  Good try! Need more speed.
-                                </Typography>
-                              ) : (
-                                <Typography textAlign="center" sx={{ mt: 2 }}>
-                                  You need{" "}
-                                  <span style={{ fontWeight: "bold" }}>
-                                    {Math.abs(70 - percentage)}
-                                  </span>{" "}
-                                  more.
-                                </Typography>
-                              )}
-                            </Typography>
-                          </Stack>
-                          {/* second stack below*/}
+                          {"Ready for Challenge?"}
+                        </span>
+                      </Typography>
+                    </>
+                  )}
+                  {gameOverData && (
+                    <>
+                      <Box
+                        sx={{
+                          position: "absolute",
+                          top: "-120px",
+                          left: "-70px",
+                        }}
+                      >
+                        {!gameOverData?.userWon && (
+                          <img
+                            src={clouds}
+                            alt="clouds"
+                            style={{ zIndex: -999 }}
+                          />
+                        )}
+                      </Box>
+                      <Box
+                        sx={{
+                          display: "flex",
+                          justifyContent: "center",
+                          position: "relative",
+                          zIndex: "100",
+                        }}
+                      >
+                        {gameOverData?.userWon ? (
+                          <img
+                            src={gameWon}
+                            alt="gameWon"
+                            style={{ zIndex: 9999, height: 340 }}
+                          />
+                        ) : (
                           <Stack
-                            direction={"column"}
+                            justifyContent="center"
                             alignItems="center"
-                            spacing={2}
-                            marginLeft={"10px"}
+                            direction={"row"}
+                            zIndex={100}
                           >
+                            <Stack justifyContent="center" alignItems="center">
+                              <img
+                                src={`https://raw.githubusercontent.com/Sunbird-ALL/all-learner-ai-app/refs/heads/all-1.3/src/assets/images/gameLost.svg`}
+                                alt="gameLost"
+                                style={{ height: 340 }}
+                              />
+                              <Typography
+                                sx={{ mb: 1, mt: 1, textAlign: "center" }}
+                              >
+                                {!props.pageName === "m8" && (
+                                  <span
+                                    style={{
+                                      fontWeight: 600,
+                                      fontSize: "24px",
+                                      lineHeight: "1.5",
+                                      letterSpacing: "1px",
+                                      fontFamily: "Quicksand",
+                                      backgroundColor: "rgb(237, 134, 0)",
+                                      padding: "6px 12px",
+                                      color: "#fff",
+                                      borderRadius: "20px",
+                                      boxShadow:
+                                        "0px 2px 4px rgba(0, 0, 0, 0.1)",
+                                      textShadow:
+                                        "1px 1px 2px rgba(0, 0, 0, 0.5)",
+                                    }}
+                                  >
+                                    {percentage <= 0 ? 0 : percentage}/100
+                                  </span>
+                                )}
+                                <br />
+
+                                {!fluency ? (
+                                  <Typography textAlign="center" sx={{ mt: 2 }}>
+                                    Good try! Need more speed.
+                                  </Typography>
+                                ) : (
+                                  <Typography textAlign="center" sx={{ mt: 2 }}>
+                                    You need{" "}
+                                    <span style={{ fontWeight: "bold" }}>
+                                      {Math.abs(70 - percentage)}
+                                    </span>{" "}
+                                    more.
+                                  </Typography>
+                                )}
+                              </Typography>
+                            </Stack>
+                            {/* second stack below*/}
                             <Stack
-                              sx={{
-                                boxShadow: "rgba(0, 0, 0, 0.24) 0px 3px 8px;",
-                                paddingY: "49px",
-                                paddingX: "30px",
-                                borderRadius: "13px",
-                                marginLeft: "80px",
-                                bgcolor: "#FFFFFF",
-                                zIndex: 100,
-                              }}
-                              direction={"row"}
+                              direction={"column"}
+                              alignItems="center"
+                              spacing={2}
+                              marginLeft={"10px"}
                             >
                               <Stack
                                 sx={{
-                                  paddingRight:
-                                    (props.pageName === "wordsorimage" ||
-                                      props.pageName === "m5") &&
-                                    !fluency
-                                      ? "20px"
-                                      : "0px",
-                                  borderRight:
-                                    (props.pageName === "wordsorimage" ||
-                                      props.pageName === "m5") &&
-                                    !fluency
-                                      ? "1px dashed grey"
-                                      : "none",
+                                  boxShadow: "rgba(0, 0, 0, 0.24) 0px 3px 8px;",
+                                  paddingY: "49px",
+                                  paddingX: "30px",
+                                  borderRadius: "13px",
+                                  marginLeft: "80px",
+                                  bgcolor: "#FFFFFF",
+                                  zIndex: 100,
                                 }}
+                                direction={"row"}
                               >
-                                {(props.pageName === "wordsorimage" ||
-                                  props.pageName === "m5") &&
-                                  storedData?.map((elem, index) => (
-                                    <Stack
-                                      key={index}
-                                      justifyContent={"start"}
-                                      alignItems={"center"}
-                                      direction={"row"}
-                                      mt={index > 0 ? "25px" : 0}
-                                    >
-                                      <Box
-                                        sx={{
-                                          marginLeft: "35px",
-                                          marginRight: "5px",
-                                        }}
-                                      >
-                                        {elem?.audioUrl ? (
-                                          <button
-                                            onClick={() =>
-                                              handleAudioPlay(index)
-                                            }
-                                            style={{
-                                              height: "30px",
-                                              cursor: "pointer",
-                                              background: "none",
-                                              border: "none",
-                                              padding: "0",
-                                            }}
-                                            aria-label={
-                                              audioPlaying === index
-                                                ? "Pause audio"
-                                                : "Play audio"
-                                            }
-                                          >
-                                            <img
-                                              src={
-                                                audioPlaying === index
-                                                  ? pauseButton
-                                                  : playButton
-                                              }
-                                              alt={
-                                                audioPlaying === index
-                                                  ? "Pause"
-                                                  : "Play"
-                                              }
-                                              style={{ height: "30px" }}
-                                            />
-                                          </button>
-                                        ) : (
-                                          <Box></Box>
-                                        )}
-                                        <audio
-                                          ref={(el) =>
-                                            (audioRefs.current[index] = el)
-                                          }
-                                          src={elem?.audioUrl}
-                                        />
-                                      </Box>
-
-                                      {elem?.correctAnswer === false ? (
-                                        <img
-                                          src="https://raw.githubusercontent.com/Sunbird-ALL/all-learner-ai-app/refs/heads/all-1.2-tn-dev/src/assets/wrong.svg"
-                                          alt="wrongImage"
-                                        />
-                                      ) : (
-                                        <img
-                                          src="https://raw.githubusercontent.com/Sunbird-ALL/all-learner-ai-app/refs/heads/all-1.2-tn-dev/src/assets/correct.svg"
-                                          alt="correctImage"
-                                        />
-                                      )}
-                                      <span
-                                        style={{
-                                          marginLeft: "8px",
-                                          color: "#1E2937",
-                                          fontWeight: 700,
-                                          lineHeight: "30px",
-                                          fontSize: "15px",
-                                          fontFamily: "Quicksand",
-                                          minWidth: "100px",
-                                        }}
-                                      >
-                                        {elem.selectedAnswer || "Binocular"}
-                                      </span>
-                                    </Stack>
-                                  ))}
-                              </Stack>
-                              {(fluency ||
-                                [10, 11, 12, 13, 14, 15].includes(LEVEL)) && (
                                 <Stack
                                   sx={{
-                                    paddingLeft:
+                                    paddingRight:
                                       (props.pageName === "wordsorimage" ||
                                         props.pageName === "m5") &&
                                       !fluency
                                         ? "20px"
                                         : "0px",
+                                    borderRight:
+                                      (props.pageName === "wordsorimage" ||
+                                        props.pageName === "m5") &&
+                                      !fluency
+                                        ? "1px dashed grey"
+                                        : "none",
                                   }}
-                                  justifyContent={"center"}
-                                  alignItems={"center"}
                                 >
-                                  <img
-                                    src="https://raw.githubusercontent.com/Sunbird-ALL/all-learner-ai-app/refs/heads/all-1.2-tn-dev/src/assets/turtle.svg"
-                                    alt="turtleImage"
-                                  />
-                                  <span
-                                    style={{
-                                      marginTop: "12px",
-                                      color: "#1E2937",
-                                      fontWeight: 700,
-                                      lineHeight: "25px",
-                                      fontSize: "20px",
-                                      fontFamily: "Quicksand",
+                                  {(props.pageName === "wordsorimage" ||
+                                    props.pageName === "m5") &&
+                                    storedData?.map((elem, index) => (
+                                      <Stack
+                                        key={index}
+                                        justifyContent={"start"}
+                                        alignItems={"center"}
+                                        direction={"row"}
+                                        mt={index > 0 ? "25px" : 0}
+                                      >
+                                        <Box
+                                          sx={{
+                                            marginLeft: "35px",
+                                            marginRight: "5px",
+                                          }}
+                                        >
+                                          {elem?.audioUrl ? (
+                                            <button
+                                              onClick={() =>
+                                                handleAudioPlay(index)
+                                              }
+                                              style={{
+                                                height: "30px",
+                                                cursor: "pointer",
+                                                background: "none",
+                                                border: "none",
+                                                padding: "0",
+                                              }}
+                                              aria-label={
+                                                audioPlaying === index
+                                                  ? "Pause audio"
+                                                  : "Play audio"
+                                              }
+                                            >
+                                              <img
+                                                src={
+                                                  audioPlaying === index
+                                                    ? pauseButton
+                                                    : playButton
+                                                }
+                                                alt={
+                                                  audioPlaying === index
+                                                    ? "Pause"
+                                                    : "Play"
+                                                }
+                                                style={{ height: "30px" }}
+                                              />
+                                            </button>
+                                          ) : (
+                                            <Box></Box>
+                                          )}
+                                          <audio
+                                            ref={(el) =>
+                                              (audioRefs.current[index] = el)
+                                            }
+                                            src={elem?.audioUrl}
+                                          />
+                                        </Box>
path: src/components/Layouts.jsx/MainLayout.jsx
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Pause handler should also reset `currentTime`**

`handleAudioPlay` pauses the previously playing clip but does not rewind it, so replaying starts mid‑way. Resetting the time creates a predictable UX:

```diff
- previousAudioElem.pause();
+ previousAudioElem.pause();
+ previousAudioElem.currentTime = 0;
```

Do the same when toggling the current clip off.  



> Committable suggestion skipped: line range outside the PR's diff.

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-21T13:03:18Z
author_association: CONTRIBUTOR

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-04-21T07:41:46Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough

This update introduces consistent handling for stopping audio and speech synthesis playback across multiple practice-related components. Functions that transition between steps or tasks now check if audio or speech is currently playing. If so, they pause and reset the playback before proceeding. The changes also standardize the use of state-managed audio instances instead of direct element references, and add robustness to UI logic in some components. Minor UI layout improvements and safe property access are also included.

## Changes

| Files/Paths                                                                                   | Change Summary                                                                                                                                                                                                                                                                                                                                                                 |
|----------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| src/components/Practice/AnouncementFlow.jsx, src/components/Practice/PhoneConversation.jsx    | Added checks in navigation functions to pause, reset, and clear audio playback state if audio is playing before proceeding to the next step or task. Ensures ongoing audio is stopped on user interactions. Also set fixed height for `Confetti` component and adjusted audio icon size in AnouncementFlow.                                                                 |
| src/components/Practice/ArrangePicture.jsx                                                    | Added logic in `handleNextStep` and `handleNextTask` to cancel ongoing speech synthesis, clear utterance references, reset highlighting, and update playing state before proceeding.                                                                                                              |
| src/components/Practice/AskMoreM14.jsx                                                        | Replaced direct audio element reference with a state-managed `audioInstance` for playback control. Unified stopping logic to use `isPlaying` flag and `audioInstance` in relevant functions, including adding audio stop logic in `handlePauseClick`.                                                                                                     |
| src/components/Practice/JumbledWord.jsx                                                       | Added a call to `stopCompleteAudio()` at the start of `goToNextStep` to ensure audio is stopped before proceeding.                                                                                                                                                                               |
| src/components/Practice/McqFlow.jsx                                                           | Introduced `handleStartRecording` to reset recorded audio before starting a new recording. Adjusted zoom modal styles and added safe navigation for accessing `tasks` in options mapping.                                                                                                        |
| src/components/Practice/R3.jsx                                                                | Introduced a state variable for the audio instance. Updated audio play and navigation logic to stop any ongoing audio before starting new playback or moving to the next step, ensuring only one audio plays at a time.                                    |
| src/components/Layouts.jsx/MainLayout.jsx                                                     | Modified conditional rendering of a Card component to include an additional `!allCompleted` check. Restored original styling values for width and minHeight, moved opacity and pointerEvents styles to Card, and restructured JSX for clarity and consistent styling. Adjusted layout of game over display and progress steps without changing core logic. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant PracticeComponent
    participant Audio/Speech

    User->>PracticeComponent: Clicks Next/Hint/Step
    alt Audio/Speech is playing
        PracticeComponent->>Audio/Speech: Pause and reset playback
        PracticeComponent->>Audio/Speech: Clear playing state
    end
    PracticeComponent->>PracticeComponent: Proceed with next step/task logic
```

## Possibly related PRs

- Sunbird-ALL/all-learner-ai-app#177: Modifies the `MainLayout` component with audio playback handling and UI rendering adjustments, related to this PR's changes in layout and audio state management.

## Suggested reviewers

- swayangjit

<!-- walkthrough_end -->
<!-- This is an auto-generated comment: all tool run failures by coderabbit.ai -->

> [!WARNING]
> There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.
> 
> <details>
> <summary>🔧 ESLint</summary>
> 
> > If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.
> 
> <details>
> <summary>src/components/Layouts.jsx/MainLayout.jsx</summary>
> 
> 
> Oops! Something went wrong! :(
> 
> ESLint: 7.32.0
> 
> ESLint couldn't find the config "react-app" to extend from. Please check that the name of the config is correct.
> 
> The config "react-app" was referenced from the config file in "/package.json".
> 
> If you still have problems, please stop by https://eslint.org/chat/help to chat with the team.
> 
> 
> </details>
> 
> </details>

<!-- end of auto-generated comment: all tool run failures by coderabbit.ai -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details>
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=Sunbird-ALL/all-learner-ai-app&utm_content=337):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR
user: login: sonarqubecloud[bot]
created_at: 2025-04-21T13:01:11Z
body: ## [![Quality Gate Failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-failed-20px.png 'Quality Gate Failed')](https://sonarcloud.io/dashboard?id=Sunbird-ALL_all-learner-ai-app&pullRequest=337) **Quality Gate failed**  
Failed conditions  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/failed-16px.png '') [B Reliability Rating on New Code](https://sonarcloud.io/dashboard?id=Sunbird-ALL_all-learner-ai-app&pullRequest=337) (required ≥ A)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=Sunbird-ALL_all-learner-ai-app&pullRequest=337)

##   
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/light_bulb-16px.png '') Catch issues before they fail your Quality Gate with our IDE extension ![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/sonarlint-16px.png '') [SonarQube for IDE](https://www.sonarsource.com/products/sonarlint/features/connected-mode/?referrer=pull-request)


author_association: NONE