Skip to content

Commit

Permalink
Added password visibility toggle
Browse files Browse the repository at this point in the history
  • Loading branch information
pani2004 authored Oct 16, 2024
1 parent 394893e commit a7bb35d
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 61 deletions.
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"firebase": "^10.14.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^5.3.0",
"react-router-dom": "^6.27.0",
"react-toastify": "^9.1.3",
"uuid": "^9.0.1"
Expand Down
139 changes: 89 additions & 50 deletions src/components/SignIn.jsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
import { useState } from 'react'
import { Link, Navigate } from 'react-router-dom'
import { doSignInWithEmailAndPassword, doSignInWithGoogle } from '../firebase/auth'
import { useAuth } from '../contexts/authContext/index'
import { useState } from 'react';
import { Link, Navigate } from 'react-router-dom';
import { doSignInWithEmailAndPassword, doSignInWithGoogle } from '../firebase/auth';
import { useAuth } from '../contexts/authContext/index';
import { AiFillEye, AiFillEyeInvisible } from 'react-icons/ai'; // Importing React Icons

const SignIn = () => {
const { userLoggedIn } = useAuth();

const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [isSigningIn, setIsSigningIn] = useState(false)
const [errorMessage, setErrorMessage] = useState('')
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [showPassword, setShowPassword] = useState(false); // Added state to toggle password visibility
const [isSigningIn, setIsSigningIn] = useState(false);
const [errorMessage, setErrorMessage] = useState('');

const onSubmit = async (e) => {
e.preventDefault()
e.preventDefault();
if (!isSigningIn) {
setIsSigningIn(true)
await doSignInWithEmailAndPassword(email, password)
// doSendEmailVerification()
setIsSigningIn(true);
await doSignInWithEmailAndPassword(email, password);
// doSendEmailVerification();
}
}
};

const onGoogleSignIn = (e) => {
e.preventDefault()
e.preventDefault();
if (!isSigningIn) {
setIsSigningIn(true)
setIsSigningIn(true);
doSignInWithGoogle().catch(err => {
setIsSigningIn(false)
})
setIsSigningIn(false);
});
}
}
};

