// public/main.js – страница записи родителей с авторизацией для сотрудников
let allLessons = [];
let currentUser = null;
// ---------- Авторизация на главной странице ----------
async function checkAuthAndRender() {
try {
const res = await fetch('/api/me');
const data = await res.json();
if (data.authenticated) {
currentUser = data.user;
renderAuthButtons(true);
} else {
currentUser = null;
renderAuthButtons(false);
}
} catch (err) {
console.error('Ошибка проверки авторизации', err);
renderAuthButtons(false);
}
}
function renderAuthButtons(isLoggedIn) {
const container = document.getElementById('authContainer');
if (!container) return;
if (!isLoggedIn) {
container.innerHTML = '';
const btn = document.getElementById('employeeBtn');
if (btn) btn.addEventListener('click', showAuthModal);
} else {
const role = currentUser.role;
let links = '';
if (role === 'admin') {
links = '📋 Админка | 📊 Список записей';
} else if (role === 'user') {
links = '📊 Список записей';
} else {
links = 'Доступ не определён';
}
container.innerHTML = `
${links}
`;
const logoutBtn = document.getElementById('logoutBtnHeader');
if (logoutBtn) logoutBtn.addEventListener('click', logout);
}
}
async function logout() {
try {
await fetch('/api/logout', { method: 'POST' });
currentUser = null;
renderAuthButtons(false);
// Обновляем список уроков (чтобы сбросить возможные фильтры, связанные с сессией)
await loadFilterOptions();
await loadLessons();
} catch (err) {
console.error('Ошибка выхода', err);
}
}
function showAuthModal() {
let modal = document.getElementById('authModal');
// Если модального окна нет в DOM – создаём динамически
if (!modal) {
modal = document.createElement('div');
modal.id = 'authModal';
modal.className = 'modal';
modal.innerHTML = `
`;
document.body.appendChild(modal);
}
const form = document.getElementById('authForm');
const errorDiv = document.getElementById('authError');
const closeSpan = modal.querySelector('.close');
if (errorDiv) errorDiv.innerText = '';
if (form) form.reset();
modal.style.display = 'flex';
if (closeSpan) closeSpan.onclick = () => modal.style.display = 'none';
window.onclick = (e) => { if (e.target === modal) modal.style.display = 'none'; };
const authForm = document.getElementById('authForm');
if (authForm) {
authForm.onsubmit = async (e) => {
e.preventDefault();
const username = document.getElementById('authUsername').value.trim();
const password = document.getElementById('authPassword').value;
if (!username || !password) {
if (errorDiv) errorDiv.innerText = 'Заполните логин и пароль';
return;
}
try {
const res = await fetch('/api/auth', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password })
});
const data = await res.json();
if (res.ok && data.success) {
modal.style.display = 'none';
await checkAuthAndRender();
await loadFilterOptions();
await loadLessons();
} else {
if (errorDiv) errorDiv.innerText = data.message || 'Ошибка входа';
}
} catch (err) {
if (errorDiv) errorDiv.innerText = 'Ошибка соединения';
}
};
}
}
// ---------- Остальная логика (фильтры, уроки, запись) ----------
async function loadFilterOptions() {
try {
const [classes, teachers, topics] = await Promise.all([
fetch('/api/filter-options/class-names').then(r => r.json()),
fetch('/api/filter-options/teachers').then(r => r.json()),
fetch('/api/filter-options/topics').then(r => r.json())
]);
window.allClassNames = classes;
window.allTeachers = teachers;
window.allTopics = topics;
populateSelect('filterClass', window.allClassNames, 'Все классы');
populateSelect('filterTeacher', window.allTeachers, 'Все учителя');
populateSelect('filterTopic', window.allTopics, 'Все темы');
} catch (err) {
console.error('Ошибка загрузки опций фильтров', err);
}
}
function populateSelect(selectId, options, defaultLabel) {
const select = document.getElementById(selectId);
if (!select) return;
const currentValue = select.value;
select.innerHTML = ``;
options.forEach(opt => {
const option = document.createElement('option');
option.value = opt;
option.textContent = opt;
select.appendChild(option);
});
if (currentValue && options.includes(currentValue)) {
select.value = currentValue;
} else {
select.value = '';
}
}
async function loadLessons() {
try {
const res = await fetch('/api/lessons');
allLessons = await res.json();
updateDependentFilters();
applyFilters();
} catch (err) {
console.error('Ошибка загрузки уроков', err);
document.getElementById('lessonsContainer').innerHTML = 'Ошибка загрузки данных
';
}
}
function updateDependentFilters() {
const selectedClass = document.getElementById('filterClass').value;
const selectedTeacher = document.getElementById('filterTeacher').value;
const selectedTopic = document.getElementById('filterTopic').value;
let filteredLessons = allLessons;
if (selectedClass) {
filteredLessons = filteredLessons.filter(l => l.class_name === selectedClass);
}
if (selectedTeacher) {
filteredLessons = filteredLessons.filter(l => l.teacher === selectedTeacher);
}
if (selectedTopic) {
filteredLessons = filteredLessons.filter(l => l.topic === selectedTopic);
}
const availableClasses = [...new Set(filteredLessons.map(l => l.class_name))].sort();
const availableTeachers = [...new Set(filteredLessons.map(l => l.teacher))].sort();
const availableTopics = [...new Set(filteredLessons.map(l => l.topic).filter(t => t))].sort();
const classSelect = document.getElementById('filterClass');
const teacherSelect = document.getElementById('filterTeacher');
const topicSelect = document.getElementById('filterTopic');
const oldClass = classSelect.value;
const oldTeacher = teacherSelect.value;
const oldTopic = topicSelect.value;
populateSelect('filterClass', availableClasses, 'Все классы');
populateSelect('filterTeacher', availableTeachers, 'Все учителя');
populateSelect('filterTopic', availableTopics, 'Все темы');
if (oldClass && availableClasses.includes(oldClass)) classSelect.value = oldClass;
else classSelect.value = '';
if (oldTeacher && availableTeachers.includes(oldTeacher)) teacherSelect.value = oldTeacher;
else teacherSelect.value = '';
if (oldTopic && availableTopics.includes(oldTopic)) topicSelect.value = oldTopic;
else topicSelect.value = '';
}
function applyFilters() {
const classFilter = document.getElementById('filterClass').value;
const teacherFilter = document.getElementById('filterTeacher').value;
const topicFilter = document.getElementById('filterTopic').value;
let filtered = allLessons.filter(lesson => lesson.available === true);
if (classFilter) filtered = filtered.filter(lesson => lesson.class_name === classFilter);
if (teacherFilter) filtered = filtered.filter(lesson => lesson.teacher === teacherFilter);
if (topicFilter) filtered = filtered.filter(lesson => lesson.topic === topicFilter);
renderLessons(filtered);
}
function renderLessons(lessons) {
const container = document.getElementById('lessonsContainer');
const counterSpan = document.getElementById('availableCount');
if (!container) return;
if (lessons.length === 0) {
container.innerHTML = 'Нет доступных уроков
';
if (counterSpan) counterSpan.textContent = '0';
return;
}
container.innerHTML = lessons.map(lesson => {
let timeHtml = '';
if (lesson.topic && lesson.topic.includes('Консультация') && lesson.date && lesson.time) {
timeHtml = `Дата/время: ${escapeHtml(lesson.date)} ${escapeHtml(lesson.time)}
`;
} else {
timeHtml = `Время: Согласно расписания
`;
}
return `
${escapeHtml(lesson.class_name)} | ${escapeHtml(lesson.subject)}
Учитель: ${escapeHtml(lesson.teacher)}
Тема: ${escapeHtml(lesson.topic || '—')}
${timeHtml}
Свободных мест: ${lesson.max_slots - lesson.current_slots}
`;
}).join('');
if (counterSpan) counterSpan.textContent = `${lessons.length}`;
document.querySelectorAll('.lesson-card').forEach(card => {
card.addEventListener('click', () => openModal(card.dataset.id));
});
}
function setupModal() {
const modal = document.getElementById('modal');
const closeSpan = modal.querySelector('.close');
const form = document.getElementById('registrationForm');
closeSpan.onclick = () => modal.style.display = 'none';
window.onclick = (e) => { if (e.target === modal) modal.style.display = 'none'; };
form.addEventListener('submit', async (e) => {
e.preventDefault();
const lessonId = document.getElementById('lessonId').value;
const parentName = document.getElementById('parentName').value.trim();
const parentPhone = document.getElementById('parentPhone').value.trim();
const messageDiv = document.getElementById('modalMessage');
if (!parentName || !parentPhone) {
messageDiv.innerHTML = 'Заполните все поля';
return;
}
try {
const res = await fetch('/api/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ lesson_id: lessonId, parent_name: parentName, parent_phone: parentPhone })
});
const data = await res.json();
if (res.ok) {
messageDiv.innerHTML = '✅ Вы успешно записаны!';
setTimeout(() => {
modal.style.display = 'none';
loadLessons();
}, 1500);
} else {
messageDiv.innerHTML = `${data.error || 'Ошибка'}`;
}
} catch (err) {
messageDiv.innerHTML = 'Ошибка сервера';
}
});
}
function openModal(lessonId) {
const modal = document.getElementById('modal');
const lesson = allLessons.find(l => l.id == lessonId);
if (!lesson) return;
let timeInfo = '';
if (lesson.topic && lesson.topic.includes('Консультация') && lesson.date && lesson.time) {
timeInfo = `${lesson.date} ${lesson.time}`;
} else {
timeInfo = 'Согласно расписания';
}
document.getElementById('lessonId').value = lessonId;
document.getElementById('modalLessonInfo').innerHTML = `
${escapeHtml(lesson.class_name)}
${escapeHtml(lesson.subject)} — ${escapeHtml(lesson.teacher)}
${timeInfo}
`;
document.getElementById('modalMessage').innerHTML = '';
document.getElementById('registrationForm').reset();
modal.style.display = 'flex';
}
function escapeHtml(str) {
if (!str) return '';
return str.replace(/[&<>]/g, function(m) {
if (m === '&') return '&';
if (m === '<') return '<';
if (m === '>') return '>';
return m;
});
}
// ---------- Инициализация ----------
document.addEventListener('DOMContentLoaded', async () => {
await checkAuthAndRender();
await loadFilterOptions();
await loadLessons();
setupModal();
const classSelect = document.getElementById('filterClass');
const teacherSelect = document.getElementById('filterTeacher');
const topicSelect = document.getElementById('filterTopic');
function handleFilterChange() {
updateDependentFilters();
applyFilters();
}
classSelect?.addEventListener('change', handleFilterChange);
teacherSelect?.addEventListener('change', handleFilterChange);
topicSelect?.addEventListener('change', handleFilterChange);
document.getElementById('resetFilter')?.addEventListener('click', () => {
classSelect.value = '';
teacherSelect.value = '';
topicSelect.value = '';
updateDependentFilters();
applyFilters();
});
});