Spaces:
Runtime error
Runtime error
import { InformationCircleIcon } from '@heroicons/react/24/outline'; | |
import { passwordStrength } from 'check-password-strength'; | |
import clsx from 'clsx'; | |
import { useEffect, useState } from 'react'; | |
import { useTranslation } from 'react-i18next'; | |
import { | |
HoverCard, | |
HoverCardContent, | |
HoverCardTrigger, | |
// eslint-disable-next-line import/extensions | |
} from '@/components/ui/hover-card'; | |
type PasswordStrengthCardProps = { | |
password: string; | |
}; | |
export const PasswordStrengthCard: React.FC<PasswordStrengthCardProps> = ({ | |
password, | |
}) => { | |
const { t } = useTranslation(); | |
const [strength, setStrength] = useState(passwordStrength(password)); | |
useEffect(() => { | |
setStrength(passwordStrength(password)); | |
}, [password]); | |
let cardText = { | |
title: t('noPasswordTitle'), | |
text: t('noPasswordText'), | |
}; | |
if (password !== '') { | |
switch (strength.value) { | |
case 'Strong': | |
cardText = { | |
title: t('strongPasswordTitle'), | |
text: t('strongPasswordText'), | |
}; | |
break; | |
case 'Medium': | |
cardText = { | |
title: t('mediumPasswordTitle'), | |
text: t('mediumPasswordText'), | |
}; | |
break; | |
case 'Weak': | |
cardText = { | |
title: t('weakPasswordTitle'), | |
text: t('weakPasswordText'), | |
}; | |
break; | |
case 'Too weak': | |
cardText = { | |
title: t('tooWeakPasswordTitle'), | |
text: t('tooWeakPasswordText'), | |
}; | |
break; | |
default: | |
cardText = { | |
title: t('noPasswordTitle'), | |
text: t('noPasswordText'), | |
}; | |
break; | |
} | |
} | |
return ( | |
<div | |
className={clsx('p-4 relative rounded-lg', { | |
'bg-red-400': strength.value === 'Too weak' && password !== '', | |
'bg-yellow-400': strength.value === 'Weak', | |
'bg-green-400': strength.value === 'Medium', | |
'bg-sky-400': strength.value === 'Strong', | |
'bg-stone-400': password === '', | |
})} | |
> | |
<div | |
className={clsx('absolute top-0 left-0 bottom-0 w-2 rounded-l-lg', { | |
'bg-red-600': strength.value === 'Too weak' && password !== '', | |
'bg-yellow-600': strength.value === 'Weak', | |
'bg-green-600': strength.value === 'Medium', | |
'bg-sky-600': strength.value === 'Strong', | |
'bg-stone-600': password === '', | |
})} | |
/> | |
<h1 | |
className={clsx('font-bold underline', { | |
'text-black': | |
strength.value === 'Medium' || | |
strength.value === 'Strong' || | |
strength.value === 'Weak', | |
})} | |
> | |
{cardText.title} | |
</h1> | |
<p | |
className={clsx({ | |
'font-bold': true, | |
'text-black': password !== '' && strength.value !== 'Too weak', | |
})} | |
> | |
{cardText.text} | |
</p> | |
<div className="sm:hidden md:block"> | |
<HoverCard> | |
<HoverCardTrigger> | |
<InformationCircleIcon | |
className={clsx('absolute top-5 right-2 bottom-0 size-8 ', { | |
'text-black': | |
strength.value === 'Medium' || | |
strength.value === 'Strong' || | |
strength.value === 'Weak', | |
})} | |
/> | |
</HoverCardTrigger> | |
<HoverCardContent className="absolute"> | |
{t('passwordStrengthInfo')} | |
</HoverCardContent> | |
</HoverCard> | |
</div> | |
<p | |
className={clsx('text-sm italic text-stone-500 md:hidden', { | |
hidden: strength.value === 'Strong', | |
})} | |
> | |
{t('passwordStrengthInfo')} | |
</p> | |
</div> | |
); | |
}; | |