- Implemented the initial version of the web interface. refactor: Begin Telegram bot refactoring - Started restructuring the bot’s code for better maintainability. chore: Migrate to Flask project structure - Reorganized the application to follow Flask's project structure. cleanup: Extensive code cleanup - Removed redundant code and improved readability. Signed-off-by: UdoChudo <stream@udochudo.ru>
401 lines
17 KiB
JavaScript
401 lines
17 KiB
JavaScript
// noinspection DuplicatedCode
|
||
|
||
let currentPage = 1;
|
||
let totalPages = 1;
|
||
let allUsers = []; // Добавляем массив для хранения всех пользователей
|
||
const perPage = 10;
|
||
|
||
// Инициализация Toastr
|
||
toastr.options = {
|
||
"closeButton": true,
|
||
"debug": false,
|
||
"newestOnTop": false,
|
||
"progressBar": false,
|
||
"positionClass": "toast-bottom-right",
|
||
"preventDuplicates": false,
|
||
"onclick": null,
|
||
"showDuration": "300",
|
||
"hideDuration": "1000",
|
||
"timeOut": "5000",
|
||
"extendedTimeOut": "1000",
|
||
"showEasing": "swing",
|
||
"hideEasing": "linear",
|
||
"showMethod": "fadeIn",
|
||
"hideMethod": "fadeOut"
|
||
};
|
||
|
||
// Функция загрузки пользователей
|
||
function loadUsers(page) {
|
||
if (page < 1 || page > totalPages) return;
|
||
currentPage = page;
|
||
|
||
fetch(`/telezab/rest/api/users?page=${currentPage}&per_page=${perPage}`)
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
totalPages = data.total_pages;
|
||
allUsers = data.users; // Сохраняем всех пользователей
|
||
updateUsersTable(data.users);
|
||
updatePagination(data.current_page, data.total_pages);
|
||
})
|
||
.catch(error => {
|
||
console.error('Error fetching users:', error);
|
||
toastr.error('Ошибка загрузки пользователей. Пожалуйста, попробуйте позже.');
|
||
});
|
||
}
|
||
|
||
// Функция обновления таблицы пользователей
|
||
function updateUsersTable(users) {
|
||
const tableBody = document.getElementById('users-table').querySelector('tbody');
|
||
tableBody.innerHTML = '';
|
||
|
||
users.forEach(user => {
|
||
const row = document.createElement('tr');
|
||
row.innerHTML = `
|
||
<td>${user.chat_id}</td>
|
||
<td>${user.telegram_id}</td>
|
||
<td>${user.email}</td>
|
||
<td>${user.subscriptions.join(', ') || 'Нет подписок'}</td>
|
||
<td>${user.disaster_only}</td>
|
||
<td>${user.status}</td>
|
||
<td><button class="btn btn-primary editUserBtn" data-id="${user.chat_id}">Редактировать</button></td>
|
||
`;
|
||
tableBody.appendChild(row);
|
||
});
|
||
|
||
setupEditButtons();
|
||
}
|
||
|
||
|
||
// Функция для обработки кнопок "Редактировать"
|
||
function setupEditButtons() {
|
||
document.querySelectorAll(".editUserBtn").forEach(button => {
|
||
button.addEventListener("click", function () {
|
||
const userId = this.dataset.id;
|
||
openUserModal(userId);
|
||
});
|
||
});
|
||
}
|
||
|
||
function openUserModal(userId) {
|
||
fetch(`/telezab/rest/api/users/${userId}`)
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
document.getElementById("userId").innerText = data.chat_id;
|
||
document.getElementById("telegram_id").innerText = data.telegram_id;
|
||
document.getElementById("userEmail").innerText = data.email;
|
||
|
||
const blockBtn = document.getElementById("toggleBlockUser");
|
||
blockBtn.innerText = data.blocked ? "Разблокировать" : "Заблокировать";
|
||
|
||
// Устанавливаем обработчик событий один раз
|
||
blockBtn.onclick = function () {
|
||
toggleUserBlock(userId, data.blocked); // Передаём текущий статус
|
||
};
|
||
|
||
document.getElementById("deleteUser").onclick = function () {
|
||
deleteUser(userId);
|
||
};
|
||
|
||
// Загрузка событий пользователя
|
||
loadUserEvents(data.chat_id);
|
||
|
||
// Использование Bootstrap для показа модального окна
|
||
var myModal = new bootstrap.Modal(document.getElementById('userModal'), {
|
||
keyboard: false
|
||
});
|
||
myModal.show(); // Открытие модального окна
|
||
})
|
||
.catch(error => {
|
||
console.error('Error fetching user data:', error);
|
||
toastr.error('Ошибка загрузки данных пользователя. Пожалуйста, попробуйте позже.');
|
||
});
|
||
}
|
||
|
||
// Функция форматирования времени
|
||
function formatDate(isoString) {
|
||
const date = new Date(isoString);
|
||
const year = date.getFullYear();
|
||
const month = String(date.getMonth() + 1).padStart(2, '0'); // Месяцы с 0, поэтому +1
|
||
const day = String(date.getDate()).padStart(2, '0');
|
||
const hours = String(date.getHours()).padStart(2, '0');
|
||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||
|
||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
}
|
||
|
||
// Функция загрузки событий пользователя
|
||
function loadUserEvents(chatId) {
|
||
fetch(`/telezab/rest/api/users/${chatId}/user_events`)
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
const tableBody = document.getElementById('userEventsTable').querySelector('tbody');
|
||
tableBody.innerHTML = '';
|
||
|
||
if (data && data.length > 0) { // Проверка массива данных
|
||
data.forEach(event => {
|
||
const row = document.createElement('tr');
|
||
row.innerHTML = `
|
||
<td>${event.event_type}</td>
|
||
<td>${formatDate(event.timestamp)}</td> <!-- Форматируем дату -->
|
||
`;
|
||
tableBody.appendChild(row);
|
||
});
|
||
} else {
|
||
tableBody.innerHTML = '<tr><td colspan="2">События не найдены</td></tr>';
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Error fetching user events:', error);
|
||
toastr.error('Ошибка загрузки событий пользователя. Пожалуйста, попробуйте позже.');
|
||
});
|
||
}
|
||
|
||
|
||
|
||
// Обработчик закрытия модального окна
|
||
document.querySelector(".btn-close").addEventListener("click", function () {
|
||
var myModal = new bootstrap.Modal(document.getElementById('userModal'));
|
||
myModal.hide(); // Закрытие модального окна
|
||
});
|
||
|
||
|
||
// Функция для блокировки/разблокировки пользователя
|
||
function toggleUserBlock(userId, isBlocked) {
|
||
fetch(`/telezab/rest/api/users/${userId}/block`, { method: "POST" })
|
||
.then(() => {
|
||
// Скрыть модальное окно с помощью Bootstrap
|
||
var myModal = bootstrap.Modal.getInstance(document.getElementById('userModal'));
|
||
if (myModal) {
|
||
myModal.hide(); // Закрытие модального окна
|
||
}
|
||
|
||
loadUsers(currentPage); // Перезагрузите список пользователей
|
||
// Отображение toast-уведомления об успешном действии
|
||
if (isBlocked) {
|
||
toastr.success('Пользователь разблокирован.');
|
||
} else {
|
||
toastr.success('Пользователь заблокирован.');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error("Ошибка при изменении статуса пользователя:", error);
|
||
toastr.error('Ошибка при изменении статуса пользователя. Пожалуйста, попробуйте позже.');
|
||
});
|
||
}
|
||
|
||
|
||
// Функция просмотра действий пользователя
|
||
function viewUserEvents(userId) {
|
||
window.location.href = `/telezab/rest/api/users/${userId}/events`;
|
||
}
|
||
|
||
// Функция для удаления пользователя
|
||
function deleteUser(userId) {
|
||
// Показываем модальное окно
|
||
$('#deleteConfirmationModal').modal('show');
|
||
|
||
// Обработчик кнопки подтверждения удаления
|
||
document.getElementById('confirmDeleteButton').onclick = function () {
|
||
const confirmationText = document.getElementById('confirmationText').value;
|
||
if (confirmationText === 'УДАЛИТЬ') {
|
||
fetch(`/telezab/rest/api/users/${userId}`, { method: "DELETE" })
|
||
.then(() => {
|
||
var myModal = bootstrap.Modal.getInstance(document.getElementById('userModal'));
|
||
if (myModal) {
|
||
myModal.hide();
|
||
}
|
||
loadUsers(currentPage);
|
||
toastr.success('Пользователь успешно удален.');
|
||
$('#deleteConfirmationModal').modal('hide'); // Скрываем модальное окно
|
||
})
|
||
.catch(error => {
|
||
console.error("Ошибка при удалении пользователя:", error);
|
||
toastr.error('Ошибка при удалении пользователя. Пожалуйста, попробуйте позже.');
|
||
$('#deleteConfirmationModal').modal('hide'); // Скрываем модальное окно
|
||
});
|
||
} else {
|
||
toastr.error('Неверное слово для подтверждения.');
|
||
}
|
||
};
|
||
}
|
||
|
||
function addNewUser() {
|
||
const newUserId = document.getElementById("newUserId");
|
||
const newUsername = document.getElementById("newUsername");
|
||
const newUserEmail = document.getElementById("newUserEmail");
|
||
|
||
if (!newUserId.checkValidity() || !newUsername.checkValidity() || !newUserEmail.checkValidity()) {
|
||
alert("Пожалуйста, заполните все поля корректно.");
|
||
return;
|
||
}
|
||
|
||
fetch(`/telezab/rest/api/users`, {
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/json"
|
||
},
|
||
body: JSON.stringify({
|
||
chat_id: newUserId.value,
|
||
telegram_id: newUsername.value,
|
||
user_email: newUserEmail.value
|
||
})
|
||
})
|
||
.then(response => {
|
||
if (!response.ok) {
|
||
return response.json().then(data => {
|
||
throw new Error(data.error || 'Ошибка при добавлении пользователя.');
|
||
});
|
||
}
|
||
return response.json();
|
||
})
|
||
.then(() => {
|
||
var myModal = bootstrap.Modal.getInstance(document.getElementById('addUserModal'));
|
||
if (myModal) {
|
||
myModal.hide();
|
||
}
|
||
loadUsers(currentPage);
|
||
toastr.success('Пользователь успешно добавлен.');
|
||
})
|
||
.catch(error => {
|
||
console.error("Ошибка при добавлении пользователя:", error);
|
||
toastr.error(error.message || 'Ошибка при добавлении пользователя. Пожалуйста, попробуйте позже.');
|
||
});
|
||
}
|
||
|
||
// Добавляем обработчик событий для кнопки "Добавить"
|
||
document.getElementById("addNewUser").addEventListener("click", addNewUser);
|
||
|
||
|
||
window.onclick = function (event) {
|
||
if (event.target === document.getElementById("userModal")) {
|
||
$('#userModal').modal('hide'); // Закрываем модальное окно с помощью Bootstrap
|
||
}
|
||
};
|
||
|
||
// Функция обновления пагинации
|
||
function updatePagination(currentPage, totalPages) {
|
||
const paginationContainer = document.getElementById('pagination');
|
||
paginationContainer.innerHTML = '';
|
||
|
||
const prevButton = document.createElement('li');
|
||
prevButton.classList.add('page-item');
|
||
prevButton.classList.toggle('disabled', currentPage === 1);
|
||
prevButton.innerHTML = `<a class="page-link" href="#" aria-label="Previous" onclick="loadUsers(${currentPage - 1})">«</a>`;
|
||
paginationContainer.appendChild(prevButton);
|
||
|
||
for (let page = 1; page <= totalPages; page++) {
|
||
const pageItem = document.createElement('li');
|
||
pageItem.classList.add('page-item');
|
||
pageItem.classList.toggle('active', page === currentPage);
|
||
|
||
const pageLink = document.createElement('a');
|
||
pageLink.classList.add('page-link');
|
||
pageLink.href = "#";
|
||
pageLink.textContent = page;
|
||
pageLink.onclick = () => loadUsers(page);
|
||
|
||
pageItem.appendChild(pageLink);
|
||
paginationContainer.appendChild(pageItem);
|
||
}
|
||
|
||
const nextButton = document.createElement('li');
|
||
nextButton.classList.add('page-item');
|
||
nextButton.classList.toggle('disabled', currentPage === totalPages);
|
||
nextButton.innerHTML = `<a class="page-link" href="#" aria-label="Next" onclick="loadUsers(${currentPage + 1})">»</a>`;
|
||
paginationContainer.appendChild(nextButton);
|
||
}
|
||
|
||
$(document).ready(function() {
|
||
// Обработчик событий для кнопки "Действия пользователя"
|
||
$(document).on('click', '.user-events-button', function() {
|
||
var chatId = $(this).data('chat-id');
|
||
console.log("Chat ID:", chatId); // Логирование chatId
|
||
|
||
if (!chatId) return;
|
||
|
||
// Отправка AJAX-запроса к API
|
||
$.ajax({
|
||
url: '/telezab/rest/api/' + chatId + '/user_events',
|
||
type: 'GET',
|
||
success: function(data) {
|
||
// Обработка успешного ответа
|
||
var eventsHtml = '';
|
||
if (data.events && data.events.length > 0) {
|
||
data.events.forEach(function(event) {
|
||
// Замените event.event_description и event.event_date на реальные поля из вашего ответа API
|
||
eventsHtml += '<p>' + event.action + ' - ' + event.timestamp + '</p>';
|
||
});
|
||
} else {
|
||
eventsHtml = '<p>Действия пользователя не найдены.</p>';
|
||
}
|
||
$('#userEventsModalBody').html(eventsHtml);
|
||
$('#userEventsModal').modal('show'); // Открытие модального окна
|
||
},
|
||
error: function() {
|
||
// Обработка ошибки
|
||
$('#userEventsModalBody').html('<p>Ошибка загрузки действий пользователя.</p>');
|
||
$('#userEventsModal').modal('show'); // Открытие модального окна
|
||
}
|
||
});
|
||
});
|
||
$(document).on('click', '.view-user', function() {
|
||
var userId = $(this).data('id');
|
||
$('#searchUsersModal').modal('hide'); // Скрываем модальное окно поиска
|
||
openUserModal(userId); // Открываем модальное окно карточки пользователя
|
||
});
|
||
});
|
||
|
||
$('#searchUsersButton').click(function() {
|
||
var telegramId = $('#searchTelegramId').val();
|
||
var email = $('#searchEmail').val();
|
||
|
||
$.ajax({
|
||
url: '/telezab/rest/api/users/search',
|
||
type: 'GET',
|
||
data: { telegram_id: telegramId, email: email },
|
||
success: function(users) {
|
||
var tableBody = $('#searchResultsTableModal tbody');
|
||
tableBody.empty();
|
||
|
||
if (users.length > 0) {
|
||
users.forEach(function(user) {
|
||
tableBody.append(
|
||
'<tr>' +
|
||
'<td>' + user.chat_id + '</td>' +
|
||
'<td>' + user.telegram_id + '</td>' +
|
||
'<td>' + user.email + '</td>' +
|
||
'<td><button class="btn btn-info view-user" data-id="' + user.chat_id + '">Карточка</button></td>' +
|
||
'</tr>'
|
||
);
|
||
});
|
||
$('#searchResults').show(); // Показываем блок с результатами поиска
|
||
} else {
|
||
$('#searchResults').hide(); // Скрываем блок, если нет результатов
|
||
toastr.info('Пользователи не найдены.');
|
||
}
|
||
},
|
||
error: function() {
|
||
toastr.error('Ошибка при выполнении поиска.');
|
||
}
|
||
});
|
||
|
||
});
|
||
|
||
const addUserModalEl = document.getElementById('addUserModal');
|
||
addUserModalEl.addEventListener('hidden.bs.modal', () => {
|
||
document.getElementById("newUserId").value = '';
|
||
document.getElementById("newUsername").value = '';
|
||
document.getElementById("newUserEmail").value = '';
|
||
});
|
||
|
||
// Очистка поля подтверждения удаления при закрытии модального окна удаления пользователя
|
||
const deleteModalEl = document.getElementById('deleteConfirmationModal');
|
||
deleteModalEl.addEventListener('hidden.bs.modal', () => {
|
||
document.getElementById('confirmationText').value = '';
|
||
});
|
||
|
||
// Запуск загрузки данных
|
||
document.addEventListener("DOMContentLoaded", () => {
|
||
loadUsers(currentPage);
|
||
}); |