Is there a way to store users first login time in react js application with react-oidc-context

I am using OIDC for authentication in my react application. For that i am using react-oidc-context library. There was some use case in our application that user first time login time i want to store in my application so i can compare his login time with current time and will logout user once 8hrs completed. I know token expiry also do the job but token we are renewing every 30minutes just i want to check if the user has been logged in for more than 8 hours he should get logged out.

I am trying to store login time in localstorage when user is authenticated by auth.isAuthenticated but the problem is if i refresh the tab then the new login time is get added to the locasotrage.

validation to avoid overlapping of text not working inside squares

Following steps need to be followed in order for the code to work.

  1. Select one option from Select options dropdown.
  2. Select a color from the dropdown.
  3. Click Show Options button
  4. Enter a row and column (For example A and 1) and then click calculate
  5. Hit the Move Text Content! button to move blue boxes on the grid.
    Forget about barcode and plate name for this problem.

Scenario I’m trying to validate:

Let’s say I have option one related content on cell A1, A2 and A3 and option two related content starting from B1.

Note: the order in which the cell contents are filling are left to right and from bottom to up. Hence, when I hit the Move Text Content button to fill 7 blue boxes on the grid starting from B1, it will look like this.
enter image description here

As you can see, the last two items OptionTwo#6 and OptionTwo#7 got overlapped with already present text on A1 and A2. So I’m trying to handle this edge case scenario and I was approaching it this way (code snippet below from the actual code):

myButton.addEventListener("click", () => {
        /* To Validate:
        Case #1: If the cell value for starting square already exists
        then, you cannot fill it. Show an alert. 
        
        Case #2: Check for all the values that are about to be moved on to
        the squares. If any of these overlap with already existing value of the grid
        then you cannot fill it. Show an alert
        */

        /* Get all values that need to be tested 
       */

        var childDivs = document
            .getElementById("phrase")
            .querySelectorAll("div:has(> span[data-id])");

        console.log(childDivs);

        // get the calculated value of the cell number
        let testValue = document.querySelector("#cellnum").innerHTML;

        console.log("Test Value");
        console.log(testValue);
        let integerValue = parseInt(testValue);

        // create an array of values to be tested.
        const valueArray = [];
        for (i = 0; i < childDivs.length; i++) {
            valueArray.push(integerValue + i);
        }



        for (j = 0; j < valueArray.length; j++) {
            var getDivWithValue = document
                .getElementById("drop-em")
                .querySelectorAll('div:has(> span[data-id="' + valueArray[j] + '"])');



            if (getDivWithValue.length > 0) {
                console.log("A value already exists for cell value " + valueArray[j]);

                alert("Starting Square or other Square needed to complete the move are already in use.Please use different Starting Cell Value");
                return;
            }
        }


        fill();
    },

    );

What’s the issue with the above approach?

Here is my complete working code:

/*

Requires jquery + UI

https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js

https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js

*/

$('[name="optionSelection"]').change(function () {
      //clean up the divs inside div with id phrase
    $("#phrase").empty();
  });
