Add access request modal with Telegram notification
- Modal on login page: Name, Email, Phone with client-side validation - POST /request-access → sends Telegram message via corporate proxy - Includes IP + geo lookup (ip-api.com) - Success screen after submission, Esc/click-outside closes modal Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+140
-1
@@ -85,10 +85,149 @@
|
||||
<button type="submit">Войти</button>
|
||||
</form>
|
||||
|
||||
<p class="auth-footer">Нет аккаунта? <a href="{{ url_for('register') }}">Запросить доступ</a></p>
|
||||
<p class="auth-footer">Нет аккаунта? <a href="#" id="open-request-modal">Запросить доступ</a></p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Модал запроса доступа -->
|
||||
<div class="modal-overlay" id="request-modal">
|
||||
<div class="modal-card">
|
||||
<button class="modal-close" id="close-request-modal">×</button>
|
||||
|
||||
<div id="modal-form-view">
|
||||
<div class="auth-kicker" style="margin-bottom:16px">
|
||||
<img src="{{ url_for('static', filename='wb3.png') }}" class="auth-kicker-logo-img" alt="WB">
|
||||
</div>
|
||||
<h2 class="login-form-title">Запросить доступ</h2>
|
||||
<p style="font-size:13px;color:#6b7280;margin-bottom:20px;margin-top:-10px">Оставьте контакты — мы свяжемся и откроем доступ.</p>
|
||||
|
||||
<div class="alert alert-error" id="modal-error" style="display:none"></div>
|
||||
|
||||
<form class="auth-form" id="request-form" novalidate>
|
||||
<label>
|
||||
Имя
|
||||
<input type="text" name="name" placeholder="Иван Иванов" required autocomplete="name">
|
||||
<span class="field-error" id="err-name"></span>
|
||||
</label>
|
||||
<label>
|
||||
Email
|
||||
<input type="email" name="email" placeholder="ivan@company.ru" required autocomplete="email">
|
||||
<span class="field-error" id="err-email"></span>
|
||||
</label>
|
||||
<label>
|
||||
Телефон
|
||||
<input type="tel" name="phone" placeholder="+7 999 000-00-00" required autocomplete="tel">
|
||||
<span class="field-error" id="err-phone"></span>
|
||||
</label>
|
||||
<button type="submit" id="request-submit">Отправить запрос</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="modal-success-view" style="display:none;text-align:center;padding:20px 0">
|
||||
<div style="font-size:52px;margin-bottom:16px">✅</div>
|
||||
<h2 style="margin-bottom:10px">Запрос отправлен!</h2>
|
||||
<p style="font-size:14px;color:#6b7280">Мы получили ваши данные и скоро свяжемся с вами.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0,0,0,0.5);
|
||||
backdrop-filter: blur(6px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
.modal-overlay.active { opacity: 1; pointer-events: all; }
|
||||
.modal-card {
|
||||
background: #fff;
|
||||
border-radius: 22px;
|
||||
padding: 40px;
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
margin: 20px;
|
||||
position: relative;
|
||||
box-shadow: 0 32px 80px rgba(0,0,0,0.22);
|
||||
transform: translateY(20px) scale(0.98);
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
.modal-overlay.active .modal-card { transform: translateY(0) scale(1); }
|
||||
.modal-close {
|
||||
position: absolute;
|
||||
top: 14px; right: 14px;
|
||||
width: 32px; height: 32px;
|
||||
border-radius: 50%;
|
||||
background: #f3f4f6;
|
||||
border: none;
|
||||
font-size: 20px;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
color: #9ca3af;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
box-shadow: none; padding: 0;
|
||||
}
|
||||
.modal-close:hover { background: #e5e7eb; color: #374151; transform: none; filter: none; }
|
||||
.field-error { display: block; font-size: 11px; color: #dc2626; margin-top: 3px; min-height: 15px; }
|
||||
</style>
|
||||
|
||||
<script>
|
||||
const modal = document.getElementById('request-modal');
|
||||
const openBtn = document.getElementById('open-request-modal');
|
||||
const closeBtn = document.getElementById('close-request-modal');
|
||||
|
||||
openBtn.addEventListener('click', e => { e.preventDefault(); modal.classList.add('active'); });
|
||||
closeBtn.addEventListener('click', () => modal.classList.remove('active'));
|
||||
modal.addEventListener('click', e => { if (e.target === modal) modal.classList.remove('active'); });
|
||||
document.addEventListener('keydown', e => { if (e.key === 'Escape') modal.classList.remove('active'); });
|
||||
|
||||
document.getElementById('request-form').addEventListener('submit', async e => {
|
||||
e.preventDefault();
|
||||
const form = e.target;
|
||||
const name = form.name.value.trim();
|
||||
const email = form.email.value.trim();
|
||||
const phone = form.phone.value.trim();
|
||||
let valid = true;
|
||||
|
||||
['name','email','phone'].forEach(f => document.getElementById('err-' + f).textContent = '');
|
||||
document.getElementById('modal-error').style.display = 'none';
|
||||
|
||||
if (!name)
|
||||
{ document.getElementById('err-name').textContent = 'Введите имя'; valid = false; }
|
||||
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email))
|
||||
{ document.getElementById('err-email').textContent = 'Введите корректный email'; valid = false; }
|
||||
if (!phone || phone.replace(/\D/g, '').length < 10)
|
||||
{ document.getElementById('err-phone').textContent = 'Введите корректный телефон'; valid = false; }
|
||||
if (!valid) return;
|
||||
|
||||
const btn = document.getElementById('request-submit');
|
||||
btn.disabled = true; btn.textContent = 'Отправка…';
|
||||
|
||||
try {
|
||||
const res = await fetch('/request-access', { method: 'POST', body: new FormData(form) });
|
||||
const data = await res.json();
|
||||
if (data.ok) {
|
||||
document.getElementById('modal-form-view').style.display = 'none';
|
||||
document.getElementById('modal-success-view').style.display = 'block';
|
||||
} else {
|
||||
document.getElementById('modal-error').textContent = data.error || 'Ошибка. Попробуйте ещё раз.';
|
||||
document.getElementById('modal-error').style.display = 'block';
|
||||
btn.disabled = false; btn.textContent = 'Отправить запрос';
|
||||
}
|
||||
} catch {
|
||||
document.getElementById('modal-error').textContent = 'Ошибка сети. Попробуйте ещё раз.';
|
||||
document.getElementById('modal-error').style.display = 'block';
|
||||
btn.disabled = false; btn.textContent = 'Отправить запрос';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user