/** * Password Strength Indicator Component * Shows password strength and validation requirements */ 'use client'; import { useState, useEffect } from 'react'; export default function PasswordStrengthIndicator({ password = '', showRequirements = true }) { const [strength, setStrength] = useState(0); const [requirements, setRequirements] = useState({ length: false, maxLength: false, uppercase: false, lowercase: false, number: false }); useEffect(() => { if (!password) { setStrength(0); setRequirements({ length: false, uppercase: false, lowercase: false, number: false }); return; } const newRequirements = { length: password.length >= 8, maxLength: password.length <= 128, uppercase: /[A-Z]/.test(password), lowercase: /[a-z]/.test(password), number: /\d/.test(password) }; setRequirements(newRequirements); // Calculate strength based on both requirements and length const requirementsMet = Object.values(newRequirements).filter(Boolean).length; let strengthValue = requirementsMet; // Adjust strength based on password length if (password.length >= 12) { strengthValue = Math.min(5, strengthValue + 1); // Bonus for long passwords } else if (password.length >= 8 && password.length < 10) { strengthValue = Math.max(1, strengthValue - 1); // Penalty for short passwords } else if (password.length < 8) { strengthValue = Math.max(0, strengthValue - 2); // Big penalty for very short passwords } // Ensure strength is between 0 and 5 strengthValue = Math.max(0, Math.min(5, strengthValue)); setStrength(strengthValue); }, [password]); const getStrengthColor = () => { switch (strength) { case 0: case 1: return 'bg-red-500'; case 2: return 'bg-orange-500'; case 3: return 'bg-yellow-500'; case 4: return 'bg-blue-500'; case 5: return 'bg-green-500'; default: return 'bg-gray-500'; } }; const getStrengthText = () => { switch (strength) { case 0: return 'Très faible'; case 1: return 'Faible'; case 2: return 'Moyen'; case 3: return 'Bon'; case 4: return 'Très bon'; case 5: return 'Excellent'; default: return ''; } }; const getStrengthTextColor = () => { switch (strength) { case 0: case 1: return 'text-red-700 dark:text-red-400'; case 2: return 'text-orange-700 dark:text-orange-400'; case 3: return 'text-yellow-700 dark:text-yellow-500'; case 4: return 'text-blue-700 dark:text-blue-400'; case 5: return 'text-green-700 dark:text-green-400'; default: return 'text-neutral-600 dark:text-neutral-400'; } }; if (!password && !showRequirements) { return null; } return (
{/* Strength Bar */} {password && (
Force du mot de passe : {getStrengthText()}
)} {/* Requirements - Only show if not all requirements are met */} {showRequirements && password && !Object.values(requirements).every(Boolean) && (
{!requirements.length && (
Au moins 8 caractères
)} {!requirements.maxLength && (
Maximum 128 caractères
)} {!requirements.uppercase && (
Au moins une majuscule
)} {!requirements.lowercase && (
Au moins une minuscule
)} {!requirements.number && (
Au moins un chiffre
)}
)}
); }