Files
tg_loader/web/admin/templates/login.html
2025-12-04 00:12:56 +03:00

221 lines
11 KiB
HTML

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Вход - TGLoader Admin</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css" rel="stylesheet">
<style>
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.login-card {
border: none;
border-radius: 1rem;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
max-width: 450px;
width: 100%;
}
.login-tabs {
border-bottom: 2px solid #dee2e6;
}
.nav-link {
color: #6c757d;
}
.nav-link.active {
color: #667eea;
border-bottom-color: #667eea;
}
</style>
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card login-card">
<div class="card-body p-5">
<div class="text-center mb-4">
<i class="bi bi-robot" style="font-size: 3rem; color: #667eea;"></i>
<h2 class="mt-3">TGLoader</h2>
<p class="text-muted">Вход в веб-интерфейс</p>
</div>
{% if error %}
<div class="alert alert-danger" role="alert">
<i class="bi bi-exclamation-triangle me-2"></i>{{ error }}
</div>
{% endif %}
<!-- Вкладки -->
<ul class="nav nav-tabs login-tabs mb-4" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="otp-tab" data-bs-toggle="tab"
data-bs-target="#otp-pane" type="button" role="tab">
<i class="bi bi-key me-2"></i>По коду
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="admin-tab" data-bs-toggle="tab"
data-bs-target="#admin-pane" type="button" role="tab">
<i class="bi bi-shield-check me-2"></i>Админ (по ID)
</button>
</li>
</ul>
<div class="tab-content">
<!-- Вход по OTP коду -->
<div class="tab-pane fade show active" id="otp-pane" role="tabpanel">
<div class="mb-3">
<label for="identifier" class="form-label">Telegram User ID или Username</label>
<input type="text" class="form-control" id="identifier"
placeholder="Введите ваш User ID или @username">
<small class="form-text text-muted">
Код будет отправлен вам в Telegram
</small>
</div>
<button type="button" class="btn btn-outline-primary w-100 mb-3"
onclick="requestOTP()">
<i class="bi bi-send me-2"></i>Получить код
</button>
<div id="otp-input-group" style="display: none;">
<div class="mb-3">
<label for="otp_code" class="form-label">Одноразовый код</label>
<input type="text" class="form-control" id="otp_code" name="otp_code"
placeholder="Введите код из Telegram" maxlength="6">
<small class="form-text text-muted">
Код действителен 10 минут
</small>
</div>
<form method="POST" action="/admin/login" id="otp-form">
{% if csrf_token %}
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
{% endif %}
<input type="hidden" name="otp_code" id="otp_code_hidden">
<button type="submit" class="btn btn-primary w-100">
<i class="bi bi-box-arrow-in-right me-2"></i>Войти
</button>
</form>
</div>
<div class="mt-3 text-center">
<small class="text-muted">
Или используйте команду <code>/login</code> в боте для получения кода
</small>
</div>
</div>
<!-- Вход по User ID (альтернативный способ) -->
<div class="tab-pane fade" id="admin-pane" role="tabpanel">
<form method="POST" action="/admin/login">
{% if csrf_token %}
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
{% endif %}
<input type="hidden" name="user_id" id="admin_user_id">
<div class="mb-3">
<label for="admin_user_id_input" class="form-label">Telegram User ID</label>
<input type="number" class="form-control" id="admin_user_id_input"
placeholder="Введите ваш Telegram User ID" required>
<small class="form-text text-muted">
Альтернативный способ входа (без OTP кода)
</small>
</div>
<button type="submit" class="btn btn-primary w-100">
<i class="bi bi-box-arrow-in-right me-2"></i>Войти
</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
function showAlert(message, type = 'success') {
const alertDiv = document.createElement('div');
alertDiv.className = `alert alert-${type} alert-dismissible fade show`;
alertDiv.innerHTML = `
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
`;
const cardBody = document.querySelector('.card-body');
cardBody.insertBefore(alertDiv, cardBody.firstChild);
setTimeout(() => alertDiv.remove(), 5000);
}
async function requestOTP() {
const identifier = document.getElementById('identifier').value.trim();
if (!identifier) {
showAlert('Введите User ID или username', 'danger');
return;
}
const btn = event.target;
btn.disabled = true;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Отправка...';
try {
const formData = new FormData();
formData.append('identifier', identifier);
const response = await fetch('/admin/api/otp/request', {
method: 'POST',
body: formData
});
const data = await response.json();
if (data.success) {
showAlert(data.message, 'success');
document.getElementById('otp-input-group').style.display = 'block';
document.getElementById('otp_code').focus();
// Если код возвращен в ответе (не удалось отправить в Telegram)
if (data.code) {
document.getElementById('otp_code').value = data.code;
showAlert(`Код не был отправлен в Telegram. Используйте код: ${data.code}`, 'warning');
}
} else {
showAlert(data.message, 'danger');
}
} catch (error) {
showAlert('Ошибка при запросе кода', 'danger');
} finally {
btn.disabled = false;
btn.innerHTML = '<i class="bi bi-send me-2"></i>Получить код';
}
}
// Обработка формы OTP
document.getElementById('otp-form').addEventListener('submit', function(e) {
const code = document.getElementById('otp_code').value.trim();
if (!code) {
e.preventDefault();
showAlert('Введите код', 'danger');
return;
}
document.getElementById('otp_code_hidden').value = code;
});
// Обработка формы админа
document.getElementById('admin_user_id_input').addEventListener('input', function(e) {
document.getElementById('admin_user_id').value = e.target.value;
});
// Enter для запроса OTP
document.getElementById('identifier').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
requestOTP();
}
});
</script>
</body>
</html>