astro_avtourist/frontend/src/pages/auth/forgot-password.astro

353 lines
No EOL
8.9 KiB
Text
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.

---
import Layout from '@layouts/Layout.astro';
import { SITE_URL } from '@constants';
---
<Layout
title="Восстановление пароля"
description="Восстановите доступ к аккаунту"
canonicalLink={`${SITE_URL}/auth/forgot-password`}
>
<div class="auth-page">
<div class="auth-container">
<div class="auth-card">
<div class="auth-header">
<h1>Восстановление пароля</h1>
<p>Введите email для сброса пароля</p>
</div>
<form class="auth-form" id="forgot-form">
<div class="form-group">
<label for="email">Email</label>
<input
type="email"
id="email"
name="email"
placeholder="example@mail.ru"
required
autocomplete="email"
inputmode="email"
/>
<span class="error-message" id="email-error"></span>
</div>
<button type="submit" class="btn-submit" id="submit-btn">
Отправить ссылку
</button>
</form>
<div class="auth-messages">
<div class="success-message hidden" id="success-message">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path>
<polyline points="22 4 12 14.01 9 11.01"></polyline>
</svg>
<p>На ваш email отправлена ссылка для сброса пароля</p>
</div>
<div class="error-message hidden" id="form-error"></div>
</div>
<div class="auth-footer">
<p>Вспомнили пароль? <a href="/auth/sign-in">Войти</a></p>
</div>
</div>
</div>
</div>
</Layout>
<script>
const form = document.getElementById('forgot-form') as HTMLFormElement;
const emailInput = document.getElementById('email') as HTMLInputElement;
const submitBtn = document.getElementById('submit-btn') as HTMLButtonElement;
const successMessage = document.getElementById('success-message');
const formError = document.getElementById('form-error');
form?.addEventListener('submit', async (e) => {
e.preventDefault();
const email = emailInput.value.trim();
if (!email) return;
submitBtn.disabled = true;
submitBtn.textContent = 'Отправка...';
try {
const response = await fetch('/api/auth/request-password-reset', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email }),
});
const data = await response.json();
if (response.ok && data.success) {
form.classList.add('hidden');
successMessage?.classList.remove('hidden');
} else {
const errorEl = document.getElementById('email-error');
if (errorEl) errorEl.textContent = data.error || 'Ошибка';
}
} catch (err) {
if (formError) {
formError.textContent = 'Ошибка соединения';
formError.classList.remove('hidden');
}
} finally {
submitBtn.disabled = false;
submitBtn.textContent = 'Отправить ссылку';
}
});
</script>
<style>
.auth-page {
min-height: calc(100vh - 160px);
background: linear-gradient(135deg, #f5f7fa 0%, #e8ecf1 100%);
display: flex;
align-items: center;
justify-content: center;
padding: 6rem 2rem 2rem;
}
.auth-container {
width: 100%;
max-width: 440px;
}
.auth-card {
background: #ffffff;
border-radius: 16px;
padding: 2rem;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
}
.auth-header {
text-align: center;
margin-bottom: 2rem;
}
.auth-header h1 {
color: #1e3050;
font-size: 1.5rem;
font-weight: 700;
margin: 0 0 0.5rem;
}
.auth-header p {
color: #64748b;
font-size: 0.95rem;
margin: 0;
}
.form-group {
margin-bottom: 1.5rem;
}
.form-group label {
display: block;
color: #1e3050;
font-size: 0.875rem;
font-weight: 600;
margin-bottom: 0.5rem;
}
.form-group input {
width: 100%;
padding: 0.75rem 1rem;
border: 1px solid #e2e8f0;
border-radius: 8px;
font-size: 0.95rem;
transition: border-color 0.2s, box-shadow 0.2s;
}
.form-group input:focus {
outline: none;
border-color: #eac26e;
box-shadow: 0 0 0 3px rgba(234, 194, 110, 0.2);
}
.error-message {
color: #ef4444;
font-size: 0.8rem;
margin-top: 0.25rem;
display: block;
}
.btn-submit {
width: 100%;
padding: 0.875rem;
background: linear-gradient(135deg, #eac26e 0%, #ce9f40 100%);
color: #ffffff;
border: none;
border-radius: 8px;
font-size: 0.95rem;
font-weight: 700;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
}
.btn-submit:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(206, 159, 64, 0.4);
}
.btn-submit:disabled {
opacity: 0.7;
cursor: not-allowed;
}
.auth-messages {
margin-top: 1.5rem;
text-align: center;
}
.success-message {
display: flex;
align-items: center;
gap: 0.75rem;
color: #10b981;
padding: 1rem;
background: #ecfdf5;
border-radius: 8px;
}
.success-message svg {
flex-shrink: 0;
}
.success-message p {
margin: 0;
font-size: 0.95rem;
}
.auth-footer {
margin-top: 1.5rem;
text-align: center;
padding-top: 1.5rem;
border-top: 1px solid #e2e8f0;
}
.auth-footer p {
color: #64748b;
font-size: 0.9rem;
margin: 0;
}
.auth-footer a {
color: #eac26e;
text-decoration: none;
font-weight: 600;
}
.auth-footer a:hover {
text-decoration: underline;
}
.hidden {
display: none !important;
}
@media (max-width: 480px) {
.auth-page {
padding: 5rem 1rem 1.5rem;
}
.auth-card {
padding: 1.5rem 1rem;
}
.auth-header h1 {
font-size: 1.35rem;
}
.auth-header p {
font-size: 0.85rem;
}
.form-group {
margin-bottom: 1rem;
}
.form-group label {
font-size: 0.8rem;
}
.form-group input {
padding: 0.5rem 0.65rem;
font-size: 0.85rem;
border-radius: 6px;
}
.form-group input::placeholder {
font-size: 0.8rem;
}
.error-message {
font-size: 0.7rem;
}
.btn-submit {
padding: 0.65rem;
font-size: 0.9rem;
border-radius: 6px;
}
.success-message h2 {
font-size: 1.25rem;
}
.success-message p {
font-size: 0.9rem;
}
.auth-footer p {
font-size: 0.85rem;
}
}
@media (max-width: 375px) {
.auth-page {
padding: 4.5rem 0.75rem 1rem;
}
.auth-card {
padding: 1.25rem 0.75rem;
border-radius: 12px;
}
.auth-header h1 {
font-size: 1.2rem;
}
.form-group input {
padding: 0.45rem 0.55rem;
font-size: 0.8rem;
}
.btn-submit {
padding: 0.55rem;
font-size: 0.85rem;
}
}
@media (max-width: 320px) {
.auth-page {
padding: 4rem 0.5rem 0.75rem;
}
.auth-card {
padding: 1rem 0.5rem;
}
.form-group input {
padding: 0.4rem 0.5rem;
font-size: 0.75rem;
}
.btn-submit {
padding: 0.5rem;
font-size: 0.8rem;
}
}
</style>