Checkpoint: Ajout de la fonctionnalité complète de réinitialisation de mot de passe avec génération de tokens temporaires (24h), stockage en base de données, et envoi d'emails automatiques. Nouveau bouton dans la page de gestion des utilisateurs avec dialogue de confirmation.
This commit is contained in:
@@ -28,7 +28,7 @@ import {
|
||||
} from "@/components/ui/select";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { toast } from "sonner";
|
||||
import { Pencil, Trash2, UserCheck, UserX, Search, Plus } from "lucide-react";
|
||||
import { Pencil, Trash2, UserCheck, UserX, Search, Plus, KeyRound } from "lucide-react";
|
||||
|
||||
export default function AdminUsers() {
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
@@ -37,6 +37,7 @@ export default function AdminUsers() {
|
||||
const [createDialogOpen, setCreateDialogOpen] = useState(false);
|
||||
const [editDialogOpen, setEditDialogOpen] = useState(false);
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [resetPasswordDialogOpen, setResetPasswordDialogOpen] = useState(false);
|
||||
const [selectedUser, setSelectedUser] = useState<any>(null);
|
||||
const [createForm, setCreateForm] = useState({
|
||||
openId: "",
|
||||
@@ -101,6 +102,16 @@ export default function AdminUsers() {
|
||||
},
|
||||
});
|
||||
|
||||
const resetPasswordMutation = trpc.users.requestPasswordReset.useMutation({
|
||||
onSuccess: () => {
|
||||
toast.success("Email de réinitialisation envoyé avec succès");
|
||||
setResetPasswordDialogOpen(false);
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.error(`Erreur : ${error.message}`);
|
||||
},
|
||||
});
|
||||
|
||||
const handleCreate = () => {
|
||||
setCreateDialogOpen(true);
|
||||
};
|
||||
@@ -158,6 +169,16 @@ export default function AdminUsers() {
|
||||
deleteMutation.mutate({ id: selectedUser.id });
|
||||
};
|
||||
|
||||
const handleResetPassword = (user: any) => {
|
||||
setSelectedUser(user);
|
||||
setResetPasswordDialogOpen(true);
|
||||
};
|
||||
|
||||
const confirmResetPassword = () => {
|
||||
if (!selectedUser) return;
|
||||
resetPasswordMutation.mutate({ id: selectedUser.id });
|
||||
};
|
||||
|
||||
// Filtrage des utilisateurs
|
||||
const filteredUsers = users.filter((user) => {
|
||||
const matchesSearch =
|
||||
@@ -301,6 +322,15 @@ export default function AdminUsers() {
|
||||
>
|
||||
<Pencil className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleResetPassword(user)}
|
||||
title="Réinitialiser le mot de passe"
|
||||
disabled={!user.email}
|
||||
>
|
||||
<KeyRound className="h-4 w-4 text-blue-500" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
@@ -464,6 +494,42 @@ export default function AdminUsers() {
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* Dialog de réinitialisation de mot de passe */}
|
||||
<Dialog open={resetPasswordDialogOpen} onOpenChange={setResetPasswordDialogOpen}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Réinitialiser le mot de passe</DialogTitle>
|
||||
<DialogDescription>
|
||||
Êtes-vous sûr de vouloir envoyer un email de réinitialisation de mot de passe à{" "}
|
||||
<strong>{selectedUser?.name || selectedUser?.email}</strong> ?
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="bg-blue-50 border-l-4 border-blue-500 p-4 my-4">
|
||||
<p className="text-sm text-blue-900">
|
||||
<strong>ℹ️ Information :</strong>
|
||||
</p>
|
||||
<ul className="text-sm text-blue-800 mt-2 space-y-1 list-disc list-inside">
|
||||
<li>Un email sera envoyé à : <strong>{selectedUser?.email}</strong></li>
|
||||
<li>Le lien de réinitialisation sera valide pendant 24 heures</li>
|
||||
<li>Il ne pourra être utilisé qu'une seule fois</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => setResetPasswordDialogOpen(false)}>
|
||||
Annuler
|
||||
</Button>
|
||||
<Button
|
||||
onClick={confirmResetPassword}
|
||||
disabled={resetPasswordMutation.isPending}
|
||||
>
|
||||
{resetPasswordMutation.isPending ? "Envoi en cours..." : "Envoyer l'email"}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* Dialog de suppression */}
|
||||
<Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
|
||||
<DialogContent>
|
||||
|
||||
Reference in New Issue
Block a user