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

feat: add password visibility button to authentication pages #572

Merged
merged 14 commits into from
Nov 24, 2023
11 changes: 8 additions & 3 deletions components/Input/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { forwardRef, InputHTMLAttributes } from "react";
import { forwardRef, InputHTMLAttributes, ReactNode } from "react";

interface Props extends InputHTMLAttributes<HTMLInputElement> {
text: string;
autocomplete?: string;
fgColor: string;
bgColor: string;
enabled?: boolean;
right?: ReactNode;
}

export default forwardRef<HTMLInputElement, Props>(function Input(
Expand All @@ -20,6 +21,7 @@ export default forwardRef<HTMLInputElement, Props>(function Input(
bgColor,
onChange,
enabled,
right,
...rest
},
ref
Expand All @@ -43,20 +45,23 @@ export default forwardRef<HTMLInputElement, Props>(function Input(
>
{text}
</label>
<div className="mt-2">
<div
className={`text-iregular mt-2 flex items-center ${textColor} ${backColor} appearance-none rounded-full border border-gray-300 px-3 py-2 pl-6 placeholder-gray-400 shadow-sm sm:text-sm`}
>
<input
id={id}
name={name}
type={type}
autoComplete={autocomplete}
value={value}
required
className={`text-iregular ${textColor} ${backColor} block w-full appearance-none rounded-full border border-gray-300 px-3 py-2 pl-6 placeholder-gray-400 shadow-sm focus:outline-none sm:text-sm`}
className="w-full bg-transparent outline-none"
onChange={onChange}
disabled={enabled == false}
ref={ref}
{...rest}
/>
{right}
</div>
</div>
);
Expand Down
39 changes: 28 additions & 11 deletions layout/Login/components/LoginForm/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useRef } from "react";
import { useRef, useState } from "react";

import { useAuth } from "@context/Auth";

Expand All @@ -8,10 +8,14 @@ import Text from "@layout/moonstone/authentication/Text";
import Form from "@components/Form";
import Input from "@components/Input";

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";

export default function LoginForm() {
const { errors, login, isLoading } = useAuth();
const emailRef = useRef(null);
const passwordRef = useRef(null);
const [isPasswordVisible, setIsPasswordVisible] = useState(false);

const onFinish = (event) => {
event.preventDefault();
Expand All @@ -22,6 +26,10 @@ export default function LoginForm() {
login({ email, password });
};

const togglePasswordVisibility = () => {
setIsPasswordVisible(!isPasswordVisible);
};

return (
<div className="mt-8">
<Form onSubmit={onFinish}>
Expand All @@ -35,16 +43,25 @@ export default function LoginForm() {
autoComplete="email"
ref={emailRef}
/>
<Input
text="YOUR PASSWORD"
id="password"
name="password"
type="password"
fgColor="white"
bgColor="primary"
autoComplete="current-password"
ref={passwordRef}
/>
<div>
<Input
text="YOUR PASSWORD"
id="password"
name="password"
type={isPasswordVisible ? "text" : "password"}
fgColor="white"
bgColor="primary"
autoComplete="current-password"
right={
<FontAwesomeIcon
className="mx-2"
onClick={togglePasswordVisibility}
Darguima marked this conversation as resolved.
Show resolved Hide resolved
icon={isPasswordVisible ? faEyeSlash : faEye}
/>
}
ref={passwordRef}
/>
</div>
<Text
padding="6"
text="Forgot your password?"
Expand Down
32 changes: 30 additions & 2 deletions layout/ResetPassword/components/ResetPasswordForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import ImageButton from "@components/ImageButton";
import Form from "@components/Form";
import Input from "@components/Input";

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";

export default function ResetPasswordForm() {
const router = useRouter();
const { token } = router.query;
Expand All @@ -20,6 +23,9 @@ export default function ResetPasswordForm() {
const passwordRef = useRef(null);
const passwordConfirmationRef = useRef(null);
const [errorMsg, updateErrorMsg] = useState(null);
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
const [isConfirmPasswordVisible, setIsConfirmPasswordVisible] =
useState(false);

function onSubmit(event) {
event.preventDefault();
Expand Down Expand Up @@ -47,6 +53,14 @@ export default function ResetPasswordForm() {
});
}

const togglePasswordVisibility = () => {
setIsPasswordVisible(!isPasswordVisible);
};

const toggleConfirmPasswordVisibility = () => {
setIsConfirmPasswordVisible(!isConfirmPasswordVisible);
};

return (
<>
{success === null && (
Expand All @@ -55,20 +69,34 @@ export default function ResetPasswordForm() {
text="PASSWORD"
id="password"
name="password"
type="password"
type={isPasswordVisible ? "text" : "password"}
autoComplete="current-password"
fgColor="white"
bgColor="primary"
right={
<FontAwesomeIcon
className="mx-2"
Darguima marked this conversation as resolved.
Show resolved Hide resolved
onClick={togglePasswordVisibility}
icon={isPasswordVisible ? faEyeSlash : faEye}
/>
}
ref={passwordRef}
/>
<Input
text="CONFIRM PASSWORD"
id="confirm"
name="confirm"
type="password"
type={isConfirmPasswordVisible ? "text" : "password"}
autoComplete="current-password"
fgColor="white"
bgColor="primary"
right={
<FontAwesomeIcon
className="mx-2"
Darguima marked this conversation as resolved.
Show resolved Hide resolved
onClick={toggleConfirmPasswordVisibility}
icon={isConfirmPasswordVisible ? faEyeSlash : faEye}
/>
}
ref={passwordConfirmationRef}
/>
<p className="mt-10 mb-10 text-center font-iregular text-failure">
Expand Down
33 changes: 31 additions & 2 deletions layout/SignUp/components/SignUpForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import Input from "@components/Input";

import BarebonesQRScanner from "@components/QRScanner/BarebonesQRScanner";

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";

export default function SignUpForm() {
const { sign_up, isLoading, errors } = useAuth();

Expand All @@ -18,6 +21,10 @@ export default function SignUpForm() {
const [password_confirmation, updatePasswordConfirmation] = useState("");
const [uuid, setUUID] = useState();

const [isPasswordVisible, setIsPasswordVisible] = useState(false);
const [isConfirmPasswordVisible, setIsConfirmPasswordVisible] =
useState(false);

const [local_error, updateError] = useState("");
const [scanned, updateScanned] = useState(false);
const [scanning, updateScanning] = useState(false);
Expand Down Expand Up @@ -63,6 +70,14 @@ export default function SignUpForm() {
}
};

const togglePasswordVisibility = () => {
setIsPasswordVisible(!isPasswordVisible);
};

const toggleConfirmPasswordVisibility = () => {
setIsConfirmPasswordVisible(!isConfirmPasswordVisible);
};

return (
<>
<Form onSubmit={onFinish}>
Expand Down Expand Up @@ -96,21 +111,35 @@ export default function SignUpForm() {
text="PASSWORD"
id="password"
name="password"
type="password"
type={isPasswordVisible ? "text" : "password"}
autoComplete="current-password"
fgColor="white"
bgColor="primary"
onChange={(e) => updatePassword(e.currentTarget.value)}
right={
<FontAwesomeIcon
className="mx-2"
Darguima marked this conversation as resolved.
Show resolved Hide resolved
onClick={togglePasswordVisibility}
icon={isPasswordVisible ? faEyeSlash : faEye}
/>
}
/>
<Input
text="CONFIRM PASSWORD"
id="password"
Darguima marked this conversation as resolved.
Show resolved Hide resolved
name="password"
type="password"
type={isConfirmPasswordVisible ? "text" : "password"}
autoComplete="current-password"
fgColor="white"
bgColor="primary"
onChange={(e) => updatePasswordConfirmation(e.currentTarget.value)}
right={
<FontAwesomeIcon
className="mx-2"
Darguima marked this conversation as resolved.
Show resolved Hide resolved
onClick={toggleConfirmPasswordVisibility}
icon={isConfirmPasswordVisible ? faEyeSlash : faEye}
/>
}
/>
<Button
text={scanning ? "STOP SCANNING" : "SCAN QR"}
Expand Down
25 changes: 23 additions & 2 deletions pages/register/[uuid].js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import Input from "@components/Input";
import Title from "@layout/moonstone/authentication/Title";
import Text from "@layout/moonstone/authentication/Text";

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";

function Register() {
const { sign_up, errors, isLoading } = useAuth();
const router = useRouter();
Expand All @@ -24,6 +27,10 @@ function Register() {
const [password, updatePassword] = useState("");
const [password_confirmation, updatePasswordConfirmation] = useState("");

const [isPasswordVisible, setIsPasswordVisible] = useState(false);
const [isConfirmPasswordVisible, setIsConfirmPasswordVisible] =
useState(false);

const onFinish = (e) => {
e.preventDefault();
sign_up({
Expand Down Expand Up @@ -72,21 +79,35 @@ function Register() {
text="PASSWORD"
id="password"
name="password"
type="password"
type={isPasswordVisible ? "text" : "password"}
autoComplete="current-password"
fgColor="white"
bgColor="primary"
onChange={(e) => updatePassword(e.currentTarget.value)}
right={
<FontAwesomeIcon
className="mx-2"
Darguima marked this conversation as resolved.
Show resolved Hide resolved
onClick={togglePasswordVisibility}
icon={isPasswordVisible ? faEyeSlash : faEye}
/>
}
/>
<Input
text="CONFIRM PASSWORD"
id="password"
name="password"
type="password"
type={isConfirmPasswordVisible ? "text" : "password"}
autoComplete="current-password"
fgColor="white"
bgColor="primary"
onChange={(e) => updatePasswordConfirmation(e.currentTarget.value)}
right={
<FontAwesomeIcon
className="mx-2"
Darguima marked this conversation as resolved.
Show resolved Hide resolved
onClick={toggleConfirmPasswordVisibility}
icon={isConfirmPasswordVisible ? faEyeSlash : faEye}
/>
}
/>
<Button
type="submit"
Expand Down
Loading