Login button doesn't take effect when clicked - reactjs

I am a total beginner in react and I have set up a an authentication system in my react webapp which is connected to a mongodb database.
I can successfully register but I can't login with the user details which have been registered - means, that nothing happens when I click the Login button.
RequireAuth.jsx:
import { Navigate } from "react-router-dom";
import { useAuth } from './auth';
function getToken() {
return localStorage.getItem('token');
}
function getInternalData() {
return JSON.parse(localStorage.getItem('internalData'));
}
export const RequireAuth = ({ children }) => {
const auth = useAuth();
if (!getToken()) {
return <Navigate to="/login" />;
}
return children;
};
export const RequireLogOut = ({ children }) => {
const auth = useAuth();
if (getToken()) {
return <Navigate to="/home" />;
}
return children;
};
export { getToken, getInternalData };
auth.jsx:
import {useState, useContext, createContext } from "react";
const AuthContext = createContext(null);
export const AuthProvider = ({children }) => {
const [token, setToken] = useState("");
const login = (token, internalData) => {
console.log(token);
localStorage.setItem('token', JSON.stringify(token));
localStorage.setItem('internalData', JSON.stringify(internalData));
setToken(token);
};
const logout = () => {
localStorage.removeItem('token');
localStorage.removeItem('internalData');
setToken("");
}
return <AuthContext.Provider value={{token, login, logout}}>{children}</AuthContext.Provider>
};
export const useAuth = () => {
return useContext(AuthContext);
};
login.jsx:
import { useState } from 'react';
import { useNavigate, Link } from 'react-router-dom'
import { useAuth } from './auth';
import axios from 'axios'
import { LockClosedIcon } from '#heroicons/react/24/solid'
import { RequireAuth, RequireLogOut } from "./RequireAuth";
async function loginUser(credentials) {
return fetch('http://localhost:4000/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(credentials)
})
.then(data => data.json())
}
export default function LoginForm() {
const [loginValues, setLoginValues] = useState({ email: "", password: "" });
const navigate = useNavigate()
const [error, setError] = useState("");
const auth = useAuth();
const handleChange = (e) => {
const { name, value } = e.target;
const newValues = { ...loginValues, [name]: value };
console.log(newValues);
setLoginValues(newValues);
};
const handleSubmit = async e => {
e.preventDefault();
//const token = await loginUser(loginValues);
const tokenData = await axios.post('http://localhost:4000/login/', loginValues);
console.log(tokenData.data)
if (tokenData.data.success) {
setError("");
auth.login(tokenData.data.token, tokenData.data.internalData);
}
else {
setError("Credentials are incorrect. Try again");
}
}
return (
<>
<div className="min-h-full flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-md w-full space-y-8">
<div>
<img
className="mx-auto h-36 w-auto"
src="/images/logo.png"
alt="Workflow"
/>
<h2 className="mt-6 text-center text-3xl tracking-tight font-bold text-gray-900">
Sign in to your account
</h2>
<p className="mt-2 text-center text-sm text-gray-600">
Or{' '}
<a href="http://localhost:3000/register" className="font-medium text-gameblue hover:text-gamebluehover">
don't have an account yet?
</a>
</p>
</div>
{error ? <div>{error}</div> : ""}
<form onSubmit={handleSubmit} className="mt-8 space-y-6" action="#" method="POST">
<input type="hidden" name="remember" defaultValue="true" />
<div className="rounded-md shadow-sm -space-y-px">
<div>
<label htmlFor="email-address" className="sr-only">
Email address
</label>
<input
onChange={handleChange}
value={loginValues.email}
id="email-address"
name="email"
type="email"
autoComplete="email"
required
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-indigo-500 focus:border-gameblue focus:z-10 sm:text-sm"
placeholder="Email address"
/>
</div>
<div>
<label htmlFor="password" className="sr-only">
Password
</label>
<input
onChange={handleChange}
value={loginValues.password}
id="password"
name="password"
type="password"
autoComplete="current-password"
required
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-indigo-500 focus:border-gameblue focus:z-10 sm:text-sm"
placeholder="Password"
/>
</div>
</div>
<div className="flex items-center justify-between">
<div className="flex items-center">
<input
id="remember-me"
name="remember-me"
type="checkbox"
className="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded"
/>
<label htmlFor="remember-me" className="ml-2 block text-sm text-gray-900">
Remember me
</label>
</div>
<div className="text-sm">
<a href="#" className="font-medium text-gameblue hover:text-gamebluehover">
Forgot your password?
</a>
</div>
</div>
<div>
<button
type="submit"
className="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-gameblue hover:bg-gamebluehover focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
<span className="absolute left-0 inset-y-0 flex items-center pl-3">
<LockClosedIcon className="h-5 w-5 text-gamebluelight group-hover:text-gamebluelightest" aria-hidden="true" />
</span>
Sign in
</button>
</div>
</form>
</div>
</div>
</>
);
}

