/
Centermant
/
web-nodejs
Обзор
Документация
Войти
/
Centermant
/
web-nodejs
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
public/lab10/task2/app.js
969 строк
40 KB
Centermant
feat(lab11)
16 дек 2025, 00:57
16 дек 2025, 00:57
01b83c7
Код
Авторство
О чём код?
const API_BASE_URL = '/api/lab10/task2'; let groups = []; let subjects = []; let teachers = []; let people = []; let currentScheduleItems = []; let itemToDelete = null; let currentUser = null; let currentToken = null; // Функция для сохранения данных пользователя и токена function saveAuthData(token, user) { currentToken = token; currentUser = user; localStorage.setItem('authToken', token); localStorage.setItem('currentUser', JSON.stringify(user)); updateAuthUI(); } // Функция для загрузки данных пользователя и токена function loadAuthData() { const token = localStorage.getItem('authToken'); const user = localStorage.getItem('currentUser'); if (token && user) { currentToken = token; currentUser = JSON.parse(user); updateAuthUI(); // Проверяем токен на сервере checkAuthOnServer(); } else { updateAuthUI(); } } // Функция для очистки данных авторизации function clearAuthData() { currentToken = null; currentUser = null; localStorage.removeItem('authToken'); localStorage.removeItem('currentUser'); updateAuthUI(); } // Проверка авторизации на сервере async function checkAuthOnServer() { try { const response = await fetch(`${API_BASE_URL}/auth/check`, { headers: { 'Authorization': `Bearer ${currentToken}` } }); if (!response.ok) { clearAuthData(); return false; } const data = await response.json(); if (!data.isLoggedIn) { clearAuthData(); return false; } // Обновляем данные пользователя, если они изменились на сервере if (data.user && JSON.stringify(data.user) !== JSON.stringify(currentUser)) { currentUser = data.user; localStorage.setItem('currentUser', JSON.stringify(currentUser)); updateAuthUI(); } return true; } catch (error) { console.error('Auth check error:', error); clearAuthData(); return false; } } // Обновление UI в зависимости от состояния авторизации function updateAuthUI() { const authButtons = document.getElementById('auth-buttons'); const userInfo = document.getElementById('user-info'); const adminTab = document.getElementById('admin-tab'); if (currentUser) { if (authButtons) authButtons.style.display = 'none'; if (userInfo) userInfo.style.display = 'flex'; if (document.getElementById('user-name')) { document.getElementById('user-name').textContent = currentUser.username; } // Показываем админ-таб только для администраторов if (adminTab) { adminTab.style.display = currentUser.role === 'admin' ? 'block' : 'none'; } } else { if (authButtons) authButtons.style.display = 'flex'; if (userInfo) userInfo.style.display = 'none'; if (adminTab) adminTab.style.display = 'none'; } } async function apiRequest(endpoint, options = {}) { const headers = options.headers || {}; // Добавляем токен авторизации ко всем запросам, если пользователь авторизован if (currentToken) { headers['Authorization'] = `Bearer ${currentToken}`; } headers['Content-Type'] = 'application/json'; const response = await fetch(`${API_BASE_URL}${endpoint}`, { ...options, headers }); // Если токен не валиден или истек, очищаем данные авторизации if (response.status === 401) { clearAuthData(); throw new Error('Unauthorized'); } if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(errorData.error || `Ошибка запроса: ${response.status} ${response.statusText}`); } return response.json(); } async function apiGet(endpoint, params = {}) { try { const queryString = new URLSearchParams(params).toString(); return await apiRequest(`${endpoint}${queryString ? `?${queryString}` : ''}`); } catch (error) { console.error('API Error:', error); throw error; } } async function apiPost(endpoint, data) { try { return await apiRequest(endpoint, { method: 'POST', body: JSON.stringify(data) }); } catch (error) { console.error('API Error:', error); throw error; } } async function apiDelete(endpoint) { try { await apiRequest(endpoint, { method: 'DELETE' }); return true; } catch (error) { console.error('API Error:', error); throw error; } } // Функция для авторизации async function login(email, password) { try { const response = await fetch(`${API_BASE_URL}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }) }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Ошибка при входе'); } const data = await response.json(); saveAuthData(data.token, data.user); return true; } catch (error) { console.error('Login error:', error); throw error; } } // Функция для регистрации async function register(username, email, password) { try { const response = await fetch(`${API_BASE_URL}/auth/register`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, email, password }) }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Ошибка при регистрации'); } const data = await response.json(); saveAuthData(data.token, data.user); return true; } catch (error) { console.error('Register error:', error); throw error; } } // Функция для выхода из системы function logout() { clearAuthData(); } async function loadAllData() { try { const [allGroups, allSubjects, allTeachers, allPeople, allScheduleItems] = await Promise.all([ apiGet('/groups'), apiGet('/subjects'), apiGet('/teachers'), apiGet('/people'), apiGet('/all-schedule') ]); groups = allGroups; subjects = allSubjects; teachers = allTeachers; people = allPeople; currentScheduleItems = allScheduleItems; populateGroupsSelect(); populateFilterSelects(); populateAdminScheduleGroupSelect(); populateAdminSelects(); populatePeopleSelect(); populateSubjectsCheckboxes(); populateGroupsCheckboxes(); populateTeachersCheckboxes(); const groupId = document.getElementById('filter-group').value; const weekType = document.getElementById('filter-week').value; if (groupId) { await loadScheduleForGroup(groupId, weekType); } if (groups.length > 0) { document.getElementById('admin-schedule-group-select').value = groups[0].id; renderAdminSchedule(); } } catch (error) { console.error('Ошибка при загрузке данных:', error); alert('Ошибка при загрузке данных. Пожалуйста, попробуйте позже.'); } } function populateGroupsSelect() { const select = document.getElementById('filter-group'); select.innerHTML = '<option value="">Все группы</option>'; groups.forEach(group => { const option = document.createElement('option'); option.value = group.id; option.textContent = `${group.name} (${group.course} курс)`; select.appendChild(option); }); } function populateFilterSelects() { const daySelect = document.getElementById('filter-day'); daySelect.innerHTML = '<option value="">Все дни</option>'; const daysOfWeek = ["Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"]; daysOfWeek.forEach((day, index) => { const option = document.createElement('option'); option.value = index + 1; option.textContent = day; daySelect.appendChild(option); }); const subjectSelect = document.getElementById('filter-subject'); subjectSelect.innerHTML = '<option value="">Все дисциплины</option>'; subjects.forEach(subject => { const option = document.createElement('option'); option.value = subject.name; option.textContent = subject.name; subjectSelect.appendChild(option); }); } function populateAdminScheduleGroupSelect() { const select = document.getElementById('admin-schedule-group-select'); select.innerHTML = '<option value="">Выберите группу</option>'; groups.forEach(group => { const option = document.createElement('option'); option.value = group.id; option.textContent = `${group.name} (${group.course} курс)`; select.appendChild(option); }); } function populateAdminSelects() { const subjectSelect = document.getElementById('admin-subject-select'); subjectSelect.innerHTML = '<option value="">Выберите дисциплину</option>'; subjects.forEach(subject => { const option = document.createElement('option'); option.value = subject.id; option.textContent = subject.name; subjectSelect.appendChild(option); }); } function populatePeopleSelect() { const select = document.getElementById('admin-person-select'); select.innerHTML = '<option value="">Выберите человека</option>'; people.forEach(person => { const option = document.createElement('option'); option.value = person.id; option.textContent = person.name; select.appendChild(option); }); } function populateSubjectsCheckboxes() { const subjectsCheckboxes = document.getElementById('subjects-checkboxes'); subjectsCheckboxes.innerHTML = ''; if (subjects.length === 0) { subjectsCheckboxes.innerHTML = '<div class="text-center text-gray-500 py-4">Нет дисциплин</div>'; return; } subjects.forEach(subject => { const checkboxDiv = document.createElement('div'); checkboxDiv.className = 'checkbox-item'; checkboxDiv.innerHTML = ` <input type="checkbox" id="subject-${subject.id}" value="${subject.id}" class="subject-checkbox"> <label for="subject-${subject.id}">${subject.name}</label> `; subjectsCheckboxes.appendChild(checkboxDiv); }); document.querySelectorAll('.subject-checkbox').forEach(checkbox => { checkbox.addEventListener('change', updateSelectedSubjectsCount); }); updateSelectedSubjectsCount(); } function updateSelectedTeachersCount() { const selectedCount = document.querySelectorAll('.teacher-checkbox:checked').length; document.getElementById('selected-teachers-count').textContent = selectedCount; } function updateSelectedGroupsCount() { const selectedCount = document.querySelectorAll('.group-checkbox:checked').length; document.getElementById('selected-groups-count').textContent = selectedCount; } function updateSelectedSubjectsCount() { const selectedCount = document.querySelectorAll('.subject-checkbox:checked').length; document.getElementById('selected-subjects-count').textContent = selectedCount; } function populateGroupsCheckboxes() { const groupsCheckboxes = document.getElementById('groups-checkboxes'); groupsCheckboxes.innerHTML = ''; if (groups.length === 0) { groupsCheckboxes.innerHTML = '<div class="text-center text-gray-500 py-4">Нет групп</div>'; return; } groups.forEach(group => { const checkboxDiv = document.createElement('div'); checkboxDiv.className = 'checkbox-item'; checkboxDiv.innerHTML = ` <input type="checkbox" id="group-${group.id}" value="${group.id}" class="group-checkbox"> <label for="group-${group.id}">${group.name}</label> `; groupsCheckboxes.appendChild(checkboxDiv); }); document.querySelectorAll('.group-checkbox').forEach(checkbox => { checkbox.addEventListener('change', updateSelectedGroupsCount); }); updateSelectedGroupsCount(); } function populateTeachersCheckboxes() { const teachersCheckboxes = document.getElementById('teachers-checkboxes'); teachersCheckboxes.innerHTML = ''; if (teachers.length === 0) { teachersCheckboxes.innerHTML = '<div class="text-center text-gray-500 py-4">Нет преподавателей</div>'; return; } teachers.forEach(teacher => { const checkboxDiv = document.createElement('div'); checkboxDiv.className = 'checkbox-item'; checkboxDiv.innerHTML = ` <input type="checkbox" id="teacher-${teacher.id}" value="${teacher.id}" class="teacher-checkbox"> <label for="teacher-${teacher.id}">${teacher.name}</label> `; teachersCheckboxes.appendChild(checkboxDiv); }); document.querySelectorAll('.teacher-checkbox').forEach(checkbox => { checkbox.addEventListener('change', function() { updateSelectedTeachersCount(); }); }); updateSelectedTeachersCount(); } async function loadScheduleForGroup(groupId, weekType = null) { try { const schedule = await apiGet('/schedule', { groupId, weekType: weekType || null }); currentScheduleItems = schedule; applyFilters(); } catch (error) { console.error('Ошибка при загрузке расписания группы:', error); alert('Ошибка при загрузке расписания. Пожалуйста, попробуйте позже.'); } } function filterCurrentScheduleItems() { const weekType = document.getElementById('filter-week').value; const dayOfWeek = document.getElementById('filter-day').value; const subjectName = document.getElementById('filter-subject').value; const teacherName = document.getElementById('filter-teacher').value.toLowerCase().trim(); const roomNumber = document.getElementById('filter-room').value.toLowerCase().trim(); const lessonType = document.getElementById('filter-lesson-type').value; let filtered = [...currentScheduleItems]; if (weekType) { filtered = filtered.filter(item => item.week_type == weekType); } if (dayOfWeek) { filtered = filtered.filter(item => item.day_of_week == dayOfWeek); } if (subjectName) { filtered = filtered.filter(item => item.subject_name === subjectName); } if (teacherName) { filtered = filtered.filter(item => { if (!item.teacher_names) return false; const teacherList = item.teacher_names.toLowerCase().split(', '); return teacherList.some(teacher => teacher.includes(teacherName)); }); } if (roomNumber) { filtered = filtered.filter(item => item.room_number && item.room_number.toLowerCase().includes(roomNumber)); } if (lessonType) { filtered = filtered.filter(item => item.lesson_type === lessonType); } return filtered; } function renderSchedule(scheduleData) { const scheduleBody = document.getElementById('schedule-body'); scheduleBody.innerHTML = ''; const lessonTimes = [ "8:00 - 9:30", "9:45 - 11:15", "11:30 - 13:00", "13:50 - 15:20", "15:35 - 17:05", "17:20 - 18:50" ]; const daysOfWeek = ["Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"]; lessonTimes.forEach((time, index) => { const lessonNumber = index + 1; const row = document.createElement('tr'); const timeCell = document.createElement('td'); timeCell.className = 'time-cell'; timeCell.innerHTML = ` <div><strong>${lessonNumber} пара</strong></div> <div style="font-size: 0.9rem; color: #718096;">${time}</div> `; row.appendChild(timeCell); daysOfWeek.forEach((day, dayIndex) => { const dayOfWeek = dayIndex + 1; const cell = document.createElement('td'); cell.style.verticalAlign = 'top'; const lessons = scheduleData.filter(item => item.day_of_week === dayOfWeek && item.lesson_number === lessonNumber ); lessons.forEach(lesson => { const lessonDiv = document.createElement('div'); lessonDiv.className = `lesson-item ${getLessonClass(lesson.lesson_type)}`; const teachersList = lesson.teacher_names ? lesson.teacher_names.split(', ') : ['Не указан']; const teachersHTML = teachersList.map(teacher => `<div style="font-size: 0.9rem;">${teacher}</div>` ).join(''); lessonDiv.innerHTML = ` <button class="delete-btn" data-id="${lesson.id}" title="Удалить пару">×</button> <div style="font-weight: 500;">${lesson.subject_name}</div> ${teachersHTML} <div style="font-size: 0.8rem; color: #718096; margin-top: 0.25rem;"> ${lesson.room_number ? `${lesson.room_number}` : 'Аудитория не указана'} </div> <div style="font-size: 0.75rem; margin-top: 0.25rem;"> <span style=" padding: 0.125rem 0.5rem; border-radius: 9999px; background: linear-gradient(45deg, #e2e8f0, #cbd5e0); color: #4a5568; "> ${lesson.week_type ? (lesson.week_type === 1 ? 'Нечетная' : 'Четная') : 'Каждая'} </span> </div> `; cell.appendChild(lessonDiv); }); row.appendChild(cell); }); scheduleBody.appendChild(row); }); document.querySelectorAll('.delete-btn').forEach(button => { button.addEventListener('click', function(e) { e.stopPropagation(); itemToDelete = this.dataset.id; document.getElementById('delete-modal').classList.add('active'); }); }); } async function renderAdminSchedule() { const groupId = document.getElementById('admin-schedule-group-select').value; const weekType = document.getElementById('admin-schedule-week-select').value; if (!groupId) return; try { const schedule = await apiGet('/schedule', { groupId, weekType: weekType || null }); const scheduleBody = document.getElementById('admin-schedule-body'); scheduleBody.innerHTML = ''; const lessonTimes = [ "8:00 - 9:30", "9:45 - 11:15", "11:30 - 13:00", "13:50 - 15:20", "15:35 - 17:05", "17:20 - 18:50" ]; const daysOfWeek = ["Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"]; lessonTimes.forEach((time, index) => { const lessonNumber = index + 1; const row = document.createElement('tr'); const timeCell = document.createElement('td'); timeCell.className = 'time-cell'; timeCell.innerHTML = ` <div><strong>${lessonNumber} пара</strong></div> <div style="font-size: 0.9rem; color: #718096;">${time}</div> `; row.appendChild(timeCell); daysOfWeek.forEach((day, dayIndex) => { const dayOfWeek = dayIndex + 1; const cell = document.createElement('td'); cell.style.verticalAlign = 'top'; const lessons = schedule.filter(item => item.day_of_week === dayOfWeek && item.lesson_number === lessonNumber ); lessons.forEach(lesson => { const lessonDiv = document.createElement('div'); lessonDiv.className = `lesson-item ${getLessonClass(lesson.lesson_type)}`; const teachersList = lesson.teacher_names ? lesson.teacher_names.split(', ') : ['Не указан']; const teachersHTML = teachersList.map(teacher => `<div style="font-size: 0.9rem;">${teacher}</div>` ).join(''); lessonDiv.innerHTML = ` <button class="delete-btn" data-id="${lesson.id}" title="Удалить пару">×</button> <div style="font-weight: 500;">${lesson.subject_name}</div> ${teachersHTML} <div style="font-size: 0.8rem; color: #718096; margin-top: 0.25rem;"> ${lesson.room_number ? `${lesson.room_number}` : 'Аудитория не указана'} </div> <div style="font-size: 0.75rem; margin-top: 0.25rem;"> <span style=" padding: 0.125rem 0.5rem; border-radius: 9999px; background: linear-gradient(45deg, #e2e8f0, #cbd5e0); color: #4a5568; "> ${lesson.week_type ? (lesson.week_type === 1 ? 'Нечетная' : 'Четная') : 'Каждая'} </span> </div> `; cell.appendChild(lessonDiv); }); row.appendChild(cell); }); scheduleBody.appendChild(row); }); document.querySelectorAll('.delete-btn').forEach(button => { button.addEventListener('click', function(e) { e.stopPropagation(); itemToDelete = this.dataset.id; document.getElementById('delete-modal').classList.add('active'); }); }); } catch (error) { console.error('Ошибка при отрисовке расписания в админке:', error); alert('Ошибка при загрузке расписания. Пожалуйста, попробуйте позже.'); } } function getLessonClass(lessonType) { switch (lessonType) { case 'lecture': return 'lesson-lecture'; case 'practice': return 'lesson-practice'; case 'lab': return 'lesson-lab'; default: return ''; } } async function addScheduleItem() { if (!currentUser || currentUser.role !== 'admin') { alert('У вас нет прав для добавления занятий'); return; } const subjectId = document.getElementById('admin-subject-select').value; const roomNumber = document.getElementById('admin-classroom-input').value; const dayOfWeek = document.getElementById('admin-day-select').value; const weekType = document.getElementById('admin-week-type-select').value || null; const lessonNumber = document.getElementById('admin-lesson-number-select').value; const lessonType = document.getElementById('admin-lesson-type-select').value; const teacherIds = Array.from(document.querySelectorAll('.teacher-checkbox:checked')) .map(checkbox => checkbox.value); const groupIds = Array.from(document.querySelectorAll('.group-checkbox:checked')) .map(checkbox => checkbox.value); if (!subjectId || !dayOfWeek || !lessonNumber || !lessonType) { alert('Пожалуйста, заполните все обязательные поля'); return; } if (teacherIds.length === 0) { alert('Пожалуйста, выберите хотя бы одного преподавателя'); return; } if (groupIds.length === 0) { alert('Пожалуйста, выберите хотя бы одну группу'); return; } if (!roomNumber.trim()) { alert('Пожалуйста, укажите номер аудитории'); return; } try { for (const groupId of groupIds) { const newItem = { subjectId, teacherIds, lessonNumber: Number(lessonNumber), dayOfWeek: Number(dayOfWeek), weekType: weekType === "null" ? null : (weekType ? Number(weekType) : null), roomNumber: roomNumber.trim(), groupIds: [groupId], lessonType }; await apiPost('/schedule', newItem); } await loadAllData(); alert('Занятие(я) успешно добавлено(ы) в расписание!'); } catch (error) { console.error('Ошибка при добавлении занятия:', error); alert('Ошибка при добавлении занятия: ' + error.message); } } async function addPerson() { if (!currentUser || currentUser.role !== 'admin') { alert('У вас нет прав для добавления людей'); return; } const lastName = document.getElementById('admin-person-last-name').value.trim(); const firstName = document.getElementById('admin-person-first-name').value.trim(); const middleName = document.getElementById('admin-person-middle-name').value.trim(); const email = document.getElementById('admin-person-email').value.trim(); if (!lastName || !firstName || !middleName) { alert('Пожалуйста, заполните фамилию, имя и отчество'); return; } try { await apiPost('/people', { last_name: lastName, first_name: firstName, middle_name: middleName, email: email || null }); await loadAllData(); alert('Человек успешно добавлен!'); document.getElementById('admin-person-last-name').value = ''; document.getElementById('admin-person-first-name').value = ''; document.getElementById('admin-person-middle-name').value = ''; document.getElementById('admin-person-email').value = ''; } catch (error) { console.error('Ошибка при добавлении человека:', error); alert('Ошибка при добавлении человека: ' + error.message); } } async function addTeacher() { if (!currentUser || currentUser.role !== 'admin') { alert('У вас нет прав для добавления преподавателей'); return; } const personId = document.getElementById('admin-person-select').value; const subjectIds = Array.from(document.querySelectorAll('.subject-checkbox:checked')) .map(checkbox => checkbox.value); if (!personId) { alert('Пожалуйста, выберите человека'); return; } if (subjectIds.length === 0) { alert('Пожалуйста, выберите хотя бы одну дисциплину'); return; } try { await apiPost('/teachers', { personId, subjectIds }); await loadAllData(); alert('Преподаватель успешно добавлен!'); document.getElementById('admin-person-select').value = ''; document.querySelectorAll('.subject-checkbox').forEach(cb => cb.checked = false); updateSelectedSubjectsCount(); } catch (error) { console.error('Ошибка при добавлении преподавателя:', error); alert('Ошибка при добавлении преподавателя: ' + error.message); } } async function addGroup() { if (!currentUser || currentUser.role !== 'admin') { alert('У вас нет прав для добавления групп'); return; } const name = document.getElementById('admin-group-name').value.trim(); const course = document.getElementById('admin-group-course').value; if (!name) { alert('Пожалуйста, укажите название группы'); return; } if (!course) { alert('Пожалуйста, укажите курс'); return; } try { await apiPost('/groups', { name, course }); await loadAllData(); alert('Группа успешно добавлена!'); document.getElementById('admin-group-name').value = ''; document.getElementById('admin-group-course').value = '1'; } catch (error) { console.error('Ошибка при добавлении группы:', error); alert('Ошибка при добавлении группы: ' + error.message); } } async function addSubject() { if (!currentUser || currentUser.role !== 'admin') { alert('У вас нет прав для добавления дисциплин'); return; } const name = document.getElementById('admin-subject-name').value.trim(); if (!name) { alert('Пожалуйста, укажите название дисциплины'); return; } try { await apiPost('/subjects', { name }); await loadAllData(); alert('Дисциплина успешно добавлена!'); document.getElementById('admin-subject-name').value = ''; } catch (error) { console.error('Ошибка при добавлении дисциплины:', error); alert('Ошибка при добавлении дисциплины: ' + error.message); } } async function deleteScheduleItem() { if (!currentUser || currentUser.role !== 'admin') { alert('У вас нет прав для удаления занятий'); return; } if (!itemToDelete) return; try { await apiDelete(`/schedule/${itemToDelete}`); await loadAllData(); alert('Занятие успешно удалено из расписания!'); } catch (error) { console.error('Ошибка при удалении занятия:', error); alert('Ошибка при удалении занятия: ' + error.message); } finally { itemToDelete = null; document.getElementById('delete-modal').classList.remove('active'); } } function applyFilters() { const filtered = filterCurrentScheduleItems(); renderSchedule(filtered); } function resetFilters() { document.getElementById('filter-week').value = ''; document.getElementById('filter-day').value = ''; document.getElementById('filter-subject').value = ''; document.getElementById('filter-teacher').value = ''; document.getElementById('filter-room').value = ''; document.getElementById('filter-lesson-type').value = ''; renderSchedule(currentScheduleItems); } function switchAdminTab(tabId) { document.getElementById('admin-schedule-section').classList.add('hidden'); document.getElementById('admin-person-section').classList.add('hidden'); document.getElementById('admin-teacher-section').classList.add('hidden'); document.getElementById('admin-group-section').classList.add('hidden'); document.getElementById('admin-subject-section').classList.add('hidden'); document.getElementById('admin-schedule-tab').classList.remove('active'); document.getElementById('admin-person-tab').classList.remove('active'); document.getElementById('admin-teacher-tab').classList.remove('active'); document.getElementById('admin-group-tab').classList.remove('active'); document.getElementById('admin-subject-tab').classList.remove('active'); if (tabId === 'admin-schedule-tab') { document.getElementById('admin-schedule-section').classList.remove('hidden'); document.getElementById('admin-schedule-tab').classList.add('active'); } else if (tabId === 'admin-person-tab') { document.getElementById('admin-person-section').classList.remove('hidden'); document.getElementById('admin-person-tab').classList.add('active'); } else if (tabId === 'admin-teacher-tab') { document.getElementById('admin-teacher-section').classList.remove('hidden'); document.getElementById('admin-teacher-tab').classList.add('active'); } else if (tabId === 'admin-group-tab') { document.getElementById('admin-group-section').classList.remove('hidden'); document.getElementById('admin-group-tab').classList.add('active'); } else if (tabId === 'admin-subject-tab') { document.getElementById('admin-subject-section').classList.remove('hidden'); document.getElementById('admin-subject-tab').classList.add('active'); } } // Функция для показа модального окна входа function showLoginModal() { document.getElementById('login-modal').classList.add('active'); } // Функция для показа модального окна регистрации function showRegisterModal() { document.getElementById('register-modal').classList.add('active'); } // Функция для закрытия модальных окон function closeModal(modalId) { document.getElementById(modalId).classList.remove('active'); } document.addEventListener('DOMContentLoaded', () => { // Загружаем данные авторизации при запуске loadAuthData(); // Обработчики для кнопок авторизации document.getElementById('login-btn').addEventListener('click', showLoginModal); document.getElementById('register-btn').addEventListener('click', showRegisterModal); document.getElementById('logout-btn').addEventListener('click', logout); // Обработчики для модального окна входа document.getElementById('login-submit').addEventListener('click', async () => { const email = document.getElementById('login-email').value; const password = document.getElementById('login-password').value; try { await login(email, password); closeModal('login-modal'); await loadAllData(); } catch (error) { alert('Ошибка при входе: ' + error.message); } }); document.getElementById('login-cancel').addEventListener('click', () => closeModal('login-modal')); // Обработчики для модального окна регистрации document.getElementById('register-submit').addEventListener('click', async () => { const username = document.getElementById('register-username').value; const email = document.getElementById('register-email').value; const password = document.getElementById('register-password').value; const confirmPassword = document.getElementById('register-confirm-password').value; if (password !== confirmPassword) { alert('Пароли не совпадают'); return; } try { await register(username, email, password); closeModal('register-modal'); await loadAllData(); } catch (error) { alert('Ошибка при регистрации: ' + error.message); } }); document.getElementById('register-cancel').addEventListener('click', () => closeModal('register-modal')); // Обработчики для основных вкладок document.getElementById('schedule-tab').addEventListener('click', () => { document.getElementById('schedule-page').classList.add('active'); document.getElementById('admin-page').classList.remove('active'); document.getElementById('schedule-tab').classList.add('active'); document.getElementById('admin-tab').classList.remove('active'); if (groups.length === 0) { loadAllData(); } }); document.getElementById('admin-tab').addEventListener('click', () => { if (!currentUser || currentUser.role !== 'admin') { alert('Доступ к админ панели разрешен только администраторам'); return; } document.getElementById('admin-page').classList.add('active'); document.getElementById('schedule-page').classList.remove('active'); document.getElementById('admin-tab').classList.add('active'); document.getElementById('schedule-tab').classList.remove('active'); if (groups.length === 0) { loadAllData(); } }); // Обработчики для вкладок админки document.getElementById('admin-schedule-tab').addEventListener('click', () => switchAdminTab('admin-schedule-tab')); document.getElementById('admin-person-tab').addEventListener('click', () => switchAdminTab('admin-person-tab')); document.getElementById('admin-teacher-tab').addEventListener('click', () => switchAdminTab('admin-teacher-tab')); document.getElementById('admin-group-tab').addEventListener('click', () => switchAdminTab('admin-group-tab')); document.getElementById('admin-subject-tab').addEventListener('click', () => switchAdminTab('admin-subject-tab')); document.getElementById('admin-schedule-group-select').addEventListener('change', renderAdminSchedule); document.getElementById('admin-schedule-week-select').addEventListener('change', renderAdminSchedule); document.getElementById('add-schedule-item').addEventListener('click', addScheduleItem); document.getElementById('add-person').addEventListener('click', addPerson); document.getElementById('add-teacher').addEventListener('click', addTeacher); document.getElementById('add-group').addEventListener('click', addGroup); document.getElementById('add-subject').addEventListener('click', addSubject); document.getElementById('cancel-delete').addEventListener('click', () => { document.getElementById('delete-modal').classList.remove('active'); itemToDelete = null; }); document.getElementById('confirm-delete').addEventListener('click', deleteScheduleItem); document.getElementById('filter-group').addEventListener('change', async function() { const groupId = this.value; const weekType = document.getElementById('filter-week').value; if (groupId) { await loadScheduleForGroup(groupId, weekType); } else { currentScheduleItems = []; renderSchedule([]); } }); document.getElementById('filter-week').addEventListener('change', applyFilters); document.getElementById('filter-day').addEventListener('change', applyFilters); document.getElementById('filter-subject').addEventListener('change', applyFilters); document.getElementById('filter-teacher').addEventListener('input', applyFilters); document.getElementById('filter-room').addEventListener('input', applyFilters); document.getElementById('filter-lesson-type').addEventListener('change', applyFilters); document.getElementById('reset-filters').addEventListener('click', resetFilters); // Если пользователь уже авторизован, загружаем данные if (currentUser && groups.length === 0) { loadAllData(); } });