bitmine/templates/settings.html
2026-03-18 22:05:02 +03:00

356 lines
14 KiB
HTML
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.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Настройки — Bitmine</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: #f5f5f5;
padding: 20px;
}
.container { max-width: 800px; margin: 0 auto; }
h1 { color: #333; margin-bottom: 20px; }
.card {
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
padding: 24px;
margin-bottom: 20px;
}
.card h2 {
color: #333;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 2px solid #eee;
}
.form-group { margin-bottom: 20px; }
label {
display: block;
margin-bottom: 8px;
font-weight: 500;
color: #333;
}
input[type="text"],
input[type="password"],
input[type="number"] {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 14px;
}
input:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 0 3px rgba(0,123,255,0.1);
}
.help-text {
font-size: 12px;
color: #666;
margin-top: 4px;
}
.btn {
background: #007bff;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
}
.btn:hover { background: #0056b3; }
.btn-secondary { background: #6c757d; margin-left: 10px; }
.btn-secondary:hover { background: #545b62; }
.btn-test { background: #28a745; margin-left: 10px; }
.btn-test:hover { background: #218838; }
.btn-test:disabled { background: #ccc; cursor: not-allowed; }
.error {
background: #ffebee;
color: #c62828;
padding: 16px;
border-radius: 8px;
margin-bottom: 20px;
}
.success {
background: #e8f5e9;
color: #388e3c;
padding: 16px;
border-radius: 8px;
margin-bottom: 20px;
}
.back-link {
display: inline-block;
margin-bottom: 20px;
color: #007bff;
text-decoration: none;
}
.back-link:hover { text-decoration: underline; }
.security-note {
background: #fff3e0;
border-left: 4px solid #f57c00;
padding: 12px;
margin-top: 20px;
font-size: 13px;
color: #e65100;
}
.test-result {
margin-top: 12px;
padding: 12px;
border-radius: 6px;
display: none;
}
.test-result.success {
background: #e8f5e9;
color: #388e3c;
display: block;
}
.test-result.error {
background: #ffebee;
color: #c62828;
display: block;
}
.webhook-instructions {
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 6px;
padding: 16px;
margin-top: 12px;
font-size: 13px;
}
.webhook-instructions ol {
margin-left: 20px;
margin-top: 8px;
}
.webhook-instructions li {
margin-bottom: 8px;
}
.webhook-instructions code {
background: #e9ecef;
padding: 2px 6px;
border-radius: 4px;
font-family: monospace;
}
.saved-indicator {
display: inline-block;
margin-left: 8px;
padding: 4px 8px;
background: #e8f5e9;
color: #388e3c;
border-radius: 4px;
font-size: 12px;
}
</style>
</head>
<body>
<div class="container">
<a href="/" class="back-link">← Назад к списку задач</a>
<h1>⚙️ Настройки подключения</h1>
{% if error.is_some() %}
<div class="error">{{ error.as_ref().unwrap() }}</div>
{% endif %}
{% if success.is_some() %}
<div class="success">{{ success.as_ref().unwrap() }}</div>
{% endif %}
<!-- Redmine Settings -->
<div class="card">
<h2>
🔴 Redmine
{% if !redmine_url.is_empty() %}
<span class="saved-indicator">✓ Сохранено</span>
{% endif %}
</h2>
<form method="POST" action="/settings" id="redmine-form">
<!-- Скрытые поля для сохранения Bitrix настроек -->
<input type="hidden" name="bitrix_url" value="{{ bitrix_url }}">
<input type="hidden" name="bitrix_webhook" value="{{ bitrix_webhook }}">
<div class="form-group">
<label for="redmine_url">Redmine URL</label>
<input
type="text"
id="redmine_url"
name="redmine_url"
value="{{ redmine_url }}"
placeholder="https://redmine.company.com"
>
<div class="help-text">Полный URL вашего Redmine</div>
</div>
<div class="form-group">
<label for="redmine_api_key">API Key</label>
<input
type="password"
id="redmine_api_key"
name="redmine_api_key"
value=""
placeholder="Введите API ключ для сохранения"
>
<div class="help-text">Ключ можно получить в Настройки → Мой аккаунт → API access key</div>
{% if !redmine_url.is_empty() %}
<div class="help-text" style="color: #388e3c;">✓ API ключ уже сохранён в сессии</div>
{% endif %}
</div>
<div class="form-group">
<label for="redmine_user_id">User ID</label>
<input
type="number"
id="redmine_user_id"
name="redmine_user_id"
value="{{ redmine_user_id }}"
placeholder="7"
>
<div class="help-text">Ваш ID пользователя в Redmine (видно в профиле или URL)</div>
</div>
<button type="submit" class="btn">💾 Сохранить Redmine</button>
<button type="button" class="btn btn-test" onclick="testRedmineConnection()">🔍 Тест подключения</button>
<div id="redmine-test-result" class="test-result"></div>
</form>
</div>
<!-- Bitrix24 Settings -->
<div class="card">
<h2>
🔵 Bitrix24
{% if !bitrix_url.is_empty() %}
<span class="saved-indicator">✓ Сохранено</span>
{% endif %}
</h2>
<form method="POST" action="/settings" id="bitrix-form">
<!-- Скрытые поля для сохранения Redmine настроек -->
<input type="hidden" name="redmine_url" value="{{ redmine_url }}">
<input type="hidden" name="redmine_user_id" value="{{ redmine_user_id }}">
<div class="form-group">
<label for="bitrix_url">Bitrix24 URL</label>
<input
type="text"
id="bitrix_url"
name="bitrix_url"
value="{{ bitrix_url }}"
placeholder="https://corp.company.com"
>
<div class="help-text">URL вашего портала Bitrix24</div>
</div>
<div class="form-group">
<label for="bitrix_webhook">Входящий вебхук</label>
<input
type="text"
id="bitrix_webhook"
name="bitrix_webhook"
value="{{ bitrix_webhook }}"
placeholder="rest/105/abc123xyz/"
>
<div class="help-text">Код вебхука из раздела Разработчикам</div>
{% if !bitrix_url.is_empty() %}
<div class="help-text" style="color: #388e3c;">✓ Вебхук уже сохранён в сессии</div>
{% endif %}
</div>
<div class="webhook-instructions">
<strong>📋 Как получить входящий вебхук в Bitrix24:</strong>
<ol>
<li>Откройте ваш Bitrix24 портал</li>
<li>Перейдите в меню <code>Разработчикам</code> (внизу левого меню)</li>
<li>Выберите <code>Другое</code><code>Входящий вебхук</code></li>
<li>Выберите права доступа: <code>tasks</code>, <code>user</code>, <code>department</code></li>
<li>Нажмите <code>Создать вебхук</code></li>
<li>Скопируйте URL вида <code>https://your-portal.com/rest/105/CODE/</code></li>
<li>В поле выше вставьте только часть после домена: <code>rest/105/CODE/</code></li>
</ol>
</div>
<button type="submit" class="btn">💾 Сохранить Bitrix24</button>
<button type="button" class="btn btn-test" onclick="testBitrixConnection()">🔍 Тест подключения</button>
<div id="bitrix-test-result" class="test-result"></div>
</form>
</div>
<div class="security-note">
🔒 <strong>Безопасность:</strong> Ваши учётные данные хранятся только в сессии браузера и не сохраняются на сервере.
При закрытии браузера сессия истекает и данные удаляются.
</div>
</div>
<script>
async function testRedmineConnection() {
const resultDiv = document.getElementById('redmine-test-result');
const btn = event.target;
btn.disabled = true;
btn.textContent = '⏳ Проверка...';
resultDiv.className = 'test-result';
resultDiv.textContent = '';
try {
const response = await fetch('/api/test/redmine', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
});
const data = await response.json();
if (data.success) {
resultDiv.className = 'test-result success';
resultDiv.textContent = '✅ ' + data.message;
} else {
resultDiv.className = 'test-result error';
resultDiv.textContent = '❌ ' + data.message;
}
} catch (e) {
resultDiv.className = 'test-result error';
resultDiv.textContent = '❌ Ошибка: ' + e.message;
} finally {
btn.disabled = false;
btn.textContent = '🔍 Тест подключения';
}
}
async function testBitrixConnection() {
const resultDiv = document.getElementById('bitrix-test-result');
const btn = event.target;
btn.disabled = true;
btn.textContent = '⏳ Проверка...';
resultDiv.className = 'test-result';
resultDiv.textContent = '';
try {
const response = await fetch('/api/test/bitrix', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
});
const data = await response.json();
if (data.success) {
resultDiv.className = 'test-result success';
resultDiv.textContent = '✅ ' + data.message;
} else {
resultDiv.className = 'test-result error';
resultDiv.textContent = '❌ ' + data.message;
}
} catch (e) {
resultDiv.className = 'test-result error';
resultDiv.textContent = '❌ Ошибка: ' + e.message;
} finally {
btn.disabled = false;
btn.textContent = '🔍 Тест подключения';
}
}
</script>
</body>
</html>