Related

Black screen in react code - possible firebase auth issue

this code is giving me a blank screen i have no idea as to why i would assume its firebase auth or the logic giving me trouble im running this in vscode and its compiling sucessfully
import { createUserWithEmailAndPassword } from "firebase/auth";
import React, { useState } from "react";
import { auth } from "../firebase";
import { Link } from "react-router-dom";
const SignUp = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [name, setName] = useState("");
const [error, setError] = useState("");
const signUp = (e) => {
e.preventDefault();
auth.createUserWithEmailAndPassword(email, password).then((userCredential) => {
userCredential.user
.updateProfile({
displayName: name,
})
.then(() => {
console.log("user name added");
})
.catch((error) => {
console.log(error);
});
})
.catch((error) => {
setError(error.message);
});
};
return (
<div className="container mx-auto flex justify-center pt-6">
<form className="bg-white p-6 rounded-lg shadow-xl" onSubmit={signUp}>
<div className="mb-4">
<label
className="block text-gray-700 font-medium mb-2"
htmlFor="name"
>
Name
</label>
<input
className="w-full border border-gray-400 p-2 rounded-md"
id="name"
type="text"
placeholder="Enter your name"
onChange={(e) => setName(e.target.value)}
/>
</div>
<div className="mb-4">
<label
className="block text-gray-700 font-medium mb-2"
htmlFor="email"
>
Email
</label>
<input
className="w-full border border-gray-400 p-2 rounded-md"
id="email"
type="email"
placeholder="Enter your email"
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="mb-4">
<label
className="block text-gray-700 font-medium mb-2"
htmlFor="password"
>
Password
</label>
<input
className="w-full border border-gray-400 p-2 rounded-md"
id="password"
type="password"
placeholder="Enter your password"
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<div className="text-red-500 text-xs mb-4">{error}</div>
<button
className="bg-indigo-500 hover:bg-indigo-600 text-white py-2 px-4
rounded-md"
type="submit"
>
Sign Up
</button>
<Link
to="/login"
className="text-indigo-500 hover:text-indigo-600 font-medium py-2 px-4"
>
Already have an account?
</Link>
</form>
</div>
);
};
export default SignUp;
was trying to make a signup page for my website that took in email and password to authenticate but also took a name to display on profile

Uncaught TypeError: Cannot destructure property 'connectWallet' of 'useContext(...)' as it is undefined

