Add src/components/onboarding/PasswordRequirements.jsx
This commit is contained in:
parent
f2d1b864e8
commit
4a7a0cb26a
|
|
@ -0,0 +1,51 @@
|
||||||
|
import React from "react";
|
||||||
|
import { Check, X } from "lucide-react";
|
||||||
|
import { motion, AnimatePresence } from "framer-motion";
|
||||||
|
|
||||||
|
const requirements = [
|
||||||
|
{ label: "At least 8 characters long", test: (p) => p.length >= 8 },
|
||||||
|
{ label: "Contains an uppercase letter", test: (p) => /[A-Z]/.test(p) },
|
||||||
|
{ label: "Contains a lowercase letter", test: (p) => /[a-z]/.test(p) },
|
||||||
|
{ label: "Contains a number", test: (p) => /[0-9]/.test(p) },
|
||||||
|
{ label: "Contains a special character (!@#$%^&*)", test: (p) => /[!@#$%^&*(),.?":{}|<>]/.test(p) },
|
||||||
|
];
|
||||||
|
|
||||||
|
export function validatePassword(password) {
|
||||||
|
return requirements.every((req) => req.test(password));
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function PasswordRequirements({ password, visible }) {
|
||||||
|
return (
|
||||||
|
<AnimatePresence>
|
||||||
|
{visible && (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, height: 0 }}
|
||||||
|
animate={{ opacity: 1, height: "auto" }}
|
||||||
|
exit={{ opacity: 0, height: 0 }}
|
||||||
|
transition={{ duration: 0.2 }}
|
||||||
|
className="overflow-hidden"
|
||||||
|
>
|
||||||
|
<div className="bg-slate-50 rounded-xl p-4 border border-slate-200 mt-2 space-y-2">
|
||||||
|
<p className="text-xs font-semibold text-slate-500 uppercase tracking-wider mb-2">
|
||||||
|
Password Requirements
|
||||||
|
</p>
|
||||||
|
{requirements.map((req, i) => {
|
||||||
|
const met = req.test(password);
|
||||||
|
return (
|
||||||
|
<div key={i} className="flex items-center gap-2">
|
||||||
|
<div
|
||||||
|
className={`w-4 h-4 rounded-full flex items-center justify-center transition-all duration-200 ${
|
||||||
|
met ? "bg-emerald-500" : "bg-slate-300"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{met ? (
|
||||||
|
<Check className="w-2.5 h-2.5 text-white" />
|
||||||
|
) : (
|
||||||
|
<X className="w-2.5 h-2.5 text-white" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
className={`text-sm transition-colors duration-200 ${
|
||||||
|
met ? "text-emerald-700 font-medium" : "text-slate-500"
|
||||||
|
}`}
|
||||||
|
|
||||||
Loading…
Reference in New Issue