Added basic password strength indicator

This commit is contained in:
K
2025-07-18 02:34:05 +05:30
parent bc41904e06
commit 2afda4873b
+56 -7
View File
@@ -7,8 +7,7 @@ import { isPasswordPwned } from "../../utils/passwordUtils";
const SignupPage = (props) => { const SignupPage = (props) => {
const outletContext = useOutletContext?.(); const outletContext = useOutletContext?.();
const language = const language = (outletContext && outletContext.language) || props.language || "en";
(outletContext && outletContext.language) || props.language || "en";
const firstNameElement = useRef(); const firstNameElement = useRef();
const lastNameElement = useRef(); const lastNameElement = useRef();
@@ -16,8 +15,28 @@ const SignupPage = (props) => {
const passwordElement = useRef(); const passwordElement = useRef();
const [error, setError] = useState(""); const [error, setError] = useState("");
const [passwordStrength, setPasswordStrength] = useState("");
const navigate = useNavigate(); const navigate = useNavigate();
const evaluatePasswordStrength = (password) => {
let score = 0;
if (password.length >= 8) score++;
if (/[a-z]/.test(password)) score++;
if (/[A-Z]/.test(password)) score++;
if (/\d/.test(password)) score++;
if (/[@$!%*?&]/.test(password)) score++;
if (score <= 2) return "Weak";
if (score === 3 || score === 4) return "Moderate";
return "Strong";
};
const handlePasswordChange = (e) => {
const pwd = e.target.value;
passwordElement.current.value = pwd; // keep the ref synced
setPasswordStrength(evaluatePasswordStrength(pwd));
};
const handleRegisteration = async (event) => { const handleRegisteration = async (event) => {
event.preventDefault(); event.preventDefault();
setError(""); setError("");
@@ -47,8 +66,7 @@ const SignupPage = (props) => {
} }
const user = { const user = {
name: name: `${firstNameElement.current.value} ${lastNameElement.current.value}`,
firstNameElement.current.value + " " + lastNameElement.current.value,
email: emailElement.current.value, email: emailElement.current.value,
password: password, password: password,
}; };
@@ -56,9 +74,7 @@ const SignupPage = (props) => {
try { try {
const response = await fetch(`${BACKEND_URL}/api/v1/register`, { const response = await fetch(`${BACKEND_URL}/api/v1/register`, {
method: "POST", method: "POST",
headers: { headers: { "Content-Type": "application/json" },
"Content-Type": "application/json",
},
body: JSON.stringify(user), body: JSON.stringify(user),
credentials: "include", credentials: "include",
}); });
@@ -79,6 +95,7 @@ const SignupPage = (props) => {
lastNameElement.current.value = ""; lastNameElement.current.value = "";
emailElement.current.value = ""; emailElement.current.value = "";
passwordElement.current.value = ""; passwordElement.current.value = "";
setPasswordStrength("");
}; };
return ( return (
@@ -142,10 +159,42 @@ const SignupPage = (props) => {
type="password" type="password"
id="password" id="password"
ref={passwordElement} ref={passwordElement}
onChange={handlePasswordChange}
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder={t("signup_password_placeholder", language)} placeholder={t("signup_password_placeholder", language)}
required required
/> />
{/* Password Strength UI */}
{passwordStrength && (
<>
<div className="mt-2 text-sm font-medium">
Password strength:{" "}
<span
className={
passwordStrength === "Weak"
? "text-red-500"
: passwordStrength === "Moderate"
? "text-yellow-500"
: "text-green-500"
}
>
{passwordStrength}
</span>
</div>
<div className="w-full h-2 rounded bg-gray-200 mt-1">
<div
className={`h-2 rounded transition-all duration-300 ${
passwordStrength === "Weak"
? "bg-red-500 w-1/4"
: passwordStrength === "Moderate"
? "bg-yellow-500 w-2/4"
: "bg-green-500 w-full"
}`}
></div>
</div>
</>
)}
</div> </div>
{error && <p className="text-red-500 text-sm font-medium">{error}</p>} {error && <p className="text-red-500 text-sm font-medium">{error}</p>}