let selectedColor;
  function showOptions() {
      selectedColor = $('#lineupColors').val();
    var html;
    if ($("#optionSelection").val() == 1) {
      for (i = 0; i < 3; i++) {
         
            html = "<div data-id="+i+"><span class='words' style='color:black;background-color:white'  data-id="+i+">OptionOne#"+i+"</span></div>";
            $("#phrase").append(html);
      }
      
    }
    else {
      for (j = 0; j < 8; j++) {
         
        html = "<div data-id="+j+"><span class='words'  style='color:black;background-color:white' data-id="+j+">OptionTwo#"+j+"</span></div>";
       $("#phrase").append(html);
    }
   // $("#phrase").append(html);
  }
}


  $(".words").draggable({
    revert: function (event, ui) {
      var bRevertingPhrase = this.closest("#drop-em");

      if (!bRevertingPhrase.length) {
        var phraseID = $(this).data("id");
        var phraseHomeID = $(this).parent().data("id");

        //If the child and parent ids don't match, we move the child to the correct parent
        if (phraseID !== phraseHomeID) {
          var correctCell = $("#phrase").find(
            "div[data-id='" + phraseID + "']"
          );
          correctCell.prepend(this);
        }
      }
      return !event;
    },
  });
  $("#drop-em > div").droppable({
    drop: function (ev, ui) {
      $(ui.draggable)
        .detach()
        .css({ top: 0, left: 0 })
        .appendTo($(this).find(".content:empty"));
      //$("#move-text").addClass("disabled");
    },
  });
  $("#phrase > div").droppable({
    drop: function (ev, ui) {
      $(ui.draggable).detach().css({ top: 0, left: 0 }).prependTo(this);
    },
  });

  const myButton = document.querySelector("#move-text");
  myButton.addEventListener("click", () => {
        /* To Validate:
        Case #1: If the cell value for starting square already exists
        then, you cannot fill it
        
        Case #2: Check for all the values that are about to be moved on to
        the squares. If anyone of these overlap with already existing value of the grid
        then you cannot fill it
        */

        /* Get all values that needs to be tested 
       */

        var childDivs = document
            .getElementById("phrase")
            .querySelectorAll("div:has(> span[data-id])");

        console.log(childDivs);

        // get the calculated value of the cell number
        let testValue = document.querySelector("#cellnum").innerHTML;

        console.log("Test Value");
        console.log(testValue);
        let integerValue = parseInt(testValue);

        // create an array of values to be tested.
        const valueArray = [];
        for (i = 0; i < childDivs.length; i++) {
            valueArray.push(integerValue + i);
        }



        for (j = 0; j < valueArray.length; j++) {
            var getDivWithValue = document
                .getElementById("drop-em")
                .querySelectorAll('div:has(> span[data-id="' + valueArray[j] + '"])');



            if (getDivWithValue.length > 0) {
                console.log("A value already exists for cell value " + valueArray[j]);

                alert("Starting Square or other Square needed to complete the move are already in use.Please use different Starting Cell Value");
                return;
            }
        }


        fill();
    },

    );

  var reOrder = [];
  function fill() {
    const cells = document.querySelectorAll("#phrase > div > span");
    var newLoc = "";
    //myButton.classList.add("disabled");

    cells.forEach((cell, index) => {
      newLoc = document.querySelector(
        ".item:nth-child(" + reOrder[index + startPos - 1] + ") .content "
      );
      newLoc.append(cell);
      newLoc.classList.add("moved");
       newLoc.classList.add("color-"+selectedColor);
      $('.color-'+selectedColor).css('background-color',selectedColor);
      
    });
  }
  function reArrange() {
    var limit1 = 85;
    var limit2 = 91;

    for (let loop = 0; loop < 8; loop++) {
      for (let i = 0; i < 6; i++) {
        reOrder.push(limit1 + i);
      }
      limit1 = limit1 - 12;
    }
    for (let loop = 0; loop < 8; loop++) {
      for (let j = 0; j < 6; j++) {
        reOrder.push(limit2 + j);
      }
      limit2 = limit2 - 12;
    }
  }
  reArrange();

  /* get cell number */

  const myRow = document.querySelector("#inp1");
  const myCol = document.querySelector("#inp2");
  var startPos = 0;
  const myCalculateButton = document.querySelector("#calculate");
  const myAnswer = document.querySelector("#cellnum");
  myCalculateButton.addEventListener("click", () => {
    var rowNumber = myRow.value.toUpperCase();
    var colNumber = myCol.value;
    var result = 0;
    switch (rowNumber) {
      case "A":
        rowNumber = 42;
        break;
      case "B":
        rowNumber = 36;
        break;
      case "C":
        rowNumber = 30;
        break;
      case "D":
        rowNumber = 24;
        break;
      case "E":
        rowNumber = 18;
        break;
      case "F":
        rowNumber = 12;
        break;
      case "G":
        rowNumber = 6;
        break;
      case "H":
        rowNumber = 0;
        break;
    }

    if (colNumber < 7) {
      result = rowNumber + parseInt(colNumber);
    } else {
      result = rowNumber + 42 + parseInt(colNumber);
    }
    myAnswer.innerHTML = result;
    startPos = result;
  });
  
 