So basically when i try to fill the form and exchange between two accounts , nothing happens
and when i check the console sometimes there's no error appearing and sometimes there's this one "Uncaught TypeError: Cannot destructure property 'connectWallet' of 'useContext(...)' as it is undefined." , and there's no data being destructered and sent to the browser , it's empty enter image description here
and it triggers "no accounts found"
this is the console after and click "send"
enter image description here
this is my code:
TransactionContext.jsx :
import React, {useEffect, useState} from 'react';
import {ethers} from 'ethers';
import {contractABI, contractAddress} from '../utils/constants';
export const TransactionContext = React.createContext();
const {ethereum} = window;
const getEthereumContract = () => {
const provider = new ethers.providers.Web3Provider(ethereum);
const signer = provider.getSigner();
const transactionContract = new ethers.Contract(contractAddress, contractABI, signer);
return transactionContract;
}
export const TransactionProvider = ({children}) => {
const [currentAccount, setCurrentAccount] = useState('');
const [formData, setFormData] = useState({addressTo: '', amount: '', keyword: '', message: ''});
const [isLoading, setIsLoading] = useState(false);
const [transactionCount, setTransactionCount] = useState(localStorage.getItem('transactionCount'));
const handleChange = (e, name) => {
setFormData((prevState) => ({ ...prevState, [name]: e.target.value }));
}
const checkIfWalletIsConnected = async () => {
try{
if(!ethereum) return alert("please install metamask");
const accounts = await ethereum.request({method: 'eth_accounts'});
if(accounts.length) {
setCurrentAccount(accounts[0]);
}
else {
console.log('no accounts found');
}
}
catch (error) {
console.log(error);
throw new Error("No ethereum object.")
}
};
const connectWallet = async () => {
try{if(!ethereum) return alert("please install metamask");
const accounts = await ethereum.request({method: 'eth_requestAccounts'});
setCurrentAccount(accounts[0]);}
catch (error){
console.log(error);
throw new Error("No ethereum object.")
}
}
const sendTransaction = async () => {
try{if(!ethereum) return alert("please install metamask");
const {addressTo, amount, keyword, message } = formData;
const transactionContract = getEthereumContract();
const parseAmount = ethers.utils.parseEther(amount);
await ethereum.request({
method: 'eth_sendTransaction',
params: [{
from: currentAccount,
to: addressTo,
gas: '0x5208',
value: parseAmount._hex,
}]
});
const transactionHash = await transactionContract.addToBlockChain(addressTo, parseAmount, message, keyword);
setIsLoading(true);
console.log('Loading - ${transactionHash.has}');
await transactionHash.wait();
setIsLoading(false);
console.log('success - ${transactionHash.has}');
const transactionCount = await transactionContract.getTransactionCount();
setTransactionCount(transactionCount.toNumber());
}
catch(error) {
console.log(error);
throw new Error("No ethereum object.")
}
}
useEffect( () => {
checkIfWalletIsConnected();
}, []);
return (
<TransactionContext.Provider value={{connectWallet, currentAccount, formData, setFormData, handleChange, sendTransaction}}>
{children}
</TransactionContext.Provider>
);
}
Welcome.jsx
import {AiFillPlayCircle} from 'react-icons/ai';
import {SiEthereum} from 'react-icons/si';
import {BsInfoCircle} from 'react-icons/bs';
import {Loader} from './';
import { TransactionContext } from '../context/TransactionContext';
import React, {useContext} from 'react';
const commonStyles = "min-h-[70px] sm:px-0 px-2 sm:min-w-[120px] flex justify-center items-center border-[0.5px] border-gray-400 text-sm font-light text-white";
const Input = ({placeholder, name, type, value, handleChange}) => (
<input
placeholder={placeholder}
type={type}
step="0.0001"
value={value}
onChange={(e) => handleChange(e, name)}
className="my-2 w-full rounded-sm p-2 outline-none bg-transparent text-white border-none text-sm white-glassmorphism" />
);
const Welcome = () => {
const {connectWallet, currentAccount, formData, sendTransaction, handleChange} = useContext(TransactionContext);
const handleSubmit = (e) => {
const { addressTo, amount, keyword, message } = formData;
e.preventDefault();
if(!addressTo || !amount || !keyword || !message) return;
sendTransaction();
};
return (
<div className="flex w-full justify-center items-center">
<div className="flex mf:flex-row flex-col items-start justify-between md:p-20 py-12 px-4">
<div className="flex flex-1 justify-start flex-col mf:mr-10 ">
<h1 className="text-3xl sm:text-5xl text-white text-gradient py-1">
Send Crypto <br/> across the world
</h1>
<p className="text-left mt-5 text-white font-light md:w-9/12 w-11/12 text-base">
Explore the universe of crypto trade cryptocurrencies smoothly and securely on Krypto
</p>
{!currentAccount && (<button type="button" onClick={connectWallet}
className="flex flex-row justify-center items-center my-5 bg-[#2952e3] p-3 rounded-full cursor-pointer hover:bg-[2546bd]">
<p className="text-white text-base font-semibold" >Connect Your Wallet </p>
</button>)}
<div className="grid sm:grid-cols-3 grid-cols-2 w-full mt-10">
<div className={`rounded-tl-2xl ${commonStyles}`}>
Reliability
</div>
<div className={commonStyles}>
Security
</div>
<div className={`rounded-tr-2xl ${commonStyles}`}>
Ethereum
</div>
<div className={`rounded-bl-2xl ${commonStyles}`}>
Web 3.0
</div>
<div className={commonStyles}>
Low fees
</div>
<div className={`rounded-br-2xl ${commonStyles}`}>
Blockchain
</div>
</div>
</div >
<div className="flex flex-col flex-1 items-center justify-start w-full mf:mt-0 mt-10">
<div className="p-3 justify-end items-start flex-col rounded-xl h-40 sm:w-72 w-full my-5 eth-card white-glassmorphism">
<div className="flex justify-between flex-col w-full h-full">
<div className="flex justify-between items-start">
<div className="w-10 h-10 rounded-full border-2 border-white flex justify-center items-center">
<SiEthereum fontSize={21} color="#fff"/>
</div>
<BsInfoCircle fontSize={17} color="fff"/>
</div>
<div>
<p className="text-white font-light text-sm ">
Address
</p>
<p className="text-white font-semibold text-lg mt-1 ">
Ethereum
</p>
</div>
</div>
</div>
<div className="p-5 sm:w-96 w-full flex flex-col justify-start items-center blue-glassmorphism">
<Input placeholder="Address to" name="addressTo" type="text" handleChange={handleChange} />
<Input placeholder="Amount of (ETH) " name="amount" type="number" handleChange={handleChange} />
<Input placeholder="Keyword (Gif)" name="Keyword" type="text" handleChange={handleChange} />
<Input placeholder="Enter message" name="message" type="text" handleChange={handleChange} />
<div className ="h-[1px] w-full bg-gray-400 my-2"/>
{false ? (
<Loader/>
) : (
<button
type="button" onClick={handleSubmit}
className="text-white w-full mt-2 border-[1px] p-2 border-[#3d4f7c] rounded-full cursor-pointer">
Send
</button>
)}
</div>
</div>
</div>
</div>
);
}
export default Welcome;
Main.jsx
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import './index.css'
import {TransactionProvider} from './context/TransactionContext';
ReactDOM.render(
<TransactionProvider>
<React.StrictMode>
<App />
</React.StrictMode>
</TransactionProvider>,
document.getElementById('root')
)

