chore: import DH V2 D5.6.4 production baseline
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
import { useState } from 'react';
|
||||
import type { FormEvent } from 'react';
|
||||
import { useNavigate } from 'react-router';
|
||||
import { useAuth } from '../auth/AuthContext';
|
||||
import { Alert, errorMessage } from '../components/Feedback';
|
||||
import { Icon } from '../components/Icon';
|
||||
|
||||
export function ChangePasswordPage() {
|
||||
const { user, changePassword, logout } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const [currentPassword, setCurrentPassword] = useState('');
|
||||
const [newPassword, setNewPassword] = useState('');
|
||||
const [confirmation, setConfirmation] = useState('');
|
||||
const [error, setError] = useState('');
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
|
||||
const submit = async (event: FormEvent) => {
|
||||
event.preventDefault();
|
||||
setError('');
|
||||
if (newPassword !== confirmation) return setError('Las contraseñas nuevas no coinciden');
|
||||
if (newPassword.length < 12) return setError('La nueva contraseña debe tener al menos 12 caracteres');
|
||||
setSubmitting(true);
|
||||
try {
|
||||
await changePassword(currentPassword, newPassword);
|
||||
navigate('/', { replace: true });
|
||||
} catch (requestError) {
|
||||
setError(errorMessage(requestError));
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
const leave = async () => {
|
||||
await logout().catch(() => undefined);
|
||||
navigate('/login', { replace: true });
|
||||
};
|
||||
|
||||
return (
|
||||
<main className="centered-page">
|
||||
<form className="login-card password-card" onSubmit={submit}>
|
||||
<div className="round-icon"><Icon name="key" size={24} /></div>
|
||||
<span className="eyebrow">SEGURIDAD DE CUENTA</span>
|
||||
<h2>{user?.mustChangePassword ? 'Cambiá tu contraseña temporal' : 'Cambiar contraseña'}</h2>
|
||||
<p className="muted">Usá al menos 12 caracteres. Las demás sesiones abiertas se cerrarán automáticamente.</p>
|
||||
{error && <Alert>{error}</Alert>}
|
||||
<label className="field"><span>Contraseña actual</span><input type="password" autoComplete="current-password" value={currentPassword} onChange={(event) => setCurrentPassword(event.target.value)} required /></label>
|
||||
<label className="field"><span>Nueva contraseña</span><input type="password" autoComplete="new-password" minLength={12} value={newPassword} onChange={(event) => setNewPassword(event.target.value)} required /></label>
|
||||
<label className="field"><span>Repetir nueva contraseña</span><input type="password" autoComplete="new-password" minLength={12} value={confirmation} onChange={(event) => setConfirmation(event.target.value)} required /></label>
|
||||
<button className="button primary wide" disabled={submitting}>{submitting ? 'Guardando…' : 'Guardar nueva contraseña'}</button>
|
||||
<button className="button text wide" type="button" onClick={leave}>Cerrar sesión</button>
|
||||
</form>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user