if (userLoggedIn) {
return <Navigate to="/" replace />;
}
Expand All @@ -42,63 +45,99 @@ const SignIn = () => {
<h3 className="text-gray-800 text-xl font-semibold sm:text-2xl">Welcome Back</h3>
</div>
</div>
<form
onSubmit={onSubmit}
className="space-y-5"
>
<form onSubmit={onSubmit} className="space-y-5">
<div>
<label className="text-sm text-gray-600 font-bold">
Email
</label>
<label className="text-sm text-gray-600 font-bold">Email</label>
<input
type="email"
autoComplete='email'
autoComplete="email"
required
value={email} onChange={(e) => { setEmail(e.target.value) }}
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full mt-2 px-3 py-2 text-gray-500 bg-transparent outline-none border focus:border-green-600 shadow-sm rounded-lg transition duration-300"
/>
</div>


<div>
<label className="text-sm text-gray-600 font-bold">
Password
</label>
<div className="relative">
<label className="text-sm text-gray-600 font-bold">Password</label>
<input
type="password"
autoComplete='current-password'
type={showPassword ? 'text' : 'password'}
autoComplete="current-password"
required
value={password} onChange={(e) => { setPassword(e.target.value) }}
className="w-full mt-2 px-3 py-2 text-gray-500 bg-transparent outline-none border focus:border-green-600 shadow-sm rounded-lg transition duration-300"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full mt-2 px-3 py-2 pr-10 text-gray-500 bg-transparent outline-none border focus:border-green-600 shadow-sm rounded-lg transition duration-300"
/>
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute inset-y-0 right-0 mt-8 flex items-center px-3"
>
{showPassword ? (
<AiFillEyeInvisible className="w-6 h-6 text-gray-500" />
) : (
<AiFillEye className="w-6 h-6 text-gray-500" />
)}
</button>
</div>

{errorMessage && (
<span className='text-red-600 font-bold'>{errorMessage}</span>
<span className="text-red-600 font-bold">{errorMessage}</span>
)}

<button
type="submit"
disabled={isSigningIn}
className={`w-full px-4 py-2 text-white font-medium rounded-lg ${isSigningIn ? 'bg-gray-300 cursor-not-allowed' : 'bg-green-600 hover:bg-green-700 hover:shadow-xl transition duration-300'}`}
className={`w-full px-4 py-2 text-white font-medium rounded-lg ${
isSigningIn
? 'bg-gray-300 cursor-not-allowed'
: 'bg-green-600 hover:bg-green-700 hover:shadow-xl transition duration-300'
}`}
>
{isSigningIn ? 'Signing In...' : 'Sign In'}
</button>
</form>
<p className="text-center text-sm">Don't have an account? <Link to={'/sign-up'} className="hover:underline font-bold">Sign up</Link></p>
<div className='flex flex-row text-center w-full'>
<div className='border-b-2 mb-2.5 mr-2 w-full'></div><div className='text-sm font-bold w-fit'>OR</div><div className='border-b-2 mb-2.5 ml-2 w-full'></div>

<p className="text-center text-sm">
Don't have an account?{' '}
<Link to="/sign-up" className="hover:underline font-bold">
Sign up
</Link>
</p>

<div className="flex flex-row text-center w-full">
<div className="border-b-2 mb-2.5 mr-2 w-full"></div>
<div className="text-sm font-bold w-fit">OR</div>
<div className="border-b-2 mb-2.5 ml-2 w-full"></div>
</div>

<button
disabled={isSigningIn}
onClick={(e) => { onGoogleSignIn(e) }}
className={`w-full flex items-center justify-center gap-x-3 py-2.5 border rounded-lg text-sm font-medium ${isSigningIn ? 'cursor-not-allowed' : 'hover:bg-gray-100 transition duration-300 active:bg-gray-100'}`}>
onClick={(e) => onGoogleSignIn(e)}
className={`w-full flex items-center justify-center gap-x-3 py-2.5 border rounded-lg text-sm font-medium ${
isSigningIn
? 'cursor-not-allowed'
: 'hover:bg-gray-100 transition duration-300 active:bg-gray-100'
}`}
>
<svg className="w-5 h-5" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clipPath="url(#clip0_17_40)">
<path d="M47.532 24.5528C47.532 22.9214 47.3997 21.2811 47.1175 19.6761H24.48V28.9181H37.4434C36.9055 31.8988 35.177 34.5356 32.6461 36.2111V42.2078H40.3801C44.9217 38.0278 47.532 31.8547 47.532 24.5528Z" fill="#4285F4" />
<path d="M24.48 48.0016C30.9529 48.0016 36.4116 45.8764 40.3888 42.2078L32.6549 36.2111C30.5031 37.675 27.7252 38.5039 24.4888 38.5039C18.2275 38.5039 12.9187 34.2798 11.0139 28.6006H3.03296V34.7825C7.10718 42.8868 15.4056 48.0016 24.48 48.0016Z" fill="#34A853" />
<path d="M11.0051 28.6006C9.99973 25.6199 9.99973 22.3922 11.0051 19.4115V13.2296H3.03298C-0.371021 20.0112 -0.371021 28.0009 3.03298 34.7825L11.0051 28.6006Z" fill="#FBBC04" />
<path d="M24.48 9.49932C27.9016 9.44641 31.2086 10.7339 33.6866 13.0973L40.5387 6.24523C36.2 2.17101 30.4414 -0.068932 24.48 0.00161733C15.4055 0.00161733 7.10718 5.11644 3.03296 13.2296L11.005 19.4115C12.901 13.7235 18.2187 9.49932 24.48 9.49932Z" fill="#EA4335" />
<path
d="M47.532 24.5528C47.532 22.9214 47.3997 21.2811 47.1175 19.6761H24.48V28.9181H37.4434C36.9055 31.8988 35.177 34.5356 32.6461 36.2111V42.2078H40.3801C44.9217 38.0278 47.532 31.8547 47.532 24.5528Z"
fill="#4285F4"
/>
<path
d="M24.48 48.0016C30.9529 48.0016 36.4116 45.8764 40.3888 42.2078L32.6549 36.2111C30.5031 37.675 27.7252 38.5039 24.4888 38.5039C18.2275 38.5039 12.9187 34.2798 11.0139 28.6006H3.03296V34.7825C7.10718 42.8868 15.4056 48.0016 24.48 48.0016Z"
fill="#34A853"
/>
<path
d="M11.0051 28.6006C9.99973 25.6199 9.99973 22.3922 11.0051 19.4115V13.2296H3.03298C-0.371021 20.0112 -0.371021 28.0009 3.03298 34.7825L11.0051 28.6006Z"
fill="#FBBC04"
/>
<path
d="M24.48 9.49932C27.9016 9.44641 31.2086 10.7339 33.6866 13.0973L40.5387 6.24523C36.2 2.17101 30.4414 -0.068932 24.48 0.00161733C15.4055 0.00161733 7.10718 5.11644 3.03296 13.2296L11.005 19.4115C12.901 13.7235 18.2187 9.49932 24.48 9.49932Z"
fill="#EA4335"
/>
</g>
<defs>
<clipPath id="clip0_17_40">
Expand All @@ -111,7 +150,7 @@ const SignIn = () => {
</div>
</main>
</div>
)
}
);
};

