Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add reset password feature while login #376

Merged
merged 3 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import Licensing from "./Components/footer_section/Legal/Licensing";
import TermsConditions from "./Components/footer_section/Legal/TermsandConditions";
import PrivacyPolicy from "./Components/footer_section/Legal/PrivacyPolicy";
import Careers from "./Components/Careers/CareersPage";
import EmailVerification from "./Components/auth/resetPassword/EmailVerification";
import OTPVerification from "./Components/auth/resetPassword/OTPVerification";
import ResetPassword from "./Components/auth/resetPassword/ResetPassword";


function App() {
return (
Expand All @@ -46,6 +50,9 @@ function App() {
<Route path="/new/project" element={<NewProject />} />
<Route path="/profile" element={<Profile />} />
<Route path="/careers" element={<Careers />} />
<Route path="/verifyEmail" element={<EmailVerification />} />
<Route path="/otpVerification/:email" element={<OTPVerification />} />
<Route path="/resetPassword/:email" element={<ResetPassword />} />

</Routes>
<Footer />
Expand Down
9 changes: 9 additions & 0 deletions src/Components/Login.css
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,15 @@ form.sign-in-form {
.container1.sign-up-mode .right-panel {
pointer-events: all;
}
.reset-link {
display: inline-block;
color: #00ced1;
cursor: pointer;
margin: 15px 0;
}
.reset-link:hover {
text-decoration: underline;
}

@media (max-width: 870px) {
.container {
Expand Down
1 change: 1 addition & 0 deletions src/Components/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ const LogIn = () => {
{showPassword ? <i className="fas fa-eye-slash"></i> : <i className="fas fa-eye"></i>}
</button>
</div>
<p><Link to="/verifyEmail" className='reset-link'>Forgot password?</Link></p>
<input type="submit" value="Login" className="btn1 solid" />
<p className="social-text">Connect with Social Magic</p>
<div className="social-media">
Expand Down
51 changes: 51 additions & 0 deletions src/Components/auth/resetPassword/EmailVerification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { useState } from 'react';
import './resetPassword.css'
import { Link, useNavigate } from 'react-router-dom';

function EmailVerification() {

const [email, setEmail] = useState("")
const [error, setError] = useState(null);
const navigate = useNavigate()

const onInputChange = (e) => {
setEmail(e.target.value)
}


const onVerify = (e) => {
e.preventDefault();

console.log(email);

// call backend api to verify the email
// if sucess, redirect to otp verification
// navigate(`/otpVerification/${email}`)
// if fails, update the error => setError()

}

return (
<section className="auth-container">

<form onSubmit={onVerify}>
<h2>Email verification</h2>
<p>To secure your account security, we need to verify your identity.</p>
<p>Please enter the email registered with us.</p>
{ error && <div className='err'>{error}</div> }
<input
type='email'
placeholder='Enter your email'
value={email}
onChange={onInputChange}
/>
<button>Verify Email</button>
<p><Link to="/login" className='link'>Back to Login</Link></p>
</form>

</section>
);

}

export default EmailVerification;
89 changes: 89 additions & 0 deletions src/Components/auth/resetPassword/OTPVerification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { useEffect, useState } from 'react';
import './resetPassword.css'
import { useNavigate, useParams } from 'react-router-dom';

function OTPVerification() {

const { email } = useParams()
const [OTP, setOTP] = useState("")
const [timeRemaining, setTimeRemaining] = useState(60);
const [noOfAttempts, setNoOfAttempts] = useState(1);
const [error, setError] = useState(null);
const navigate = useNavigate()

const onInputChange = (e) => {
setOTP(e.target.value)
}

useEffect(() => {
if (noOfAttempts > 3) {
return;
}
if (timeRemaining >= 1) {
setTimeout(() => {
setTimeRemaining(prev => prev - 1)
}, 1000)
}
}, [noOfAttempts, timeRemaining])

const onResend = () => {

// call backend api to send otp again
// in backend if number of attempts <= 3 send the otp or
// send a bad request.
// if success,
// update the no of attempts and time remaining
// setNoOfAttempts()
// setTimeRemaining(60)
// if fails, update the error => setError()
}


const onVerify = (e) => {
e.preventDefault();

console.log(OTP);

// call backend api to verify the otp
// if otp is valid redirect to reset password
// navigate(`/resetPassword/${email}`)
// if fails, update the error => setError()

}

return (
<section className="auth-container">

<form onSubmit={onVerify}>
<h2>OTP verification</h2>
<p>In order to verify your identity, we have sent an one time code to your email <strong>{email}</strong>. </p>

{ error && <div className='err'>{error}</div> }

<input
type='text'
placeholder='Enter OTP code'
value={OTP}
onChange={onInputChange}
/>
<button>Verify Code</button>
<p>
{
noOfAttempts > 3 ? <>You have tried maximum no of attempts.</> :

timeRemaining >= 1 ? <>Resend OTP in {timeRemaining} seconds</> :

<span
className='link'
onClick={onResend}
>Resend OTP</span>
}
</p>
</form>

</section>
);

}

export default OTPVerification;
76 changes: 76 additions & 0 deletions src/Components/auth/resetPassword/ResetPassword.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { useState } from 'react';
import './resetPassword.css'
import { useNavigate, useParams } from 'react-router-dom';

function ResetPassword() {

const { email } = useParams()
const [inputs, setInputs] = useState({ password: "", cpassword: "" })
const [error, setError] = useState(null);
const navigate = useNavigate()

const onInputChange = (e) => {
const { name, value } = e.target;

setInputs(prev => {
return { ...prev, [name]: value }
});
}

const onReset = (e) => {
e.preventDefault()
console.log(inputs)
const err = validateInputs(inputs)
setError(err)
if (err) {
return
}
console.log("valid")

// call backend api to reset password
// is success redirect to login
// navigate("/login")
// if fails, set the error by => setError()
}

return (
<section className="auth-container">

<form onSubmit={onReset}>
<h2>Reset Password</h2>
<p>Your account has been verified! You can reset your password.</p>
{error && <div className='err'>{error}</div>}
<input
type='password'
placeholder='Enter new password'
name='password'
value={inputs.password}
onChange={onInputChange}
/>
<input
type='password'
placeholder='Re enter new password'
name='cpassword'
value={inputs.cpassword}
onChange={onInputChange}
/>
<button>Reset password</button>
</form>

</section>
);

}

export default ResetPassword;


function validateInputs({password, cpassword}) {
if (password.trim().length < 6) {
return "Password must have atleat 6 characters!"
}
if (password.trim() !== cpassword.trim()) {
return "Passwords do not match"
}
return null
}
43 changes: 43 additions & 0 deletions src/Components/auth/resetPassword/resetPassword.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
.auth-container {
min-height: 100dvh;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 15px;
}
.auth-container form {
width: 100%;
max-width: 400px;
padding: 15px;
border-radius: 4px;
box-shadow: 0 0 10px rgb(60, 59, 71);
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
}
.auth-container form p {
text-align: center;
color: rgb(186, 186, 186);
font-size: 14px;
}
.auth-container form button {
width: 100%;
}
p .link {
color: #cf00a3;
cursor: pointer;
}
p .link:hover {
text-decoration: underline;
}
.err {
width: 100%;
padding: 7px;
text-align: center;
border-radius: 4px;
color: red;
background-color: rgb(255, 230, 230);
font-size: 14px;
}
Loading