After browser relode i got the user profile pic in website.how can i get it first time without browser reloding

**
import { useForm } from "react-hook-form";
import React, { useState } from "react";
import { useEffect } from "react";
import { useUpdateProfile } from "react-firebase-hooks/auth";
import { ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
import {
useCreateUserWithEmailAndPassword,
useSignInWithGoogle,
} from "react-firebase-hooks/auth";
import auth, { storage } from "../../firebase.init";
import { Link, useLocation, useNavigate } from "react-router-dom";
import Loader from "../Shared/Loader";
const Register = () => {
const [image, setImage] = useState(null);
const [url, setUrl] = useState(null);
const [percentage, setPercentage] = useState("");
const [updateProfile, updating] = useUpdateProfile(auth);
const [signInWithGoogle, gUser, gLoading] = useSignInWithGoogle(auth);
const [
createUserWithEmailAndPassword,
user,
loading,
error,
] = useCreateUserWithEmailAndPassword(auth);
const navigate = useNavigate();
const { register, handleSubmit, formState } = useForm({
mode: "onChange", // I want to change it to onBlur
});
const { isValid, errors } = formState;
const handleimagechange = (e) => {
if (e.target.files[0]) {
setImage(e.target.files[0]);
}
};
**useEffect(() => {
if (user?.user?.uid) {
navigate("/appiontment");
window.location.reload();
}
}, [user?.user?.uid, navigate]);
useEffect(() => {
if (gUser?.user?.uid) {
navigate("/appiontment");
}
}, [gUser?.user?.uid, navigate]);**
**useEffect(() => {
const uploadImage = () => {
// const name = new Date().getTime + image.name
const storageRef = ref(storage, image.name);
const uploadTask = uploadBytesResumable(storageRef, image);
uploadTask.on(
"state_changed",
(snapshot) => {
const progress =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
setPercentage(progress);
switch (snapshot.state) {
case "paused":
break;
case "running":
break;
default:
break;
}
},
(error) => {},
() => {
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
console.log("File available at", downloadURL);
setUrl(downloadURL);
});
}
);
};
image && uploadImage();
}, [image]);**
let singninErrors;
if (error?.message === "Firebase: Error (auth/email-already-in-use).") {
singninErrors = (
<div
className="bg-red-100 rounded-lg py-5 px-6 mb-4 text-base text-red-700 mb-3"
role="alert"
>
Email already Exsist
</div>
);
console.log(error.message);
}
**const onSubmit = async (data) => {
await createUserWithEmailAndPassword(data.email, data.password, data.name);
await updateProfile({ displayName: data.name, photoURL: url });
};
if (error) {
console.log(error.message);
}**
if (loading || gLoading || updating) {
return <Loader />;
}
return (
<div className="flex h-screen justify-center items-center ">
<div className="card w-96 bg-base-100 shadow-xl">
<div className="card-body">
<div className="flex flex-col w-full border-opacity-50">
<h1 className="text-xl text-center">Sign Up</h1>
<form onSubmit={handleSubmit(onSubmit)}>
<div className="form-control w-full max-w-xs ">
<label className="label">
<span className="label-text">Name</span>
</label>
<input
{...register("name", {
required: {
value: true,
message: "Name is required",
},
})}
type="text"
placeholder="Your Name"
className="input input-bordered w-full max-w-xs"
/>
<label className="label">
{errors.name?.type === "required" && (
<span className="label-text text-red-500">
{errors.name.message}
</span>
)}
</label>
</div>
<div className="form-control w-full max-w-xs ">
<label className="label">
<span className="label-text">Email</span>
</label>
<input
{...register("email", {
required: {
value: true,
message: "Email Adress is required",
},
pattern: {
value: /^[^\s#]+#[^\s#]+\.[^\s#]+$/,
message: "please enter a valid email adress",
},
})}
type="email"
placeholder="Your Email"
className="input input-bordered w-full max-w-xs"
/>
<label className="label">
{errors.email?.type === "required" && (
<span className="label-text text-red-500">
{errors.email.message}
</span>
)}
{errors.email?.type === "pattern" && (
<span className="label-text text-red-500">
{errors.email.message}
</span>
)}
</label>
</div>
<div className="form-control w-full max-w-xs ">
<label className="label">
<span className="label-text">Password</span>
</label>
<input
{...register("password", {
required: {
value: true,
message: "password is required",
},
minLength: {
value: 6,
message: "password must be 6 character or long",
},
})}
type="password"
placeholder="Your password"
className="input input-bordered w-full max-w-xs"
/>
<label className="label">
{errors.password?.type === "required" && (
<span className="label-text text-red-500">
{errors.password.message}
</span>
)}
{errors.password?.type === "minLength" && (
<span className="label-text text-red-500">
{errors.password.message}
</span>
)}
</label>
</div>
<label className="label">Upload Your Avatar</label>
<div className="w-full bg-gray-200 rounded-full">
{percentage === 0 && (
<div
className="bg-blue-100 rounded-lg py-5 px-6 mb-4 text-base text-blue-700
mb-3"
role="alert"
>
Image Uploading please wait
</div>
)}
{percentage === 100 && url && (
<div
className="bg-green-100 rounded-lg py-5 px-6 mb-4 text-base text-green-700
mb-3"
role="alert"
>
img Uploading:{percentage}% Successfully
</div>
)}
</div>
<div className="flex justify-center">
<div className="mb-3 w-96 ">
<input
onChange={handleimagechange}
className="form-control block
w-full
px-3
py-1.5
text-base
font-normal
text-gray-700
bg-white bg-clip-padding
border border-solid border-gray-300
rounded
transition
ease-in-out
m-0
focus:text-gray-700 focus:bg-white focus:border-blue-
600 focus:outline-none"
type="file"
id="formFile"
/>
</div>
</div>
{singninErrors}
<button
disabled={!isValid || !url}
type="submit"
className="btn w-full max-w-xs">
Signup</button> </form>
<p className="font-semibold ">
<small>
already have an account ?
<Link className="text-secondary mx-2" to="/">
Please login
</Link>
</small>
</p>
<div className="divider">OR</div>
<button
onClick={() => signInWithGoogle()}
className="btn btn-outline"
>
Continue with Google
</button>
</div>
</div>
</div>
</div>
);
};
export default Register;
**

