Build a One-Time Password Generator - Build a One-Time Password Generator

Tell us what’s happening:

Hello hello,

After completing (as well as obtaining) both JS and WebDesign certifications, I’m now moving on to the Development Librairies. In this code here, tests 12,13 and 16 always fail, even though the rendering works as intended.
I can’t figure out where the problem is. Can you guys help me please?
Thank you,
Good day,
MChance

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>OTP Generator</title>
    <link rel="stylesheet" href="styles.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.development.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.development.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.26.5/babel.min.js"></script>
    <script
      data-plugins="transform-modules-umd"
      type="text/babel"
      src="index.jsx"
    ></script>
</head>

<body>
    <div id="root"></div>
    <script
      data-plugins="transform-modules-umd"
      type="text/babel"
      data-presets="react"
      data-type="module"
    >
      import { OTPGenerator } from './index.jsx';
      ReactDOM.createRoot(document.getElementById('root')).render(<OTPGenerator />);
    </script>
</body>

</html>
/* file: styles.css */

/* file: index.jsx */
const { useState, useEffect, useRef } = React;

export const OTPGenerator = () => {
  const intervalId = useRef(null);
  const [otp, setOtp] = useState(null);
  const [secLeft, setSecLeft] = useState(5);
  const [isCounting, setIsCounting] = useState(false);
  const [hasGen, setHasGen] = useState(false);

  const generateOtp = () => {
    return (Math.floor(100000+Math.random()*900000).toString())
  }
  const handleGenerateOtp = () => {
    clearInterval(intervalId.current);
    setOtp(generateOtp());
    setSecLeft(5);
    setIsCounting(true);
    setHasGen(true);
    intervalId.current = setInterval(()=>{
      setSecLeft(prevSeconds => prevSeconds - 1);
    }, 1000)
  }
  useEffect(() => {
    if (secLeft===0){
      setIsCounting(false);
      setOtp(null);
      clearInterval(intervalId.current);
    }
  }, [secLeft])
   useEffect (
    () => () => {
      clearInterval(intervalId.current);
    }, []
  )
  return (
    <div className="container">
      <h1 id="otp-title">OTP Generator</h1>
      <h2 id="otp-display">{otp ? otp : "Click 'Generate OTP' to get a code"}</h2>
      <p id="otp-timer" aria-live="polite">{
        isCounting ? `Expires in ${secLeft} seconds`
        : hasGen && "OTP Expired. Click the button to generate a new OTP."
      }</p>
      <button id="generate-otp-button"onClick={handleGenerateOtp}disabled={isCounting}>Generate OTP</button>
    </div>
  )
};

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36 OPR/133.0.0.0

Challenge Information:

Build a One-Time Password Generator - Build a One-Time Password Generator

GitHub Link: freeCodeCamp/curriculum/challenges/english/blocks/lab-one-time-password-generator/67c562286b29447da020d407.md at main · freeCodeCamp/freeCodeCamp · GitHub

Hi @MChance

Are you sure?

Expires in 5 seconds

OTP Expired. Click the button to generate a new OTP.

Check for typo and punctuation.

Happy coding

Hi @MChance,

To add to what @Teller is pointing out, please check the example application again. Should “Click ‘Generate OTP’ to get a code” replace the OTP when it has expired?

Happy coding

Hey @Teller @dhess

Thank you so much :slight_smile: I finally got it :slight_smile: As always, the devil is in the details.

Happy coding!!