import { api } from '../api.js'; import { escapeHtml, showAlert, hideAlert, initMultiSelect, updateSelectText } from '../utils.js'; import { fetchEquipments, renderEquipmentCheckboxes } from './equipments.js'; 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'); 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.isAvailable ? 'Доступна' : 'Не доступна'}
`; }).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-delete'); const btnToggleStatus = e.target.closest('.btn-icon-toggle'); const btnEdit = e.target.closest('.btn-edit-classroom'); if (btnDelete) { if (!confirm('Удалить аудиторию?')) return; try { await api.delete('/api/classrooms/' + btnDelete.dataset.id); 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'); 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'); } }); loadInitialData(); }