frontend_nyla/src/pages/PasswordResetRequest.tsx
ValueOn AG 7d2808d22e hotfix
2026-01-13 07:25:32 +01:00

129 lines
4.8 KiB
TypeScript

import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import styles from './PasswordResetRequest.module.css';
import { usePasswordResetRequest } from '../hooks/useAuthentication';
import { generateAndStoreCSRFToken } from '../utils/csrfUtils';
function PasswordResetRequest() {
const navigate = useNavigate();
const { requestReset, isLoading } = usePasswordResetRequest();
const [username, setUsername] = useState('');
const [usernameFocused, setUsernameFocused] = useState(false);
const [validationError, setValidationError] = useState<string | null>(null);
const [successMessage, setSuccessMessage] = useState<string | null>(null);
// Set page title and generate CSRF token
useEffect(() => {
document.title = "PowerOn AI Platform - Passwort zurücksetzen";
generateAndStoreCSRFToken();
}, []);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setValidationError(null);
if (!username.trim()) {
setValidationError('Bitte geben Sie Ihren Benutzernamen ein.');
return;
}
try {
await requestReset(username.trim());
setSuccessMessage('Falls ein Konto mit diesem Benutzernamen existiert, wurde ein Reset-Link an die hinterlegte E-Mail-Adresse gesendet. Bitte prüfen Sie auch Ihren Spam-Ordner.');
// Redirect to login after delay
setTimeout(() => {
navigate('/login', {
state: {
passwordResetRequested: true,
message: 'Bitte prüfen Sie Ihre E-Mail für den Passwort-Reset-Link.'
}
});
}, 5000);
} catch (err) {
// For security, still show success message even on error
setSuccessMessage('Falls ein Konto mit diesem Benutzernamen existiert, wurde ein Reset-Link an die hinterlegte E-Mail-Adresse gesendet. Bitte prüfen Sie auch Ihren Spam-Ordner.');
setTimeout(() => {
navigate('/login');
}, 5000);
}
};
return (
<div className={styles.container}>
<div className={styles.mainContent}>
<div className={styles.logo}>
<div className={styles.logoText}>
<span className={styles.logoPower}>Power</span>
<span className={styles.logoOn}>On</span>
</div>
</div>
<div className={styles.loginSection}>
<div className={styles.loginBox}>
<h2 className={styles.title}>Passwort zurücksetzen</h2>
<div className={styles.loginForm}>
{validationError && (
<div className={styles.error}>{validationError}</div>
)}
{successMessage && (
<div className={styles.success}>{successMessage}</div>
)}
{!successMessage && (
<>
<div className={styles.floatingLabelInput}>
<input
type="text"
placeholder=" "
value={username}
onChange={(e) => {
setUsername(e.target.value);
setValidationError(null);
}}
onFocus={() => setUsernameFocused(true)}
onBlur={() => setUsernameFocused(false)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault();
handleSubmit(e);
}
}}
className={`${styles.input} ${usernameFocused || username ? styles.focused : ''}`}
/>
<label className={usernameFocused || username ? styles.focusedLabel : styles.label}>Benutzername</label>
</div>
<div className={styles.infoMessage}>
<p>Geben Sie Ihren Benutzernamen ein. Falls ein Konto existiert, erhalten Sie einen Link zum Zurücksetzen des Passworts an Ihre hinterlegte E-Mail-Adresse.</p>
</div>
<button
className={`${styles.button} ${styles.loginButton}`}
onClick={handleSubmit}
disabled={isLoading}
>
{isLoading ? "Wird gesendet..." : "Reset-Link anfordern"}
</button>
</>
)}
<div className={styles.registerLink}>
<span>Zurück zum</span>
<button
className={styles.textButton}
onClick={() => navigate("/login")}
>
Login
</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
export default PasswordResetRequest;