Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 7155

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 60k
Author
Asked: November 28, 20242024-11-28T01:10:09+00:00 2024-11-28T01:10:09+00:00

Password Reset Feature: Frontend

  • 60k

Frontend

The frontend part is very easy compared to the backend part. All I need to do is create a modal, and use it to send data twice.

  • Firstly send email to send OTP to
  • Then send the OTP and the new password to change it

To create the modal, I copied some code, the classNames for the encapsulation of a modal, from the MessageModal component in my earlier project Chat-Nat.

Planning

I'll add a “Forgot Password?” button on the login page, and set the onClick handler to open the modal

I need to use a boolean state to denote whether the OTP has been sent to the user's email before asking for it. I'm naming the state isOTPSent

  • If !isOTPSent -> just ask for the email address, send api req, then if successful setOTPSent(true)
  • If isOTPSent -> now also ask for the OTP and the new password, then if successful, close the modal

Here are a few components and hooks that I'm reusing from the existing frontend of this project:

  • Box -> It neatly wrapped my login and register pages into a card, centered on the page, reusing here with title "Password Reset"
  • AuthForm -> Just a form but I coded it to disable the submit button and set button text to "Loading..." when we are waiting on a response from the server
  • FormInput -> Input field with a label of its own, with value setter and onChange handler, optionally with an isRequired boolean
  • useAxios -> Custom hook to handle the responses from the server which needs a token refresh. apiReq function for the normal request sending, some custom error handling to display an alert() and refresh token, refreshReq function to refresh the auth token and try the initial request again.

Here's the entire code for the modal:

// src/components/PasswordResetModal.tsx import React, { useState } from "react" import AuthForm from "./AuthForm"; import FormInput from "./FormInput"; import Box from "./Box"; import { useAxios } from "../hooks/useAxios";  interface FormData {     email: string,     new_password: string,     otp: string, }  interface Props {     isVisible: boolean,     onClose: () => void, }  const PasswordResetModal: React.FC<Props> = ({ isVisible, onClose }) => {     const [formData, setFormData] = useState<FormData>({         email: "",         new_password: "",         otp: ""     });     const [isLoading, setLoading] = useState<boolean>(false);     const [isOTPSent, setOTPSent] = useState<boolean>(false);     const { apiReq } = useAxios();      const handleClose = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {         if ((e.target as HTMLElement).id === "wrapper") {             onClose();              // could have setOTPSent(false), but avoiding it in case user misclicks outside         }     };      const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {         const { name, value } = e.target;         setFormData({             ...formData,             [name]: value,         });     };      const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {         e.preventDefault();         setLoading(true);          if (!isOTPSent) { // first request for sending otp,             const response = await apiReq<unknown, FormData>("post", "/api/reset-password", formData)              if (response) {                 alert("OTP has been sent to your email");                 setOTPSent(true);             }         } else { // then using otp to change password             const response = await apiReq<unknown, FormData>("put", "/api/reset-password", formData)              if (response) {                 alert("Password has been successfully reset
Please log in again");                  // clear the form                 setFormData({                     email: "",                     otp: "",                     new_password: "",                 })                  // close modal                 onClose();             }         }          setLoading(false);     };      if (!isVisible) return null;      return (         <div             id="wrapper"             className="fixed inset-0 bg-black bg-opacity-25 backdrop-blur-sm flex justify-center items-center"             onClick={handleClose}>             <Box title="Password Reset">                 <AuthForm                     submitHandler={handleSubmit}                     isLoading={isLoading}                     buttonText={isOTPSent ? "Change Password" : "Send OTP"}>                     <FormInput                         id="email"                         label="Your email"                         type="email"                         value={formData.email}                         changeHandler={handleChange}                         isRequired />                      {isOTPSent && (<>                         <FormInput                             id="otp"                             label="OTP"                             type="text"                             value={formData.otp}                             changeHandler={handleChange}                             isRequired />                         <FormInput                             id="new_password"                             label="New Password"                             type="password"                             value={formData.new_password}                             changeHandler={handleChange}                             isRequired />                     </>)}                 </AuthForm>             </Box>         </div>     ) }  export default PasswordResetModal 
Enter fullscreen mode Exit fullscreen mode

And here's how the conditional rendering of the modal is handled in the Login form

// src/pages/auth/Login.tsx import PasswordResetModal from "../../components/PasswordResetModal";  const Login: React.FC = () => {     const [showModal, setShowModal] = useState<boolean>(false);      return (         <Section>             <Box title="Login">                 <div className="grid grid-flow-col">                     {/* link to the register page here */}                     <button                      type="button"                     onClick={() => setShowModal(true)}                     className="text-blue-700 hover:text-white border border-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-3 py-2 text-center me-2 mb-2 dark:border-blue-500 dark:text-blue-500 dark:hover:text-white dark:hover:bg-blue-500 dark:focus:ring-blue-800">                         Forgot Password?                     </button>                      <PasswordResetModal isVisible={showModal} onClose={() => setShowModal(false)} />                 </div>             </Box>         </Section>     ) 
Enter fullscreen mode Exit fullscreen mode


We're done! Or so I thought.

While running the app in my development environment, I discovered a bug where the emails wouldn't go through if the backend has been running since a long time.

We'll fix this bug in the next post

javascriptreacttypescriptwebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 2k
  • Popular
  • Answers
  • Author

    ES6 - A beginners guide - Template Literals

    • 0 Answers
  • Author

    Understanding Higher Order Functions in JavaScript.

    • 0 Answers
  • Author

    Build a custom video chat app with Daily and Vue.js

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.