html {
    box-sizing: border-box;
  }
  *,
  *:before,
  *:after {
    box-sizing: inherit;
  }
  body {
    counter-reset: columnCount 1 alphaCount cellCount;
  }
  h1 {
    text-align: center;
  }
  .wrap {
    display: flex;
    gap: 2rem;
    position: relative;
    padding-left: 220px;
  }

  .grid {
    margin: auto;
    display: grid;
    flex: 1 0 0;
    grid-template-columns: repeat(12, 1fr);
    padding-top: 1.5rem;
  }

  .item {
    position: relative;
    background-color: #f9f9f9;
    border: 1px solid grey;
    aspect-ratio: 1/1;
    counter-increment: columnCount;
    min-width: 0;
    transition: background 1s ease;
  }
  .item:nth-of-type(12n + 1) {
    counter-increment: alphaCount;
  }
  .item:nth-of-type(12n + 1)::before {
    content: counter(alphaCount, upper-alpha);
    position: absolute;
    display: flex;
    align-items: center;
    top: 0;
    bottom: 0;
    left: -1.75rem;
    color: red;
    pointer-events: none;
  }
  .item:nth-of-type(n + 13)::after {
    display: none;
  }
  .item::after {
    content: counter(columnCount);
    position: absolute;
    left: 0;
    right: 0;
    text-align: center;
    top: -1.75rem;
    color: red;
    pointer-events: none;
  }
  .content {
    display: flex;
    flex-direction: column;
    justify-content: center;
    width: 100%;
    height: 100%;
    overflow: auto;
    color: #000;
    padding: 1rem;
    word-wrap: break-word;
    counter-increment: cellCount;
  }

  .words {
    cursor: move;
    transition: padding 0.5s ease;
   }
     
  .content:has(.ui-draggable-dragging) {
    overflow: visible;
  }
  .ui-droppable-active .content {
    overflow: visible;
  }
  .words.ui-draggable-dragging {
    background: blue;
    padding: 5px 10px;
    border-radius: 6px;
    z-index: 999;
    color: #fff;
    display: block;
    width: 50px;
    height: 50px;
    overflow: hidden;
  }
  #phrase {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    color: #fff;
    width: 150px;
    overflow: auto;
    z-index: 2;
    display: flex;
    flex-direction: column;
    margin: 1rem 0 0.5rem;
  }
  #phrase > div {
    margin: 0 0 10px;
    width: 150px;
    padding: 5px 10px;
    background: #007bff;
    border: 2px solid #007bff;
    border-radius: 6px;
    color: #fff;
  }
  #phrase > div:empty {
    background: #fff;
    border-style: dashed;
    padding: 0px 25px;
    min-height: 30px;
  }

  .moved {
    animation: fade 3s ease;
  }
  @keyframes fade {
    0% {
      opacity: 0;
    }
    50% {
      opacity: 1;
      background: red;
    }
  }

  .item .content::before {
    content: counter(cellCount);
    position: absolute;
    top: 2px;
    left: 2px;
    font-size: smaller;
    color: #666;
    border-radius: 50%;
    border: 1px solid red;
    background: white;
    width: 1.2rem;
    height: 1, 2rem;
    display: grid;
    place-items: center;
  }

  #move-text.disabled {
    cursor: none;
    pointer-events: none;
    opacity: 0.5;
  }
  #phrase:has(.ui-droppable-active) {
    overflow: visible;
  }

  input,
  button,
  label,
  p.target {
    display: block;
    margin: 0 0 0.4rem;
    color: #000;
  }
  p.target {
    margin: 0 0 1rem;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
  <!-- You'd need to set up something different for touch devices though -->

  <h1>Move testings</h1>
  <div class="wrap">
    <div>
      <label for="optionSelection">Select options</label>
      <select name="optionSelection" id="optionSelection">
        <option value="1">OptionOne</option>
        <option value="2">OptionTwo</option>
      </select>
    </div>
    <div>
    <label for="lineupColors">Colors:<br /></label>
    <select id="lineupColors">
       <option value="-">select</option>
      <option value="blue">Blue</option>
      <option value="orange">Orange</option>
      <option value="red">Red</option>
      <option value="green">Green</option>
      <option value="purple">Purple</option>
      <option value="brown">Brown</option>
      <option value="black">Black</option>
      <option value="magenta">Magenta</option>
    </select>
  </div>
    <div>
      <button id="showOptions" onclick="showOptions()" type="button">
        Show Options
      </button>
    </div>
    <div>
      <label for="inp1">Enter a row A - H</label>
      <input id="inp1" placeholder="Enter Row" />
      <label for="inp2">Enter a column 1 - 12</label>
      <input id="inp2" placeholder="Enter Column" />
      <button id="calculate">Calculate</button>
      <p class="target">The cell number is <b id="cellnum">?</b></p>
        <label for="barcode">Barcode</label>
      <input id="barcode" placeholder="" />
        <label for="pName">Plate Name</label>
      <input id="pName" placeholder="" />
      <button id="move-text" type="button">Move Text Content!</button>
    </div>
    <div id="phrase">
      <!-- remove whitespace from  inside div html and then we can use :empty in css to change background -->
      <!-- <div data-id="1"><span class="words" data-id="1">H1 text</span></div>
      <div data-id="2"><span class="words" data-id="2">H2 text</span></div>
      <div data-id="3"><span class="words" data-id="3">H3 text</span></div>
      <div data-id="4"><span class="words" data-id="4">H4 text</span></div>
      <div data-id="5"><span class="words" data-id="5">H5 text</span></div>
      <div data-id="6"><span class="words" data-id="6">H6 text</span></div>
      <div data-id="7"><span class="words" data-id="7">G1 text</span></div>
      <div data-id="8"><span class="words" data-id="8">G2 text</span></div>
      <div data-id="9"><span class="words" data-id="9">G3 text</span></div>
      <div data-id="10"><span class="words" data-id="10">G4 text</span></div> -->
    </div>

    <div id="drop-em" class="grid">
      <div class="item">
        <div class="content"></div>
        <!-- must have no spaces inside .content -->
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
      <div class="item">
        <div class="content"></div>
      </div>
    </div>
  </div>

how to add usernames to firebase (authentication) [duplicate]

I’m new to using firebase. I want users on my website to have to use a username, password, and email to sign up and sign in. In that way, in the future, I can make profiles and display usernames on a leaderboard. Currently they only need need to enter an email and password. How do i change this?

Heres my code


// Import the functions you need from the SDKs you need
import { initializeApp } from "https://www.gstatic.com/firebasejs/10.11.1/firebase-app.js";
import { getAnalytics } from "https://www.gstatic.com/firebasejs/10.11.1/firebase-analytics.js";
import { 
    getAuth, 
    createUserWithEmailAndPassword,
    signInWithEmailAndPassword,
    onAuthStateChanged,
    signOut
} from "https://www.gstatic.com/firebasejs/10.11.1/firebase-auth.js"

const firebaseConfig = {
  apiKey: "AIzaSyDW9v17UJm3ry7ccV7bz1To2NZdOdYBBV0",
  authDomain: "tech-2024.firebaseapp.com",
  databaseURL: "https://tech-2024-default-rtdb.asia-southeast1.firebasedatabase.app",

  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
  measurementId: ""
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
const auth = getAuth(app);
const userEmail = document.querySelector("#userEmail");
const userPassword = document.querySelector("#userPassword");
const authForm = document.querySelector("#authForm")
const content = document.querySelector("#content");
const signUpButton = document.querySelector("#signUpButton");
const signInButton = document.querySelector("#signInButton");
const signOutButton = document.querySelector("#signOutButton");

content.style.display ="none";

const userSignUp = async() => {
    const signUpEmail =userEmail.value 
    const signUpPassword =userPassword.value 
    createUserWithEmailAndPassword ( auth, signUpEmail, signUpPassword)
    .then (( userCredential) => {
        const user  = userCredential.user;
        console.log( user);
        alert (" your account has been created!");
    } )
    .catch ((error)=> {
        const errorCode = error.code;
        const errorMessage = error.message; 
        console.log(errorCode + errorMessage)
        alert ( errorMessage);
    

    } )
    
}

const userSignIn = async () => {
    const signInEmail = userEmail.value;
    const signInPassword = userPassword.value;
    signInWithEmailAndPassword(auth, signInEmail, signInPassword)
        .then((userCredential) => {
            const user = userCredential.user;
            alert("You have signed in");
            window.location.href = "index.html"; // Redirect to index.html
        })
        .catch((error) => {
            const errorCode = error.code;
            const errorMessage = error.message;
            console.log(errorCode + errorMessage);
            alert(errorMessage);
        });
};

const checkAuthState =async() => {
    onAuthStateChanged(auth,user => { 
        if(user){
            authForm.style.display ='none';
            content.style.display = 'block';

        }
        else {
            authForm.style.display ='block';
            content.style.display = 'none';
        }
   
})
}
const userSignOut = async() => {
    signOut(auth).then(() => {
        alert("You have signed out successfully!");
    }).catch((error) => {})
  }

  onAuthStateChanged(auth, (user) => {
    if(user) {
      signOutButton.style.display = "block";
      message.style.display = "block";
      userName.innerHTML = user.displayName;
      userEmail.innerHTML = user.email
    } else {
      signOutButton.style.display = "none";
      message.style.display = "none";
    }
  })

  signInButton.addEventListener('click', userSignIn);
  signUpButton.addEventListener('click', userSignUp);
  signOutButton.addEventListener('click', userSignOut);,

this the relevant html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>auth</title>
    <style> body { text-align: center; background-color: lightblue }</style>
</head>

<body>
    <div id="authForm">
        <h2> sign up or sign in</h2>
        <input type="email" placeholder="email" id="userEmail" >
        <input type="password" placeholder="password" id="userPassword"> <br> <br>
        <button id="signUpButton"> sign up</button>
        <button id="signInButton"> sign in</button>
    </div>
    <div id="content">
        <h2> suprise </h2>
        <button id="signOutButton"> sign out</button>
    </div>
    
    <script type="module"  src="auth.js">
        </script>
</body>
</html>

i have tried changing the userSignUp and userSignIn code

const userSignUp = async () => {
    const signUpEmail = userEmail.value;
    const signUpPassword = userPassword.value;
    const signUpUsername = userName.value; // Get the username input value
    createUserWithEmailAndPassword(auth, signUpEmail, signUpPassword)
        .then((userCredential) => {
            const user = userCredential.user;
            // Update display name with the provided username
            user.updateProfile({
                displayName: signUpUsername
            }).then(() => {
                console.log("User profile updated successfully!");
            }).catch((error) => {
                console.log(error.message);
            });
            console.log(user);
            alert("Your account has been created!");
        })
        .catch((error) => {
            const errorCode = error.code;
            const errorMessage = error.message;
            console.log(errorCode + errorMessage);
            alert(errorMessage);
        });
};
const userSignIn = async () => {
    const signInEmail = userEmail.value;
    const signInPassword = userPassword.value;
    const signInUsername = userName.value; // Get the username input value
    const credential = signInEmail ? signInWithEmailAndPassword(auth, signInEmail, signInPassword) : null;

    if (credential) {
        credential.then((userCredential) => {
            const user = userCredential.user;
            // Check if the username matches the one associated with the user
            if (user.displayName === signInUsername) {
                alert("You have signed in");
                window.location.href = "index.html"; // Redirect to index.html
            } else {
                alert("Incorrect username or password");
            }
        }).catch((error) => {
            const errorCode = error.code;
            const errorMessage = error.message;
            console.log(errorCode + errorMessage);
            alert(errorMessage);
        });
    } else {
        alert("Please enter your email and password");
    }
};

What framework(s) to improve my web app? Currently using react.js

Currently I have just about my full web app built out in React using mostly just javascript and css.

While the functionality is fine, I feel like its really lacking a very fluid user interaction and experience.

Am I limiting myself by just using React and javascript?

For my backend im utilizing heroku and firestore.

For reference, my site is an AI GPT app where users can easily create there own assistants and chat with them.My project site

Ive been using react.js and just utilizing javascript and html. I’m fairly new to developing, but most videos I see the developers use jsx and typescript.

Any and all feedback is great and I have linked my site to see what it currently looks like too

Unable to use removeEventListener() to remove a handler from an element

I’ve added a “click” event listener to a “Delete” button.

deleteButton.addEventListener("click", deleteNote);

This event listener when triggered calls the function below:

let deleteEnabled = false; // global variable

const deleteNote = function () {
  deleteEnabled = !deleteEnabled;
  const noteElements = document.querySelectorAll(".note");

  const setDeleteBorder = function (e) {
    e.target.style.border = "5px solid red";
    e.target.style.borderRadius = "10px";
    e.target.style.cursor = "pointer";
  };

  if (deleteEnabled) {
    noteElements.forEach((el) => {
      el.addEventListener("mouseenter", (e) => setDeleteBorder(e));
      el.addEventListener("mouseleave", (e) => {
        e.target.style.border = "";
        e.target.style.borderRadius = "";
      });
    });
  } else if (!deleteEnabled) {
    noteElements.forEach((el) =>
      el.removeEventListener("mouseenter", (e) => setDeleteBorder(e))
    );
  }
};

The function works, and will add both the mouseenter and mouseleave event listeners to the array of elements, but when the deleteButton is pressed again mouseenter will not be removed by the removeEventListener.

At first i’ve thought it was a problem with the global variable not being toggled correctly, but when checking the console i’ve found out that multiple event listeners are being added, and removeEventListener is not removing any of them.

What could be causing this? Could it be a problem related to this pointing to the wrong element? Or is there something i am misunderstanding about removeEventListener?

So far, i’ve tried using console.log() to verify the value of the deleteEnabled variable, i’ve also tested with addEventListener and removeEventListener with another element on the global scope and i’ve managed to remove the event listener in that test. I’ve also tried renaming the handler that is being used with the event listener. Nothing i’ve tried so far has worked, and when i press the button, the same event handler keeps being added on top of the element.

Java script codes [closed]

enter image description here

Can you give me the code?

  1. Create a class called car.
    Each car has:
    a cusromer name rowner name
    a type (BMW, Mazda, or Toyota) a colour White. Red. or Silver)
    a status used. new
    an amount a price
    tax (a percentage -> between 0 and 1)
    Note that:
    Type and colour can be defined as static integers
    Status can be defined as Boolean
    The class has
    one constructor that takes values for all these data rields.
    b. A getPrice() method that returns the price of the car that returns the price of the car
    after the tax (car price = amount + (amount* tax))
    An overridden toString0 method
    All required setters and getters.
    [ Practical Final
    Customer Name
    Car Tune
    status
    BMW
    White
    O used
    O new
    Add
    Clear
    Print List
    Write to File
  2. Create a class that creates the GUI for this project, as shown in the picture.
    The buttons on this GUE
    a. Add: creates a new Car object with the data that is taken from the text fields, combo boxes and radio buttons, and adds it to an array list.
    Clear: clears all the data written in the text fields.
    c. Print List: prints the data about each car in the array list using the toString method in the Car class to the text area in the GUI

How to embed a TikTok mobile link to my web website?

I have a website that allows users to create trip itineraries. One of the features is embedding TikTok videos of points of interest into the site. However, according to TikTok’s documentation for developers, only links from a browser are compatible, not the links generated when you share a video from the app.

This limitation complicates the user experience from mobile users, so it makes this feature very unatractive there. I’m wondering if there’s a way to convert a mobile link into a web link using pure JavaScript.

Currently, the only solution I’ve found is implementing a server-side solution using Node.js. However, my app only has a JavaScript front-end and communicates with Firebase to get/update the data.

Are there any alternatives?

I’ve tried using the mobile link as is, but just as the documentation states, it did not work.

I’ve also tried doing an async function with pure js to open the page in an iframe and get the link, but CORS won’t allow it.

Why ReqRes response to my POST request doesn’t return the values I included?

I’m learning about API etc, and I was trying to do a simple POST request to ReqRes.in. Although the POST response suggests that the request was successful, it doesn’t include the data I’m sending, which is not the behavior expected according to the documentation…

My code:

<script>
function startAPI() {
  let xhttp;
  xhttp = new XMLHttpRequest;
  xhttp.onreadystatechange = () => {
    if (xhttp.readyState == 4) {
      if (xhttp.status == 201) {
        let reqresponse = JSON.parse(xhttp.responseText);
        console.log(reqresponse)
      };
    };
  };
  let newUser = {
    name: document.querySelector("#userName").value,
    email: document.querySelector("#userEmail").value,
  };
  xhttp.open('POST', 'https://reqres.in/api/users', true);
  xhttp.send(JSON.stringify(newUser));
};
</script>
<body>
<form onsubmit="startAPI(); return false">
  <p>
    <label for="userName">Nome: </label>
    <input type="text" name="userName" id="userName">
  </p>
  <p>
    <label for="userEmail">Email: </label>
    <input type="email" name="userEmail" id="userEmail">
  </p>
  <p>
    <input type="submit" value="Create User">
  </p>
</form>
</body>

On submitting, I was expecting this response:

Object { name: "User Input Value", email: "Email Input Value", id: "848", createdAt: "2024-05-09T01:17:49.098Z" }

But what I receive is:

Object { id: "848", createdAt: "2024-05-09T01:17:49.098Z" }

I tested several combinations of ID, values capturing, methods of form submit, variables and function names, removal of If’s in the function etc, nothing worked.
What am I doing wrong?

Thanks everyone, peace.

Extracting page metadata when converting DOCX to HTML (javascript)

I’m working on a Vue page where I need to convert DOCX files to HTML while preserving page metadata (e.g., page numbers, section breaks).

I’ve explored libraries like Mammoth.js, but it seems they don’t handle page metadata extraction. Other libraries I found primarily focus on DOCX to HTML conversion without retaining pagination information. The issue is still open here.

vue-document-editor offers functionalities for creating page breaks using arrays, but this doesn’t support docx conversion to html.

Is there a way to achieve DOCX to HTML conversion with page metadata extraction (preferably in JS/Vue application)?

How to execute a function if a loop is taking a long time?

I have an AJAX call, and the result is processed by a callback. This may be real quick, or take some time. If the callback lasts more than 3 seconds, I want to display an image (or a text) that tell the user “please wait!”.

This is what I have:

var process_timer, is_processing = false;
var request = createCORSRequest();
if (request) {
    // This SETTIMEOUT function should execute 3 seconds after REQUEST.SEND()
    process_timer = setTimeout(function(){
        if (is_processing) {
            // It's still processing, so we show the message
            show_please_wait();
        }
    },3000);
    request.onload = function() {
        process(JSON.parse(request.responseText));
        // OK, processing is done, so we reset everything
        is_processing = false;
        // If SETTIMEOUT didn't fire yet, we cancel it so no image will ever show
        clearTimeout(process_timer);
        // We hide the message anyway, just in case it was displayed
        hide_please_wait();
    };
    is_processing = true;
    request.send();
}

What is happening:

  • REQUEST.SEND() works fine
  • REQUEST.ONLOAD() works fine
  • … but the SHOW_PLEASE_WAIT() function never gets executed, no matter how long the process lasts.
    What am I doing wrong?

Can we make a button stay still when you move your screen around or scroll up/down on a tablet?

This code work well on a traditional computer with non-touch screen.

`<style>
    #stayFixedDiv{
      background-color: #FBD603;
      position: fixed;
      left: 40px;
    }
    </style>

    <body>
    <div id ="stayFixedDiv">
     <a   style="font-size: 35px; text-decoration: none" > Pause Video</a>
    </div>

    </body>
`

But that code does not work on a tablet. When I move the screen on my tablet around, the button doesn’t stay still as on my desktop.

How can we achieve that?