import { api } from '../api.js';
import { escapeHtml, showAlert, hideAlert, initMultiSelect, updateSelectText } from '../utils.js';
async function fetchEquipments() {
try {
return await api.get('/api/equipments');
} catch (e) {
console.error("Failed to fetch equipments", e);
return [];
}
}
function renderEquipmentCheckboxes(equipments, containerId, selectTextId, selectedIds = []) {
const container = document.getElementById(containerId);
if (!container) return;
if (!equipments || !equipments.length) {
container.innerHTML = '
Оборудование отсутствует
';
updateSelectText(containerId, selectTextId);
return;
}
container.innerHTML = equipments.map(eq => `
`).join('');
updateSelectText(containerId, selectTextId);
}
export async function initClassrooms() {
const classroomsTbody = document.getElementById('classrooms-tbody');
const createClassroomForm = document.getElementById('create-classroom-form');
const equipmentCheckboxes = document.getElementById('equipment-checkboxes');
const editEquipmentCheckboxes = document.getElementById('edit-equipment-checkboxes');
const modalEditClassroom = document.getElementById('modal-edit-classroom');
const modalEditClassroomClose = document.getElementById('modal-edit-classroom-close');
const editClassroomForm = document.getElementById('edit-classroom-form');
let allEquipments = [];
let editingClassroomData = null;
initMultiSelect('equipment-select-box', 'equipment-dropdown-menu', 'equipment-select-text', 'equipment-checkboxes');
initMultiSelect('edit-equipment-select-box', 'edit-equipment-dropdown-menu', 'edit-equipment-select-text', 'edit-equipment-checkboxes');
async function loadInitialData() {
try {
allEquipments = await fetchEquipments();
renderEquipmentCheckboxes(allEquipments, 'equipment-checkboxes', 'equipment-select-text');
await loadClassrooms();
} catch (e) {
classroomsTbody.innerHTML = '| Ошибка загрузки данных |
';
}
}
async function loadClassrooms() {
try {
const classrooms = await api.get('/api/classrooms?includeArchived=true');
renderClassrooms(classrooms);
} catch (e) {
classroomsTbody.innerHTML = '| Ошибка загрузки |
';
}
}
function renderClassrooms(classrooms) {
if (!classrooms || !classrooms.length) {
classroomsTbody.innerHTML = '| Нет аудиторий |
';
return;
}
classroomsTbody.innerHTML = classrooms.map(c => {
const equipHtml = c.equipments && c.equipments.length
? c.equipments.map(eq => escapeHtml(eq.name)).join(', ')
: '—';
return `
| ${c.id} |
${escapeHtml(c.name)} |
${c.capacity} чел. |
${equipHtml} |
${c.status === 'ARCHIVED' ? 'Архив' : (c.isAvailable ? 'Доступна' : 'Не доступна')}
|
${c.status === 'ARCHIVED'
? ``
: ``}
|
`;
}).join('');
}
createClassroomForm.addEventListener('submit', async (e) => {
e.preventDefault();
hideAlert('create-classroom-alert');
const name = document.getElementById('new-classroom-name').value.trim();
const capacity = parseInt(document.getElementById('new-classroom-capacity').value, 10);
const checkedBoxes = Array.from(equipmentCheckboxes.querySelectorAll('input:checked'));
const equipmentIds = checkedBoxes.map(chk => parseInt(chk.value, 10));
if (!name || isNaN(capacity)) { showAlert('create-classroom-alert', 'Заполните обязательные поля', 'error'); return; }
try {
const data = await api.post('/api/classrooms', { name, capacity, equipmentIds, isAvailable: true });
showAlert('create-classroom-alert', `Аудитория "${escapeHtml(data.name)}" добавлена`, 'success');
createClassroomForm.reset();
updateSelectText('equipment-checkboxes', 'equipment-select-text');
loadClassrooms();
} catch (e) {
showAlert('create-classroom-alert', e.message || 'Ошибка создания', 'error');
}
});
classroomsTbody.addEventListener('click', async (e) => {
const btnDelete = e.target.closest('.btn-archive-classroom');
const btnToggleStatus = e.target.closest('.btn-icon-toggle');
const btnEdit = e.target.closest('.classroom-edit-action');
if (btnDelete) {
if (!confirm('Вывести аудиторию из эксплуатации? Историческое расписание сохранится.')) return;
try {
await api.delete('/api/classrooms/' + btnDelete.dataset.id);
loadClassrooms();
} catch (err) { alert('Ошибка архивирования'); }
}
const btnRestore = e.target.closest('.btn-restore-classroom');
if (btnRestore) {
try {
await api.post('/api/classrooms/' + btnRestore.dataset.id + '/restore', {});
loadClassrooms();
} catch (err) { alert('Ошибка восстановления аудитории'); }
}
if (btnToggleStatus) {
const id = btnToggleStatus.dataset.id;
const currentStatus = btnToggleStatus.dataset.currentStatus === 'true';
try {
await api.put('/api/classrooms/' + id, { isAvailable: !currentStatus });
loadClassrooms();
} catch (err) { alert('Ошибка изменения статуса'); }
}
if (btnEdit) {
openEditClassroomModal(btnEdit.dataset.id);
}
});
async function openEditClassroomModal(id) {
try {
// Can optimize by using already loaded classrooms, but fetch is safer to get fresh data
const classrooms = await api.get('/api/classrooms?includeArchived=true');
editingClassroomData = classrooms.find(c => c.id == id);
if (!editingClassroomData) return;
document.getElementById('edit-classroom-id').value = editingClassroomData.id;
document.getElementById('edit-classroom-name').value = editingClassroomData.name;
document.getElementById('edit-classroom-capacity').value = editingClassroomData.capacity;
const existingEquipIds = editingClassroomData.equipments.map(e => e.id);
renderEquipmentCheckboxes(allEquipments, 'edit-equipment-checkboxes', 'edit-equipment-select-text', existingEquipIds);
hideAlert('edit-classroom-alert');
modalEditClassroom.classList.add('open');
} catch (e) {
alert('Ошибка загрузки данных аудитории');
}
}
modalEditClassroomClose.addEventListener('click', () => {
modalEditClassroom.classList.remove('open');
});
modalEditClassroom.addEventListener('click', (e) => {
if (e.target === modalEditClassroom) {
modalEditClassroom.classList.remove('open');
}
});
editClassroomForm.addEventListener('submit', async (e) => {
e.preventDefault();
hideAlert('edit-classroom-alert');
const id = document.getElementById('edit-classroom-id').value;
const name = document.getElementById('edit-classroom-name').value.trim();
const capacity = parseInt(document.getElementById('edit-classroom-capacity').value, 10);
const checkedBoxes = Array.from(editEquipmentCheckboxes.querySelectorAll('input:checked'));
const equipmentIds = checkedBoxes.map(chk => parseInt(chk.value, 10));
if (!name || isNaN(capacity)) { showAlert('edit-classroom-alert', 'Заполните обязательные поля', 'error'); return; }
try {
const data = await api.put('/api/classrooms/' + id, {
name,
capacity,
equipmentIds,
isAvailable: editingClassroomData.isAvailable
});
modalEditClassroom.classList.remove('open');
// We show alert on the main create form area or we could use toast
showAlert('create-classroom-alert', `Аудитория "${escapeHtml(data.name)}" обновлена`, 'success');
loadClassrooms();
} catch (e) {
showAlert('edit-classroom-alert', e.message || 'Ошибка обновления', 'error');
}
});
// Элементы модалки оборудования
const btnManageEquipments = document.getElementById('btn-manage-equipments');
const modalManageEquipments = document.getElementById('modal-manage-equipments');
const modalManageEquipmentsClose = document.getElementById('modal-manage-equipments-close');
const manageEquipmentForm = document.getElementById('manage-equipment-form');
const manageEquipmentNameInput = document.getElementById('manage-equipment-name');
const manageEquipmentTbody = document.getElementById('manage-equipments-tbody');
btnManageEquipments.addEventListener('click', openManageEquipmentsModal);
modalManageEquipmentsClose.addEventListener('click', () => modalManageEquipments.classList.remove('open'));
modalManageEquipments.addEventListener('click', (e) => {
if (e.target === modalManageEquipments) modalManageEquipments.classList.remove('open');
});
async function openManageEquipmentsModal() {
hideAlert('manage-equipment-alert');
manageEquipmentForm.reset();
modalManageEquipments.classList.add('open');
await loadManageEquipments();
}
async function loadManageEquipments() {
manageEquipmentTbody.innerHTML = '| Загрузка... |
';
try {
allEquipments = await fetchEquipments();
renderManageEquipmentsTable();
// Обновим чекбоксы на основной странице
renderEquipmentCheckboxes(allEquipments, 'equipment-checkboxes', 'equipment-select-text');
} catch (e) {
manageEquipmentTbody.innerHTML = '| Ошибка загрузки |
';
}
}
function renderManageEquipmentsTable() {
if (!allEquipments || !allEquipments.length) {
manageEquipmentTbody.innerHTML = '| Нет оборудования |
';
return;
}
manageEquipmentTbody.innerHTML = allEquipments.map(eq => `
| ${eq.id} |
${escapeHtml(eq.name)} |
|
`).join('');
}
manageEquipmentForm.addEventListener('submit', async (e) => {
e.preventDefault();
hideAlert('manage-equipment-alert');
const name = manageEquipmentNameInput.value.trim();
if (!name) {
showAlert('manage-equipment-alert', 'Введите название', 'error');
return;
}
try {
const data = await api.post('/api/equipments', { name });
showAlert('manage-equipment-alert', `Оборудование "${escapeHtml(data.name)}" добавлено`, 'success');
manageEquipmentForm.reset();
await loadManageEquipments();
} catch (err) {
showAlert('manage-equipment-alert', err.message || 'Ошибка добавления', 'error');
}
});
manageEquipmentTbody.addEventListener('click', async (e) => {
const btnDelete = e.target.closest('.btn-delete-equipment');
if (!btnDelete) return;
if (!confirm('Удалить оборудование из каталога?')) return;
try {
await api.delete('/api/equipments/' + btnDelete.dataset.id);
await loadManageEquipments();
} catch (err) {
alert(err.message || 'Ошибка удаления');
}
});
loadInitialData();
}