From 207645565516bbfc77cce6b64f1f63b04a5d4755 Mon Sep 17 00:00:00 2001 From: Wind-Explorer Date: Mon, 10 Feb 2025 22:55:54 +0800 Subject: [PATCH] password complexity indicator --- .../src/components/LoginView.tsx | 1 + .../PasswordComplexityIndicator.tsx | 60 +++++++++++++++++++ .../src/components/SignupView.tsx | 12 +++- 3 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 AceJobAgency.client/src/components/PasswordComplexityIndicator.tsx diff --git a/AceJobAgency.client/src/components/LoginView.tsx b/AceJobAgency.client/src/components/LoginView.tsx index bcb3933..3090229 100644 --- a/AceJobAgency.client/src/components/LoginView.tsx +++ b/AceJobAgency.client/src/components/LoginView.tsx @@ -67,6 +67,7 @@ export default function LoginView({ onSignup }: { onSignup: () => void }) {
({ + isLongEnough: password.length >= 12, + hasLowercase: /[a-z]/.test(password), + hasUppercase: /[A-Z]/.test(password), + hasNumber: /\d/.test(password), + hasSpecialChar: /[^A-Za-z\d]/.test(password), +}); + +// Dot indicator component +const DotIndicator = ({ met }: { met: boolean }) => ( + +); + +// List item component +const CriteriaItem = ({ label, met }: { label: string; met: boolean }) => ( +
+ + {label} +
+); + +// Main password complexity component +const PasswordComplexityIndicator: React.FC< + PasswordComplexityIndicatorProps +> = ({ password }) => { + const criteria = checkCriteria(password); + + const criteriaList = [ + { label: "12 characters", met: criteria.isLongEnough }, + { label: "Lowercase", met: criteria.hasLowercase }, + { label: "Uppercase", met: criteria.hasUppercase }, + { label: "Number", met: criteria.hasNumber }, + { label: "Special character", met: criteria.hasSpecialChar }, + ]; + + return ( + +
+ {criteriaList.map((criterion, index) => ( + + ))} +
+
+ ); +}; + +export default PasswordComplexityIndicator; diff --git a/AceJobAgency.client/src/components/SignupView.tsx b/AceJobAgency.client/src/components/SignupView.tsx index 296f8cd..a929a74 100644 --- a/AceJobAgency.client/src/components/SignupView.tsx +++ b/AceJobAgency.client/src/components/SignupView.tsx @@ -3,6 +3,7 @@ import { IconMail, IconLock } from "@tabler/icons-react"; import { useState } from "react"; import { toast } from "react-toastify"; import http, { login } from "../http"; +import PasswordComplexityIndicator from "./PasswordComplexityIndicator"; export const validatePassword = (password: string): boolean => { const passwordComplexityRegex = @@ -108,26 +109,30 @@ export default function SignupView({
} label="Email" type="email" value={emailValue} onValueChange={setEmailValue} /> - +
setDateOfBirth(e.target.value)} />
} label="Password" type="password" @@ -152,12 +158,14 @@ export default function SignupView({ onValueChange={setPassword} /> } label="Confirm password" type="password" value={confirmPassword} onValueChange={setConfirmPassword} /> +