Import password filed as an functional component in ReactJs

I want to store this react hook and password field in a separate js file and I want to import it to my register form how can I do that?
Password Field
<label class="font-medium block mb-1 mt-6 text-gray-700" for="password">
Password
</label>
<div class="relative w-full">
<div class="absolute inset-y-0 right-0 flex items-center px-2">
<input class="hidden js-password-toggle" id="toggle" type="checkbox" />
<label class="bg-gray-300 hover:bg-gray-400 rounded px-2 py-1 text-sm text-gray-600 font-mono cursor-pointer js-password-label" for="toggle">show</label>
</div>
<input class="appearance-none border-2 rounded w-full py-3 px-3 leading-tight border-gray-300 bg-gray-100 focus:outline-none focus:border-indigo-700 focus:bg-white text-gray-700 pr-16 font-mono js-password" id="password" type="password" autocomplete="off"
/>
</div>
Password function filed
useEffect(() => {
const passwordToggle = document.querySelector('.js-password-toggle')
passwordToggle.addEventListener('change', function() {
const password = document.querySelector('.js-password'),
passwordLabel = document.querySelector('.js-password-label')
if (password.type === 'password') {
password.type = 'text'
passwordLabel.innerHTML = 'hide'
} else {
password.type = 'password'
passwordLabel.innerHTML = 'show'
}
password.focus()
})
}, [])
Form That I want to add this password filed
import React, { useEffect, useState } from "react";
import Buttons from "../../../elements/form/Button";
import PasswordInput from "../../../elements/form/PasswordInput";
import { Col, Input, Row, Select, Form, InputNumber, Divider } from "antd";
import { ChangePassword, sentOtp, changePhoneNumber, requestOtp } from "./SecurityApi";
const { Option } = Select;
const Security = () => {
const [phoneNo, setPhoneNo] = useState("");
const [otp, setOtp] = useState("");
//const [password, setPassword] = useState("");
const [conPassword, setConPassword] = useState("");
const [passError, setPassError] = useState();
const [otpError, setOtpError] = useState();
const [user, setUser] = useState(null);
//changing password
const [editPasswordState, setEditPasswordState] = useState(false);
const [password, setPassword] = useState({
password: "",
});
const handlePasswordChange = async () => {
if (password === user.password) {
return;
}
if (password.trim() === "") {
console.log("cant be empty");
return;
}
await ChangePassword(password, setUser);
};
useEffect(() => {
setPassError(password && conPassword && password !== conPassword);
}, [password, conPassword]);
useEffect(() => {
setOtpError(!otp && phoneNo);
}, [otp]);
//onSubmit password
const onSubmit = async () => {
if (passError) return false;
try {
const res = await ChangePassword({ password });
setPassword("");
setConPassword("");
alert("Password Changed !!");
} catch (error) {
alert("Something went wrong !!");
}
};
//OTP
const sendOtp = async () => {
if (phoneNo === "") return false;
try {
const res = await sentOtp(phoneNo);
alert(`Otp is ${res} !!`);
} catch (error) {
alert("Something went wrong !!");
}
};
//Changing the phone number
const changePhoneNo = async () => {
if (phoneNumber === "") return false;
if (otp === "") {
setOtpError(true);
return false;
}
try {
const res = await changePhoneNumber(phoneNo);
setPhoneNumber("");
setOtp("");
alert("Phone Number Changed !!");
} catch (error) {
alert("Something went wrong !!");
}
};
const [editPhoneNumberState, setEditPhoneNumberState] = useState(false);
const [phoneNumber, setPhoneNumber] = useState({
password: "",
});
const handlePhoneNumberChange = async () => {
if (phoneNumber === user.phoneNumber) {
return;
}
if (password.trim() === "") {
console.log("cant be empty");
return;
}
await ChangePassword(password, setUser);
};
return (
<>
<div className="md:pl-8 sm:pl-0 ">
{/* ---------- Password Change ------------ */}
<div class="mt-10 sm:mt-0">
<div class="md:grid md:grid-cols-3 md:gap-6">
<div class="md:col-span-1">
<div class="px-4 sm:px-0">
<h3 class="text-lg font-medium leading-6 text-gray-900">
Change Password
</h3>
<p class="mt-1 text-sm text-gray-600">Change password here</p>
</div>
</div>
<div class="mt-5 md:mt-0 md:col-span-2">
<form action="#" method="POST">
<div class="shadow overflow-hidden sm:rounded-md">
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
<div class="grid grid-cols-6 gap-6">
<div class="col-span-6 sm:col-span-3">
<Buttons
title={
!editPasswordState ? "Edit Full Password" : "Cancel"
}
outline
onClick={() => {
setEditPasswordState(!editPasswordState);
}}
class="inline-flex
justify-center
py-2 px-4 border
border-transparent
shadow-sm text-sm
font-medium rounded-md
text-white bg-red-400
hover:bg-red-400
focus:outline-none f
ocus:ring-2
focus:ring-offset-2
focus:ring-red-500"
/>
</div>
<div class="col-span-6 sm:col-span-3">
{editPasswordState && (
<Buttons
title="Save"
onClick={async () => {
setEditPasswordState(false);
await handlePasswordChange();
}}
/>
)}
</div>
</div>
</div>
<div class="px-4 py-5 bg-white sm:p-6">
{/* OTP Check*/}
<div class="grid grid-cols-6 gap-1">
<div class="col-span-4 sm:col-span-3">
<label
for="first-name"
class="block text-sm font-medium text-gray-700"
>
Send OTP
</label>
<Buttons
title={"Request OTP"}
outline
onClick={async () => {
await requestOtp(user.phoneNumber);
}}
/>
</div>
<div class="col-span-6 sm:col-span-3">
<label
for="last-name"
class="block text-sm font-medium text-gray-700"
>
Enter OTP
</label>
<input
type="text"
name="last-name"
id="last-name"
autocomplete="family-name"
class="mt-1
focus:ring-red-400
focus:border-red-400
block w-full
shadow-sm sm:text-sm
border-gray-300 rounded-md"
/>
{passError && (
<Col className="text-red-500">
OTP doesn't Correct !!
</Col>
)}
</div>
</div>
{/* OTP Check End */}
</div>
<div class="px-4 py-5 bg-white sm:p-6">
{/* Password Check*/}
<div class="grid grid-cols-6 gap-6">
<div class="col-span-6 sm:col-span-3">
<label
for="first-name"
class="block text-sm font-medium text-gray-700"
>
New Password
</label>
<Input.Password
value={password}
onChange={(event) => {
setPassword(event.target.value);
}}
class="mt-1
focus:ring-red-400
focus:border-red-400
block w-full
shadow-sm sm:text-sm
border-gray-300 rounded-md"/>
This is the Place
</div>
<div class="col-span-6 sm:col-span-3">
<label
for="last-name"
class="block text-sm font-medium text-gray-700"
>
Confirm New Password
</label>
<Input.Password
value={conPassword}
onChange={(event) => {
setConPassword(event.target.value);
}}
/>
{passError && (
<Col className="text-red-500">
Password doesn't match !!
</Col>
)}
</div>
</div>
{/* Password Check End*/}
</div>
</div>
</form>
</div>
</div>
</div>
{/* ------- End Password Change -------- */}
<div class="px-4 py-1 bg-black-50 text-right sm:px-6">
<Divider></Divider>
</div>
{/* ------------ Mobile Number Change ---------------- */}
<div class="mt-10 sm:mt-0">
<div class="md:grid md:grid-cols-3 md:gap-6">
<div class="md:col-span-1">
<div class="px-4 sm:px-0">
<h3 class="text-lg font-medium leading-6 text-gray-900">
Change Mobile Number
</h3>
<p class="mt-1 text-sm text-gray-600">
Use a permanent address where you can receive mail.
</p>
</div>
</div>
<div class="mt-5 md:mt-0 md:col-span-2">
<form action="#" method="POST">
<div class="shadow overflow-hidden sm:rounded-md">
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
<div class="grid grid-cols-6 gap-6">
<div class="col-span-6 sm:col-span-3">
<Buttons
title={
!editPhoneNumberState ? "Edit Phone Number" : "Cancel"
}
outline
onClick={() => {
setEditPhoneNumberState(!editPhoneNumberState);
}}
className={" flex items-center justify-center "}
/>
</div>
<div class="col-span-6 sm:col-span-3">
{editPhoneNumberState && (
<Buttons
title="Save"
onClick={async () => {
setEditPhoneNumberState(false);
await handlePhoneNumberChange();
}}
/>
)}
</div>
</div>
</div>
<div/>
<div class="px-4 py-5 bg-white sm:p-6">
{/** Email Verification */}
<div class="grid grid-cols-6 gap-6">
<div class="col-span-6 sm:col-span-3">
<label
for="first-name"
class="block text-sm font-medium text-gray-700"
>
Email
</label>
<Buttons
title="Send Email"
onClick={sendOtp}
outline
class=" inline-flex
justify-center
py-2 px-4 border
border-transparent
shadow-sm text-sm
font-medium rounded-md
text-white bg-red-400
hover:bg-red-400
focus:outline-none f
ocus:ring-2
focus:ring-offset-2
focus:ring-red-500"
/>
</div>
<div class="col-span-6 sm:col-span-3">
<label
for="last-name"
class="block text-sm font-medium text-gray-700"
>
Verification Code
</label>
<input
type="text"
name="last-name"
id="last-name"
autocomplete="family-name"
class="mt-1
focus:ring-red-400
focus:border-red-400
block w-full
shadow-sm sm:text-sm
border-gray-300 rounded-md"
/>
</div>
</div>
{/** End Email Verification */}
{/** Phone Number change */}
<div class="grid grid-cols-6 gap-6">
<div class="col-span-6 sm:col-span-3">
<label
for="first-name"
class="block text-sm font-medium text-gray-700"
>
New Mobile Number
</label>
<input
type="text"
name="first-name"
id="first-name"
autocomplete="given-name"
class="mt-1
focus:ring-red-400
focus:border-red-400
block w-full
shadow-sm sm:text-sm
border-gray-300 rounded-md"
/>
</div>
</div>
{/** End Email change */}
</div>
</div>
</form>
</div>
</div>
</div>
{/* ------------ Mobile Number Change ---------------- */}
</div>
</>
);
};
export default Security;
Above mention between two section, the password field should be added
Ok, lets assume this is your form:
import PasswordField from "/PasswordField"
const Form = () => {
const [password, setPassword] = useState("")
const [name, setName] = useState("")
const [lastName, setLastName] = useState("")
const submitForm = () => {
//your logic for submitting form
}
return (
<form onSubmit={submitForm}>
<input type="text" value={name} onChange={(e) => setName(e.target.value)} />
<input type="text" value={lastName} onChange={(e) => setLastName(e.target.value)} />
<PasswordField password={password} setPassword={setPassword} />
</form>
);
};
export default Form;
Note we are importing the PasswordField component to be used inside the form, and passing the value and the function to change that value as props to the PasswordField component.
Now lets create the Password component:
import React, {useState} from 'react';
const PasswordField = (props) => {
return (
<div>
<label class="font-medium block mb-1 mt-6 text-gray-700" for="password">
Password
</label>
<input id={"password"} type="password" value={props.password} onChange={(e) => props.setPassword(e.target.value)} />
</div>
);
};
export default PasswordField;
Obviously, you need to add your classes and styling accordingly, but I thing this could get you going.

