Files
flyer-crawler.projectium.com/components/PasswordStrength.tsx
Torben Sorensen aa5990763d
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 18s
typescript fixin
2025-11-11 22:00:46 -08:00

56 lines
1.6 KiB
TypeScript

import React from 'react';
interface PasswordStrengthProps {
password?: string;
}
type Strength = {
level: 'none' | 'weak' | 'medium' | 'strong';
text: string;
};
const checkStrength = (password: string): Strength => {
if (!password) return { level: 'none', text: '' };
const hasNumber = /\d/.test(password);
const hasSpecial = /[!@#$%^&*]/.test(password);
const hasUpper = /[A-Z]/.test(password);
const hasLower = /[a-z]/.test(password);
let score = 0;
if (password.length >= 8) score++;
if (password.length >= 12) score++;
if (hasNumber) score++;
if (hasSpecial) score++;
if (hasUpper && hasLower) score++;
if (score >= 4) return { level: 'strong', text: 'Strong' };
if (score >= 2) return { level: 'medium', text: 'Medium' };
return { level: 'weak', text: 'Weak' };
};
export const PasswordStrength: React.FC<PasswordStrengthProps> = ({ password = '' }) => {
const { level, text } = checkStrength(password);
const colorClasses = {
weak: 'bg-red-500',
medium: 'bg-yellow-500',
strong: 'bg-green-500',
none: 'bg-gray-300',
};
const widthClasses = {
weak: 'w-1/3',
medium: 'w-2/3',
strong: 'w-full',
none: 'w-0',
};
return (
<div className="mt-2">
<div className="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-1.5">
<div className={`h-1.5 rounded-full ${colorClasses[level]} ${widthClasses[level]} transition-all duration-300`}></div>
</div>
{/* Display the strength text only if a password has been entered. */}
{level !== 'none' && <p className="text-xs text-right mt-1 font-medium text-gray-500 dark:text-gray-400">{text}</p>}
</div>
);
};