575 lines
25 KiB
JavaScript
575 lines
25 KiB
JavaScript
let currentPage = 1;
|
||
let totalPages = 1;
|
||
const perPage = 10;
|
||
let sortField = 'region_id';
|
||
let sortOrder = 'asc';
|
||
let currentFetchController = null;
|
||
|
||
|
||
// Переменные для систем
|
||
let systemsCurrentPage = 1;
|
||
let systemsTotalPages = 1;
|
||
let systemsSortField = 'system_id';
|
||
let systemsSortOrder = 'asc';
|
||
|
||
|
||
// Инициализация 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 loadRegions(page) {
|
||
if (page < 1 || page > totalPages) return;
|
||
currentPage = page;
|
||
|
||
const url = `/telezab/rest/api/regions?page=${currentPage}&per_page=${perPage}&sort_field=${sortField}&sort_order=${sortOrder}`;
|
||
|
||
if (currentFetchController) {
|
||
currentFetchController.abort();
|
||
}
|
||
currentFetchController = new AbortController();
|
||
|
||
fetch(url, { signal: currentFetchController.signal })
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
currentFetchController = null;
|
||
totalPages = data.total_pages;
|
||
updateRegionsTable(data.regions);
|
||
updatePagination(data.current_page, data.total_pages);
|
||
})
|
||
.catch(error => {
|
||
if (error.name === 'AbortError') {
|
||
} else {
|
||
console.error('Error fetching regions:', error);
|
||
}
|
||
currentFetchController = null;
|
||
});
|
||
}
|
||
|
||
function updateRegionsTable(regions) {
|
||
const tableBody = document.getElementById('regions-table');
|
||
if (tableBody) {
|
||
tableBody.innerHTML = '';
|
||
|
||
regions.forEach(region => {
|
||
const row = document.createElement('tr');
|
||
row.innerHTML = `
|
||
<td>${region.region_id}</td>
|
||
<td>${region.name}</td>
|
||
<td>
|
||
<span id="region-status-label-${region.region_id}">${region.active ? 'Включен' : 'Выключен'}</span>
|
||
</td>
|
||
<td>
|
||
<div class="d-flex align-items-center">
|
||
<div class="form-check form-switch me-2">
|
||
<input class="form-check-input region-status-switch" type="checkbox" role="switch" id="region-status-${region.region_id}" data-id="${region.region_id}" ${region.active ? 'checked' : ''}>
|
||
<label class="form-check-label" for="region-status-${region.region_id}"></label>
|
||
</div>
|
||
<button class="btn btn-sm btn-primary edit-name-btn me-2" data-id="${region.region_id}" data-name="${region.name}"><i class="bi bi-pencil"></i></button>
|
||
<button class="btn btn-sm btn-info subscribers-btn me-2" data-id="${region.region_id}"><i class="bi bi-people"></i></button>
|
||
<button class="btn btn-sm btn-danger delete-btn" data-id="${region.region_id}"><i class="bi bi-trash"></i></button>
|
||
</div>
|
||
</td>
|
||
`;
|
||
tableBody.appendChild(row);
|
||
});
|
||
|
||
setupRegionActions();
|
||
} else {
|
||
console.error("regions-table element not found!");
|
||
}
|
||
}
|
||
|
||
function setupRegionActions() {
|
||
document.querySelectorAll('th[data-sort]').forEach(th => {
|
||
th.replaceWith(th.cloneNode(true)); // Удаляем все обработчики
|
||
});
|
||
|
||
document.querySelectorAll('.delete-btn').forEach(button => {
|
||
button.addEventListener('click', () => deleteRegion(button.dataset.id));
|
||
});
|
||
document.querySelectorAll('.region-status-switch').forEach(switchElement => {
|
||
switchElement.addEventListener('change', (event) => {
|
||
const regionId = event.target.dataset.id;
|
||
const active = event.target.checked;
|
||
toggleRegionStatus(regionId, active);
|
||
document.getElementById(`region-status-label-${regionId}`).textContent = active ? 'Включен' : 'Выключен';
|
||
});
|
||
});
|
||
document.querySelectorAll('.edit-name-btn').forEach(button => {
|
||
button.addEventListener('click', () => {
|
||
const regionId = button.dataset.id;
|
||
const regionName = button.dataset.name;
|
||
document.getElementById('old-region-name').value = regionName;
|
||
document.getElementById('new-region-name').value = regionName;
|
||
$('#editRegionNameModal').modal('show');
|
||
|
||
let timer = 5;
|
||
document.getElementById('edit-region-name-timer').textContent = timer;
|
||
const timerInterval = setInterval(() => {
|
||
timer--;
|
||
document.getElementById('edit-region-name-timer').textContent = timer;
|
||
if (timer === 0) {
|
||
clearInterval(timerInterval);
|
||
document.getElementById('save-region-name-btn').removeAttribute('disabled');
|
||
}
|
||
}, 1000);
|
||
|
||
document.getElementById('save-region-name-btn').addEventListener('click', () => {
|
||
const newName = document.getElementById('new-region-name').value;
|
||
updateRegionName(regionId, newName);
|
||
$('#editRegionNameModal').modal('hide');
|
||
}, { once: true }); // Удаляем обработчик после первого клика
|
||
});
|
||
});
|
||
|
||
document.querySelectorAll('.subscribers-btn').forEach(button => {
|
||
button.addEventListener('click', () => {
|
||
const regionId = button.dataset.id;
|
||
showRegionSubscribers(regionId);
|
||
});
|
||
});
|
||
|
||
function showRegionSubscribers(regionId) {
|
||
fetch(`/telezab/rest/api/regions/${regionId}/subscribers`)
|
||
.then(response => {
|
||
return response.json();
|
||
})
|
||
.then(data => {
|
||
|
||
|
||
const tableBody = document.getElementById('regionSubscribersTableBody');
|
||
tableBody.innerHTML = '';
|
||
|
||
if (data.subscribers && data.subscribers.length > 0) {
|
||
data.subscribers.forEach(user => {
|
||
const row = document.createElement('tr');
|
||
row.innerHTML = `
|
||
<td>${user.telegram_id}</td>
|
||
<td>${user.email}</td>
|
||
`;
|
||
tableBody.appendChild(row);
|
||
});
|
||
} else {
|
||
const row = document.createElement('tr');
|
||
row.innerHTML = `<td colspan="2">Нет подписчиков для этого региона.</td>`;
|
||
tableBody.appendChild(row);
|
||
}
|
||
|
||
$('#regionSubscribersModal').modal('show');
|
||
})
|
||
.catch(error => {
|
||
console.error('Ошибка при получении подписчиков региона:', error);
|
||
toastr.error('Ошибка при получении подписчиков региона. Пожалуйста, попробуйте позже.');
|
||
});
|
||
}
|
||
|
||
function updateRegionName(regionId, newName) {
|
||
fetch('/telezab/rest/api/regions', {
|
||
method: 'PUT',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ region_id: regionId, name: newName })
|
||
})
|
||
.then(() => {
|
||
loadRegions(currentPage);
|
||
toastr.success('Название региона изменено.');
|
||
})
|
||
.catch(error => {
|
||
console.error('Ошибка при изменении названия региона:', error);
|
||
toastr.error('Ошибка при изменении названия региона. Пожалуйста, попробуйте позже.');
|
||
});
|
||
}
|
||
|
||
document.querySelectorAll('th[data-sort]').forEach(th => {
|
||
th.addEventListener('click', () => {
|
||
const field = th.dataset.sort;
|
||
if (field === sortField) {
|
||
sortOrder = sortOrder === 'asc' ? 'desc' : 'asc';
|
||
} else {
|
||
sortField = field;
|
||
sortOrder = 'asc';
|
||
}
|
||
loadRegions(currentPage);
|
||
});
|
||
});
|
||
}
|
||
|
||
function toggleRegionStatus(regionId, active) {
|
||
fetch('/telezab/rest/api/regions', {
|
||
method: 'PUT',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ region_id: regionId, active: active })
|
||
})
|
||
.then(() => {
|
||
loadRegions(currentPage);
|
||
if (active) {
|
||
toastr.success('Регион активирован.');
|
||
} else {
|
||
toastr.success('Регион деактивирован.');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Ошибка при изменении статуса региона:', error);
|
||
toastr.error('Ошибка при изменении статуса региона. Пожалуйста, попробуйте позже.');
|
||
});
|
||
}
|
||
|
||
function deleteRegion(regionId) {
|
||
$('#deleteRegionModal').modal('show'); // Открываем модальное окно
|
||
|
||
$(document).ready(function() {
|
||
// Обработчик события input для текстового поля подтверждения
|
||
$('#deleteConfirmationInput').on('input', function() {
|
||
const inputValue = $(this).val();
|
||
if (inputValue === 'УДАЛИТЬ') {
|
||
$('#confirmDeleteButton').prop('disabled', false); // Активируем кнопку "Удалить"
|
||
} else {
|
||
$('#confirmDeleteButton').prop('disabled', true); // Деактивируем кнопку "Удалить"
|
||
}
|
||
});
|
||
|
||
// Обработчик события click для кнопки "Удалить"
|
||
$('#confirmDeleteButton').on('click', function() {
|
||
fetch(`/telezab/rest/api/regions?region_id=${regionId}`, { method: 'DELETE' })
|
||
.then(() => {
|
||
loadRegions(currentPage);
|
||
toastr.success('Регион успешно удален.');
|
||
$('#deleteRegionModal').modal('hide'); // Закрываем модальное окно
|
||
})
|
||
.catch(error => {
|
||
console.error('Ошибка при удалении региона:', error);
|
||
toastr.error('Ошибка при удалении региона. Пожалуйста, попробуйте позже.');
|
||
});
|
||
});
|
||
|
||
// Обработчик события hidden.bs.modal для модального окна
|
||
$('#deleteRegionModal').on('hidden.bs.modal', function() {
|
||
$('#deleteConfirmationInput').val(''); // Очищаем текстовое поле при закрытии модального окна
|
||
$('#confirmDeleteButton').prop('disabled', true); // Деактивируем кнопку "Удалить"
|
||
});
|
||
});
|
||
}
|
||
|
||
|
||
document.getElementById('add-region-form').addEventListener('submit', (event) => {
|
||
event.preventDefault();
|
||
const regionId = document.getElementById('region-id').value;
|
||
const regionName = document.getElementById('region-name').value;
|
||
const regionActive = document.getElementById('region-active').checked;
|
||
|
||
// Проверка, что все символы в regionId являются числами
|
||
if (!/^\d+$/.test(regionId)) {
|
||
toastr.error('ID региона должен содержать только числа.');
|
||
return; // Прерываем выполнение функции
|
||
}
|
||
|
||
fetch('/telezab/rest/api/regions', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ region_id: regionId, name: regionName, active: regionActive })
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
|
||
|
||
const responseData = data[0];
|
||
const statusCode = data[1];
|
||
|
||
if (statusCode === 409) {
|
||
toastr.error(responseData.message);
|
||
throw new Error(responseData.message);
|
||
} else if (statusCode === 201) {
|
||
document.getElementById('region-id').value = '';
|
||
document.getElementById('region-name').value = '';
|
||
document.getElementById('region-active').checked = true;
|
||
loadRegions(currentPage);
|
||
toastr.success('Регион успешно добавлен.');
|
||
$('#addRegionModal').modal('hide');
|
||
} else {
|
||
throw new Error('Неизвестный код состояния ответа');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Ошибка при добавлении региона:', error);
|
||
if (error.message !== 'Регион с таким ID уже существует') {
|
||
toastr.error('Ошибка при добавлении региона. Пожалуйста, попробуйте позже.');
|
||
}
|
||
});
|
||
});
|
||
|
||
// Функция обновления пагинации
|
||
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="loadRegions(${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 = () => loadRegions(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="loadRegions(${currentPage + 1})">»</a>`;
|
||
paginationContainer.appendChild(nextButton);
|
||
}
|
||
|
||
// Функция загрузки систем
|
||
function loadSystems(page) {
|
||
if (page < 1 || page > systemsTotalPages) return;
|
||
systemsCurrentPage = page;
|
||
|
||
const url = `/telezab/rest/api/systems?page=${systemsCurrentPage}&per_page=${perPage}&sort_field=${systemsSortField}&sort_order=${systemsSortOrder}`;
|
||
|
||
if (currentFetchController) {
|
||
currentFetchController.abort();
|
||
}
|
||
currentFetchController = new AbortController();
|
||
|
||
fetch(url, { signal: currentFetchController.signal })
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
currentFetchController = null;
|
||
systemsTotalPages = data.total_pages;
|
||
updateSystemsTable(data.systems);
|
||
updatePagination(data.current_page, data.total_pages);
|
||
})
|
||
.catch(error => {
|
||
if (error.name === 'AbortError') {
|
||
} else {
|
||
console.error('Error fetching systems:', error);
|
||
}
|
||
currentFetchController = null;
|
||
});
|
||
}
|
||
|
||
// Функция обновления таблицы систем
|
||
function updateSystemsTable(systems) {
|
||
const tableBody = document.getElementById('systems-table');
|
||
if (tableBody) {
|
||
tableBody.innerHTML = '';
|
||
|
||
systems.forEach(system => {
|
||
const row = document.createElement('tr');
|
||
row.innerHTML = `
|
||
<td>${system.system_id}</td>
|
||
<td>${system.system_name}</td>
|
||
<td>${system.name}</td>
|
||
<td>
|
||
<div class="d-flex align-items-center">
|
||
<button class="btn btn-sm btn-primary edit-name-btn me-2" data-id="${system.system_id}" data-name="${system.name}"><i class="bi bi-pencil"></i></button>
|
||
<button class="btn btn-sm btn-danger delete-btn" data-id="${system.system_id}"><i class="bi bi-trash"></i></button>
|
||
</div>
|
||
</td>
|
||
`;
|
||
tableBody.appendChild(row);
|
||
});
|
||
|
||
setupSystemActions();
|
||
} else {
|
||
console.error("systems-table element not found!");
|
||
}
|
||
}
|
||
|
||
// Функция настройки действий для систем
|
||
function setupSystemActions() {
|
||
document.querySelectorAll('th[data-sort]').forEach(th => {
|
||
th.replaceWith(th.cloneNode(true)); // Удаляем все обработчики
|
||
});
|
||
|
||
document.querySelectorAll('.delete-btn').forEach(button => {
|
||
button.addEventListener('click', () => deleteSystem(button.dataset.id));
|
||
});
|
||
|
||
document.querySelectorAll('.edit-name-btn').forEach(button => {
|
||
button.addEventListener('click', () => {
|
||
const systemId = button.dataset.id;
|
||
const systemName = button.dataset.name;
|
||
document.getElementById('old-system-name').value = systemName;
|
||
document.getElementById('new-system-name').value = systemName;
|
||
$('#editSystemNameModal').modal('show');
|
||
|
||
let timer = 5;
|
||
document.getElementById('edit-system-name-timer').textContent = timer;
|
||
const timerInterval = setInterval(() => {
|
||
timer--;
|
||
document.getElementById('edit-system-name-timer').textContent = timer;
|
||
if (timer === 0) {
|
||
clearInterval(timerInterval);
|
||
document.getElementById('saveSystemNameBtn').removeAttribute('disabled'); // Изменяем идентификатор
|
||
}
|
||
}, 1000);
|
||
|
||
document.getElementById('saveSystemNameBtn').addEventListener('click', () => { // Изменяем идентификатор
|
||
const newName = document.getElementById('new-system-name').value;
|
||
updateSystemName(systemId, newName);
|
||
$('#editSystemNameModal').modal('hide');
|
||
}, { once: true });
|
||
});
|
||
});
|
||
|
||
function updateSystemName(systemId, newName) {
|
||
fetch('/telezab/rest/api/systems', {
|
||
method: 'PUT',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ system_id: systemId, name: newName })
|
||
})
|
||
.then(() => {
|
||
loadSystems(systemsCurrentPage);
|
||
toastr.success('Название системы изменено.');
|
||
})
|
||
.catch(error => {
|
||
console.error('Ошибка при изменении названия системы:', error);
|
||
toastr.error('Ошибка при изменении названия системы. Пожалуйста, попробуйте позже.');
|
||
});
|
||
}
|
||
|
||
function deleteSystem(systemId) {
|
||
$('#deleteSystemModal').modal('show'); // Открываем модальное окно
|
||
|
||
$(document).ready(function() {
|
||
console.log(document.getElementById('deleteSystemConfirmationInput'));
|
||
// Обработчик события input для текстового поля подтверждения
|
||
$('#deleteSystemConfirmationInput').on('input', function() {
|
||
const inputValue = $(this).val();
|
||
console.log('inputValue:', inputValue); // Логируем значение inputValue
|
||
if (inputValue === 'УДАЛИТЬ') {
|
||
$('#confirmDeleteSystemButton').prop('disabled', false);
|
||
console.log('Кнопка активирована'); // Логируем активацию кнопки
|
||
} else {
|
||
$('#confirmDeleteSystemButton').prop('disabled', true);
|
||
console.log('Кнопка деактивирована'); // Логируем деактивацию кнопки
|
||
}
|
||
});
|
||
|
||
// Обработчик события click для кнопки "Удалить"
|
||
$('#confirmDeleteSystemButton').on('click', function() {
|
||
fetch(`/telezab/rest/api/systems?system_id=${systemId}`, { method: 'DELETE' })
|
||
.then(() => {
|
||
loadSystems(systemsCurrentPage);
|
||
toastr.success('Система успешно удалена.');
|
||
$('#deleteSystemModal').modal('hide'); // Закрываем модальное окно
|
||
})
|
||
.catch(error => {
|
||
console.error('Ошибка при удалении системы:', error);
|
||
toastr.error('Ошибка при удалении системы. Пожалуйста, попробуйте позже.');
|
||
});
|
||
});
|
||
|
||
// Обработчик события hidden.bs.modal для модального окна
|
||
$('#deleteSystemModal').on('hidden.bs.modal', function() {
|
||
$('#deleteSystemConfirmationInput').val(''); // Очищаем текстовое поле при закрытии модального окна
|
||
$('#confirmDeleteSystemButton').prop('disabled', true); // Деактивируем кнопку "Удалить"
|
||
});
|
||
});
|
||
}
|
||
|
||
document.querySelectorAll('th[data-sort]').forEach(th => {
|
||
th.addEventListener('click', () => {
|
||
const field = th.dataset.sort;
|
||
if (field === systemsSortField) {
|
||
systemsSortOrder = systemsSortOrder === 'asc' ? 'desc' : 'asc';
|
||
} else {
|
||
systemsSortField = field;
|
||
systemsSortOrder = 'asc';
|
||
}
|
||
loadSystems(systemsCurrentPage);
|
||
});
|
||
});
|
||
}
|
||
|
||
// Функция добавления системы
|
||
document.getElementById('add-system-form').addEventListener('submit', (event) => {
|
||
event.preventDefault();
|
||
const systemId = document.getElementById('system-id').value;
|
||
const systemNameLat = document.getElementById('system-name-lat').value;
|
||
const systemNameCyr = document.getElementById('system-name-cyr').value;
|
||
|
||
if (!/^\d+$/.test(systemId)) {
|
||
toastr.error('ID системы должен содержать только числа.');
|
||
return;
|
||
}
|
||
|
||
fetch('/telezab/rest/api/systems', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ system_id: systemId, system_name: systemNameLat, name: systemNameCyr })
|
||
})
|
||
.then(response => {
|
||
if (!response.ok) {
|
||
// Если статус ответа не OK, обрабатываем ошибку
|
||
return response.json().then(errorData => {
|
||
throw new Error(errorData.message || 'Ошибка добавления системы');
|
||
});
|
||
}
|
||
return response.json();
|
||
})
|
||
.then(data => {
|
||
// Обрабатываем успешное добавление системы
|
||
document.getElementById('system-id').value = '';
|
||
document.getElementById('system-name-lat').value = '';
|
||
document.getElementById('system-name-cyr').value = '';
|
||
loadSystems(systemsCurrentPage); // Обновляем таблицу систем
|
||
toastr.success('Система успешно добавлена.');
|
||
$('#addSystemModal').modal('hide');
|
||
})
|
||
.catch(error => {
|
||
// Обрабатываем ошибки
|
||
console.error('Ошибка при добавлении системы:', error);
|
||
toastr.error(error.message || 'Ошибка при добавлении системы. Пожалуйста, попробуйте позже.');
|
||
});
|
||
});
|
||
|
||
|
||
|
||
// Запуск загрузки данных
|
||
document.addEventListener("DOMContentLoaded", () => {
|
||
const regionsTab = document.getElementById('regions-tab');
|
||
const systemsTab = document.getElementById('systems-tab');
|
||
|
||
// Обработчик для вкладки "Регионы"
|
||
regionsTab.addEventListener('shown.bs.tab', () => {
|
||
loadRegions(currentPage);
|
||
});
|
||
|
||
// Обработчик для вкладки "Системы"
|
||
systemsTab.addEventListener('shown.bs.tab', () => {
|
||
loadSystems(systemsCurrentPage);
|
||
});
|
||
|
||
// Инициализация загрузки данных для активной вкладки
|
||
if (regionsTab.classList.contains('active')) {
|
||
loadRegions(currentPage);
|
||
}
|
||
}); |