Warning after signup and login in ReactJS

Since I am new to ReactJS, I can't able to find why I am getting this "Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function." after signing up and loging in. Here is my code as follows:
AuthContext.js:
import React, { useContext, useState, useEffect } from "react";
import { auth } from "../firebase";
const AuthContext = React.createContext();
export function useAuth() {
return useContext(AuthContext);
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState();
const [loading, setLoading] = useState(true);
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password);
}
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password);
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) => {
setCurrentUser(user);
setLoading(false);
});
return unsubscribe;
}, []);
const value = {
currentUser,
login,
signup,
};
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
);
}
Signup.js:
import React, { useRef, useState } from "react";
import { useAuth } from "../contexts/AuthContext";
import { Link, useHistory } from "react-router-dom";
export default function Signup() {
const emailRef = useRef();
const passwordRef = useRef();
const passwordConfirmRef = useRef();
const { signup } = useAuth();
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const history = useHistory();
async function handleSubmit(e) {
e.preventDefault();
if (passwordRef.current.value !== passwordConfirmRef.current.value) {
return setError("Passwords do not match");
}
try {
setError("");
setLoading(true);
await signup(emailRef.current.value, passwordRef.current.value);
history.push("/login");
} catch (e) {
console.error(e);
}
setLoading(false);
}
return (
<div>
<div
className="h-screen overflow-hidden flex
items-center justify-center bg-blue-300"
>
<form
onSubmit={handleSubmit}
className="space-y-5 bg-white p-16 rounded shadow w-2/3"
>
<h2 className="text-3xl mb-5 text-center text-gray-800">Sign Up</h2>
<hr />
<div class="bg-teal-200 relative text-teal-600 py-3 px-3 rounded-lg">
{error}
</div>
<label
htmlFor="email"
className="block mb-1 font-mono mt-3 text-gray-500"
>
Email
</label>
<input
ref={emailRef}
type="email"
name="email"
placeholder="Email"
className="w-full border-2 border-gray-200 p-3
rounded outline-none focus:border-blue-300"
required
/>
<label
htmlFor="password"
className="block mb-1 font-mono mt-3 text-gray-500"
>
Password
</label>
<input
ref={passwordRef}
type="password"
name="password"
placeholder="Password"
className="w-full border-2 border-gray-200 p-3
rounded outline-none focus:border-blue-300"
required
/>
<label
htmlFor="confirm password"
className="block mb-1 font-mono mt-3 text-gray-500"
>
Confirm Password
</label>
<input
ref={passwordConfirmRef}
type="password"
name="confirm-password"
placeholder="Retype Password"
className="w-full border-2 border-gray-200 p-3
rounded outline-none focus:border-blue-300"
required
/>
<hr />
<button
disabled={loading}
type="submit"
className="block w-full bg-pink-400 hover:bg-pink-300 p-4
rounded text-blck transition duration-300 font-semibold"
>
SIGN UP
</button>
<div className="w-100 text-center mt-2">
Already have an account?{" "}
<Link className="text-blue-600" to="/login">
Log In
</Link>
</div>
</form>
</div>
</div>
);
}
Login.js:
import React, { useRef, useState } from "react";
import { useAuth } from "../contexts/AuthContext";
import { Link, useHistory } from "react-router-dom";
export default function Login() {
const emailRef = useRef();
const passwordRef = useRef();
const { login } = useAuth();
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const history = useHistory();
async function handleSubmit(e) {
e.preventDefault();
try {
setError("");
setLoading(true);
await login(emailRef.current.value, passwordRef.current.value);
history.push("/appointments");
} catch (e) {
console.error(e);
}
setLoading(false);
}
return (
<div>
<div
className="h-screen overflow-hidden flex
items-center justify-center bg-blue-300"
>
<form
onSubmit={handleSubmit}
className="space-y-5 bg-white p-16 rounded shadow w-2/3"
>
<h2 className="text-3xl mb-5 text-center text-gray-800">Log In</h2>
<hr />
<div class="bg-teal-200 relative text-teal-600 py-3 px-3 rounded-lg">
{error}
</div>
<label
htmlFor="email"
className="block mb-1 font-mono mt-3 text-gray-500"
>
Email
</label>
<input
ref={emailRef}
type="email"
name="email"
placeholder="Email"
className="w-full border-2 border-gray-200 p-3
rounded outline-none focus:border-blue-300"
/>
<label
htmlFor="password"
className="block mb-1 font-mono mt-3 text-gray-500"
>
Password
</label>
<input
ref={passwordRef}
type="password"
name="password"
placeholder="Password"
className="w-full border-2 border-gray-200 p-3
rounded outline-none focus:border-blue-300"
/>
<button
disabled={loading}
type="submit"
className="block w-full bg-pink-400 hover:bg-pink-300 p-4
rounded text-blck transition duration-300 font-semibold"
>
LOG IN
</button>
<div className="w-100 text-center mt-2">
Need an account?{" "}
<Link className="text-blue-500" to="/register">
Sign Up
</Link>
</div>
</form>
</div>
</div>
);
}
Simply because you have not make a callback after the return in useEffet which mean, your useEffect hook should be like so:
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) => {
if (user) {
setCurrentUser(user);
}
setLoading(false);
});
return () => unsubscribe();
}, []);

Resources