export default SignIn
export default SignIn;
34 changes: 23 additions & 11 deletions src/components/SignUp.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ import { useState } from 'react'
import { Navigate, Link } from 'react-router-dom'
import { useAuth } from '../contexts/authContext/index'
import { doCreateUserWithEmailAndPassword } from '../firebase/auth'
import { AiFillEye, AiFillEyeInvisible } from 'react-icons/ai'

const Register = () => {


const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [confirmPassword, setconfirmPassword] = useState('')
const [isRegistering, setIsRegistering] = useState(false)
const [errorMessage, setErrorMessage] = useState('')
const [showPassword, setShowPassword] = useState(false);
const [showConfirmPassword, setShowConfirmPassword] = useState(false);

const { userLoggedIn } = useAuth()

Expand All @@ -28,14 +30,12 @@ const Register = () => {

return (
<>

<main className="w-full h-screen flex self-center place-content-center place-items-center">
<div className="w-96 text-gray-600 space-y-5 p-4 shadow-xl border rounded-xl">
<div className="text-center mb-6">
<div className="mt-2">
<h3 className="text-gray-800 text-xl font-semibold sm:text-2xl">Create a New Account</h3>
</div>

</div>
<form
onSubmit={onSubmit}
Expand All @@ -50,36 +50,48 @@ const Register = () => {
autoComplete='email'
required
value={email} onChange={(e) => { setEmail(e.target.value) }}
className="w-full mt-2 px-3 py-2 text-gray-500 bg-transparent outline-none border focus:green-600 shadow-sm rounded-lg transition duration-300"
className="w-full mt-2 px-3 py-2 text-gray-500 bg-transparent outline-none border focus:border-green-600 shadow-sm rounded-lg transition duration-300"
/>
</div>

<div>
<div className="relative">
<label className="text-sm text-gray-600 font-bold">
Password
</label>
<input
disabled={isRegistering}
type="password"
type={showPassword ? 'text' : 'password'}
autoComplete='new-password'
required
value={password} onChange={(e) => { setPassword(e.target.value) }}
className="w-full mt-2 px-3 py-2 text-gray-500 bg-transparent outline-none border focus:border-green-600 shadow-sm rounded-lg transition duration-300"
/>
<button
type="button"
className="absolute inset-y-0 right-2 top-9"
onClick={() => setShowPassword(!showPassword)}
>
{showPassword ? <AiFillEyeInvisible /> : <AiFillEye />}
</button>
</div>

<div>
<div className="relative">
<label className="text-sm text-gray-600 font-bold">
Confirm Password
</label>
<input
disabled={isRegistering}
type="password"
type={showConfirmPassword ? 'text' : 'password'}
autoComplete='off'
required
value={confirmPassword} onChange={(e) => { setconfirmPassword(e.target.value) }}
className="w-full mt-2 px-3 py-2 text-gray-500 bg-transparent outline-none border focus:border-green-600 shadow-sm rounded-lg transition duration-300"
/>
<button
type="button"
className="absolute inset-y-0 right-2 top-9"
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
>
{showConfirmPassword ? <AiFillEyeInvisible /> : <AiFillEye />}
</button>
</div>

{errorMessage && (
Expand All @@ -104,4 +116,4 @@ const Register = () => {
)
}

export default Register
export default Register

0 comments on commit a7bb35d

Please sign in to comment.