uchill/front_material/app/(auth)/forgot-password/page.tsx

146 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { requestPasswordReset } from '@/api/auth';
import { getErrorMessage } from '@/lib/error-utils';
const loadMaterialComponents = async () => {
await Promise.all([
import('@material/web/textfield/filled-text-field.js'),
import('@material/web/button/filled-button.js'),
import('@material/web/button/text-button.js'),
]);
};
export default function ForgotPasswordPage() {
const router = useRouter();
const [email, setEmail] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const [success, setSuccess] = useState(false);
const [componentsLoaded, setComponentsLoaded] = useState(false);
useEffect(() => {
loadMaterialComponents()
.then(() => setComponentsLoaded(true))
.catch((err) => {
console.error('Error loading components:', err);
setComponentsLoaded(true);
});
}, []);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
setError('');
setSuccess(false);
try {
await requestPasswordReset({ email });
setSuccess(true);
} catch (err: any) {
setError(getErrorMessage(err, 'Ошибка при отправке запроса. Проверьте email.'));
} finally {
setLoading(false);
}
};
if (!componentsLoaded) {
return (
<div style={{ display: 'flex', justifyContent: 'center', padding: '48px' }}>
<div
style={{
width: '40px',
height: '40px',
border: '3px solid #e0e0e0',
borderTopColor: 'var(--md-sys-color-primary, #6750a4)',
borderRadius: '50%',
animation: 'spin 0.8s linear infinite',
}}
/>
</div>
);
}
return (
<div style={{ width: '100%', maxWidth: '400px' }}>
<p style={{ fontSize: '14px', color: '#666', marginBottom: '28px' }}>
Восстановление пароля
</p>
{success ? (
<>
<div
style={{
padding: '16px',
marginBottom: '24px',
background: '#e8f5e9',
color: '#2e7d32',
borderRadius: '12px',
fontSize: '14px',
lineHeight: '1.5',
}}
>
Инструкции по восстановлению пароля отправлены на ваш email.
</div>
<md-filled-button
onClick={() => router.push('/login')}
style={{ width: '100%', height: '48px' }}
>
Вернуться к входу
</md-filled-button>
</>
) : (
<>
<p style={{ fontSize: '14px', color: '#666', marginBottom: '20px' }}>
Введите ваш email для восстановления пароля
</p>
<form onSubmit={handleSubmit}>
<div style={{ marginBottom: '20px' }}>
<md-filled-text-field
label="Email"
type="email"
value={email}
onInput={(e: any) => setEmail(e.target.value || '')}
required
style={{ width: '100%' }}
/>
</div>
{error && (
<div
style={{
padding: '12px 16px',
marginBottom: '20px',
background: '#ffebee',
color: '#c62828',
borderRadius: '12px',
fontSize: '14px',
}}
>
{error}
</div>
)}
<md-filled-button
type="submit"
disabled={loading}
style={{ width: '100%', height: '48px', marginBottom: '16px' }}
>
{loading ? 'Отправка...' : 'Отправить'}
</md-filled-button>
<div style={{ textAlign: 'center', marginTop: '20px' }}>
<md-text-button onClick={() => router.push('/login')} style={{ fontSize: '14px' }}>
Вернуться к входу
</md-text-button>
</div>
</form>
</>
)}
</div>
);
}