"use client";
import { useState } from "react";
import { Eye, EyeOff, Lock, Check, KeyRound } from "lucide-react";
import Modal from "../ui/Modal";
import Button from "../ui/Button";
import toast from "react-hot-toast";
interface ChangePasswordModalProps {
isOpen: boolean;
onClose: () => void;
}
function strength(pwd: string): { score: number; label: string; bar: string } {
if (!pwd) return { score: 0, label: "", bar: "bg-gray-300" };
let s = 0;
if (pwd.length >= 8) s++;
if (pwd.length >= 12) s++;
if (/[A-Z]/.test(pwd) && /[a-z]/.test(pwd)) s++;
if (/\d/.test(pwd)) s++;
if (/[^A-Za-z0-9]/.test(pwd)) s++;
const labels = ["", "Très faible", "Faible", "Moyen", "Bon", "Excellent"];
const bars = ["bg-gray-300", "bg-rose-500", "bg-orange-500", "bg-amber-500", "bg-emerald-500", "bg-emerald-500"];
return { score: s, label: labels[s], bar: bars[s] };
}
function Field({
label, value, onChange, show, onToggle, placeholder, autoFocus, extraClass = "", onEnter, showToggle = true, trailing,
}: {
label: string; value: string; onChange: (v: string) => void; show?: boolean; onToggle?: () => void;
placeholder: string; autoFocus?: boolean; extraClass?: string; onEnter?: () => void; showToggle?: boolean; trailing?: React.ReactNode;
}): React.ReactElement {
return (
);
}
export default function ChangePasswordModal({ isOpen, onClose }: ChangePasswordModalProps) {
const [currentPassword, setCurrentPassword] = useState("");
const [newPassword, setNewPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [showCurrent, setShowCurrent] = useState(false);
const [showNew, setShowNew] = useState(false);
const [loading, setLoading] = useState(false);
const handleClose = () => {
setCurrentPassword("");
setNewPassword("");
setConfirmPassword("");
setShowCurrent(false);
setShowNew(false);
onClose();
};
const passwordsMatch = newPassword && confirmPassword && newPassword === confirmPassword;
const newPasswordValid = newPassword.length >= 6;
const canSubmit = currentPassword && newPasswordValid && passwordsMatch;
const st = strength(newPassword);
const handleSubmit = async () => {
if (!canSubmit) return;
setLoading(true);
try {
const res = await fetch("/api/auth/change-password", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ currentPassword, newPassword }),
});
const data = await res.json();
if (res.ok) {
toast.success("Mot de passe modifié avec succès");
handleClose();
} else {
toast.error(data.error || "Erreur");
}
} catch {
toast.error("Erreur réseau");
} finally {
setLoading(false);
}
};
return (
>
}
>
setShowCurrent(!showCurrent)} placeholder="••••••••" autoFocus />
setShowNew(!showNew)}
placeholder="Min. 6 caractères"
extraClass={newPassword && !newPasswordValid ? "!border-rose-400" : ""}
/>
{newPassword && (
{Array.from({ length: 5 }).map((_, i) => (
))}
{st.label}
)}
{newPassword && !newPasswordValid && Au moins 6 caractères requis
}
: undefined}
/>
{confirmPassword && !passwordsMatch &&
Les mots de passe ne correspondent pas
}
);
}