142 lines
6.5 KiB
TypeScript
142 lines
6.5 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { KeyRound, AlertCircle, ShieldCheck } from "lucide-react";
|
|
import { Card } from '@/components/ui/Card';
|
|
import { Input } from '@/components/ui/Input';
|
|
import { Button } from '@/components/ui/Button';
|
|
import { pb } from '@/services/pocketbase';
|
|
import BackButton from '@/components/ui/BackButton';
|
|
import { NEUMORPHISM } from '@/styles/Neumorphism';
|
|
|
|
export default function UpdatePasswordPage() {
|
|
const navigate = useNavigate();
|
|
|
|
const [isUpdating, setIsUpdating] = useState(false);
|
|
const [feedback, setFeedback] = useState<{ type: 'error' | 'success', message: string } | null>(null);
|
|
|
|
const [formData, setFormData] = useState({
|
|
oldPassword: '',
|
|
newPassword: '',
|
|
confirmPassword: ''
|
|
});
|
|
|
|
const handlePasswordChange = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
setIsUpdating(true);
|
|
setFeedback(null);
|
|
|
|
if (formData.newPassword !== formData.confirmPassword) {
|
|
setFeedback({ type: 'error', message: "Les nouveaux mots de passe ne correspondent pas." });
|
|
setIsUpdating(false);
|
|
return;
|
|
}
|
|
|
|
if (formData.newPassword.length < 8) {
|
|
setFeedback({ type: 'error', message: "Le mot de passe doit contenir au moins 8 caractères minimum." });
|
|
setIsUpdating(false);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const userId = pb.authStore.model?.id;
|
|
if (!userId) throw new Error("Non authentifié.");
|
|
|
|
await pb.collection("users").update(userId, {
|
|
oldPassword: formData.oldPassword,
|
|
password: formData.newPassword,
|
|
passwordConfirm: formData.confirmPassword,
|
|
});
|
|
|
|
setFeedback({ type: 'success', message: "Votre mot de passe a été modifié avec succès." });
|
|
setFormData({ oldPassword: '', newPassword: '', confirmPassword: '' });
|
|
|
|
// Retour automatique après 2.5 secondes
|
|
setTimeout(() => navigate(-1), 2500);
|
|
|
|
} catch {
|
|
setFeedback({ type: 'error', message: "Ancien mot de passe incorrect ou erreur réseau." });
|
|
} finally {
|
|
setIsUpdating(false);
|
|
}
|
|
};
|
|
return (
|
|
<div className="max-w-4xl mx-auto py-8 px-4 space-y-6">
|
|
|
|
{/* BOUTON DE RETOUR EXTRAIT */}
|
|
<BackButton to="/account" label="Retour aux paramètres" />
|
|
|
|
{/* LE FORMULAIRE */}
|
|
<Card className="p-8 sm:p-10">
|
|
<div className="flex items-center gap-4 mb-8 pb-6 border-b border-slate-300/30 dark:border-slate-700/30">
|
|
<div className="p-4 rounded-2xl bg-[#e8e8e8] dark:bg-[#1e293b] shadow-[3px_3px_6px_#c5c5c5,-3px_-3px_6px_#ffffff] dark:shadow-[3px_3px_6px_#121926,-3px_-3px_6px_#2a3850]">
|
|
<KeyRound className="w-8 h-8 text-slate-700 dark:text-slate-200" />
|
|
</div>
|
|
<div>
|
|
<h1 className="text-2xl font-black text-slate-800 dark:text-slate-100 tracking-tight">
|
|
Renouvellement du mot de passe
|
|
</h1>
|
|
<p className="text-slate-500 dark:text-slate-400 font-medium mt-1">
|
|
Veuillez choisir un mot de passe fort et unique pour sécuriser votre accès AEGIS.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<form onSubmit={handlePasswordChange} className="space-y-6">
|
|
<div className="space-y-2">
|
|
<Input
|
|
label="Mot de passe actuel"
|
|
type="password"
|
|
required
|
|
placeholder="••••••••"
|
|
value={formData.oldPassword}
|
|
onChange={(e) => setFormData({ ...formData, oldPassword: e.target.value })}
|
|
/>
|
|
</div>
|
|
|
|
<div className="grid sm:grid-cols-2 gap-6 pt-4">
|
|
<Input
|
|
label="Nouveau mot de passe"
|
|
type="password"
|
|
required
|
|
placeholder="••••••••"
|
|
value={formData.newPassword}
|
|
onChange={(e) => setFormData({ ...formData, newPassword: e.target.value })}
|
|
/>
|
|
<Input
|
|
label="Confirmez le nouveau mot de passe"
|
|
type="password"
|
|
required
|
|
placeholder="••••••••"
|
|
value={formData.confirmPassword}
|
|
onChange={(e) => setFormData({ ...formData, confirmPassword: e.target.value })}
|
|
/>
|
|
</div>
|
|
|
|
{/* Zone de Feedback */}
|
|
{feedback && (
|
|
<div className={`p-4 mt-4 rounded-xl flex items-center gap-3 text-sm font-bold ${feedback.type === 'error'
|
|
? `bg-rose-50/50 dark:bg-rose-950/20 text-rose-600 dark:text-rose-400 ${NEUMORPHISM.insetLight} ${NEUMORPHISM.insetDark}`
|
|
: `bg-emerald-50/50 dark:bg-emerald-950/20 text-emerald-600 dark:text-emerald-400 ${NEUMORPHISM.insetLight} ${NEUMORPHISM.insetDark}`
|
|
}`}>
|
|
{feedback.type === 'error' ? <AlertCircle className="w-5 h-5 shrink-0" /> : <ShieldCheck className="w-5 h-5 shrink-0" />}
|
|
{feedback.message}
|
|
{feedback.type === 'success' && <span className="ml-auto font-normal text-xs animate-pulse">Redirection...</span>}
|
|
</div>
|
|
)}
|
|
|
|
<div className="pt-6 flex justify-center">
|
|
<Button
|
|
type="submit"
|
|
variant="primary"
|
|
size="lg"
|
|
isLoading={isUpdating}
|
|
disabled={!formData.oldPassword || !formData.newPassword || !formData.confirmPassword}
|
|
>
|
|
Valider le nouveau mot de passe
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</Card>
|
|
</div>
|
|
);
|
|
} |