cогласно расписания

This commit is contained in:
2026-04-13 18:06:41 +05:00
parent fe3824b9da
commit 5af0487869
3 changed files with 68 additions and 34 deletions

View File

@@ -174,6 +174,7 @@ function openLessonModal(id = null) {
document.getElementById('lessonId').value = ''; document.getElementById('lessonId').value = '';
document.getElementById('modalTitle').innerText = id ? 'Редактирование урока' : 'Новый урок'; document.getElementById('modalTitle').innerText = id ? 'Редактирование урока' : 'Новый урок';
if (id) { if (id) {
// Загружаем все уроки и находим нужный (можно было бы сделать отдельный запрос, но так проще)
fetch(`/api/admin/lessons`).then(res => res.json()).then(lessons => { fetch(`/api/admin/lessons`).then(res => res.json()).then(lessons => {
const lesson = lessons.find(l => l.id == id); const lesson = lessons.find(l => l.id == id);
if (lesson) { if (lesson) {
@@ -184,6 +185,7 @@ function openLessonModal(id = null) {
document.getElementById('teacher').value = lesson.teacher; document.getElementById('teacher').value = lesson.teacher;
document.getElementById('topic').value = lesson.topic || ''; document.getElementById('topic').value = lesson.topic || '';
document.getElementById('maxSlots').value = lesson.max_slots; document.getElementById('maxSlots').value = lesson.max_slots;
// Заполняем дату и время, если они есть, иначе пустые строки
document.getElementById('date').value = lesson.date || ''; document.getElementById('date').value = lesson.date || '';
document.getElementById('time').value = lesson.time || ''; document.getElementById('time').value = lesson.time || '';
} }
@@ -196,24 +198,51 @@ function openLessonModal(id = null) {
document.getElementById('lessonForm')?.addEventListener('submit', async (e) => { document.getElementById('lessonForm')?.addEventListener('submit', async (e) => {
e.preventDefault(); e.preventDefault();
const id = document.getElementById('lessonId').value; const id = document.getElementById('lessonId').value;
const class_name = document.getElementById('className').value.trim();
const parallel = parseInt(document.getElementById('parallel').value);
const subject = document.getElementById('subject').value.trim();
const teacher = document.getElementById('teacher').value.trim();
const topic = document.getElementById('topic').value;
const max_slots = parseInt(document.getElementById('maxSlots').value);
const date = document.getElementById('date').value;
const time = document.getElementById('time').value;
// Проверяем обязательные поля (дата и время теперь обязательны)
if (!class_name || isNaN(parallel) || !subject || !teacher || isNaN(max_slots) || !date || !time) {
alert('Пожалуйста, заполните все поля: класс, параллель, предмет, учитель, макс. мест, дата и время.');
return;
}
const payload = { const payload = {
id: id || undefined, id: id || undefined,
class_name: document.getElementById('className').value, class_name,
parallel: parseInt(document.getElementById('parallel').value), parallel,
subject: document.getElementById('subject').value, subject,
teacher: document.getElementById('teacher').value, teacher,
topic: document.getElementById('topic').value, topic,
max_slots: parseInt(document.getElementById('maxSlots').value), max_slots,
date: document.getElementById('date').value, date,
time: document.getElementById('time').value time
}; };
await fetch('/api/admin/lessons', {
try {
const response = await fetch('/api/admin/lessons', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload) body: JSON.stringify(payload)
}); });
const data = await response.json();
if (!response.ok) {
alert('Ошибка сохранения: ' + (data.error || 'Неизвестная ошибка'));
return;
}
document.getElementById('lessonModal').style.display = 'none'; document.getElementById('lessonModal').style.display = 'none';
// Сбрасываем фильтры, чтобы обновлённый урок точно отобразился
resetFilters();
loadLessons(getCurrentFilters()); loadLessons(getCurrentFilters());
} catch (err) {
alert('Ошибка соединения: ' + err.message);
}
}); });
function getCurrentFilters() { function getCurrentFilters() {
@@ -225,6 +254,14 @@ function getCurrentFilters() {
}; };
} }
function resetFilters() {
document.getElementById('filterClass').value = '';
document.getElementById('filterParallel').value = '';
document.getElementById('filterTeacher').value = '';
document.getElementById('filterTopic').value = '';
updateDependentFilters();
}
function setupEventListeners() { function setupEventListeners() {
const classSelect = document.getElementById('filterClass'); const classSelect = document.getElementById('filterClass');
const teacherSelect = document.getElementById('filterTeacher'); const teacherSelect = document.getElementById('filterTeacher');
@@ -244,11 +281,7 @@ function setupEventListeners() {
}); });
document.getElementById('resetFilters')?.addEventListener('click', () => { document.getElementById('resetFilters')?.addEventListener('click', () => {
document.getElementById('filterClass').value = ''; resetFilters();
document.getElementById('filterParallel').value = '';
document.getElementById('filterTeacher').value = '';
document.getElementById('filterTopic').value = '';
updateDependentFilters();
loadLessons({}); loadLessons({});
}); });
@@ -276,7 +309,7 @@ function setupEventListeners() {
} }
}); });
// Импорт (теперь XLSX всегда глобально доступен) // Импорт (XLSX)
function parseExcelToRecords(file) { function parseExcelToRecords(file) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const reader = new FileReader(); const reader = new FileReader();

View File

@@ -118,11 +118,11 @@ function renderLessons(lessons) {
container.innerHTML = lessons.map(lesson => { container.innerHTML = lessons.map(lesson => {
// Определяем, что показывать в строке времени // Определяем, что показывать в строке времени
let timeHtml = ''; let timeHtml = '';
if (lesson.topic === 'Консультация' && lesson.date && lesson.time) { if (lesson.topic && lesson.topic.includes('Консультация') && lesson.date && lesson.time) {
timeHtml = `<p><strong>Дата/время:</strong> ${escapeHtml(lesson.date)} ${escapeHtml(lesson.time)}</p>`; timeHtml = `<p><strong>Дата/время:</strong> ${escapeHtml(lesson.date)} ${escapeHtml(lesson.time)}</p>`;
} else { } else {
timeHtml = `<p><strong>Время:</strong> Согласно расписания</p>`; timeHtml = `<p><strong>Время:</strong> Согласно расписания</p>`;
} }
return ` return `
<div class="lesson-card" data-id="${lesson.id}"> <div class="lesson-card" data-id="${lesson.id}">
@@ -192,11 +192,11 @@ function openModal(lessonId) {
if (!lesson) return; if (!lesson) return;
let timeInfo = ''; let timeInfo = '';
if (lesson.topic === 'Консультация' && lesson.date && lesson.time) { if (lesson.topic && lesson.topic.includes('Консультация') && lesson.date && lesson.time) {
timeInfo = `${lesson.date} ${lesson.time}`; timeInfo = `${lesson.date} ${lesson.time}`;
} else { } else {
timeInfo = 'Согласно расписания'; timeInfo = 'Согласно расписания';
} }
document.getElementById('lessonId').value = lessonId; document.getElementById('lessonId').value = lessonId;
document.getElementById('modalLessonInfo').innerHTML = ` document.getElementById('modalLessonInfo').innerHTML = `

View File

@@ -165,8 +165,9 @@ app.get('/api/admin/lessons', isAuthenticated, isAdmin, async (req, res) => {
app.post('/api/admin/lessons', isAuthenticated, isAdmin, async (req, res) => { app.post('/api/admin/lessons', isAuthenticated, isAdmin, async (req, res) => {
const { id, class_name, parallel, subject, teacher, topic, max_slots, date, time } = req.body; const { id, class_name, parallel, subject, teacher, topic, max_slots, date, time } = req.body;
if (!class_name || !parallel || !subject || !teacher || !max_slots || !date || !time) { // Проверяем все обязательные поля, включая дату и время
return res.status(400).json({ error: 'Все поля обязательны' }); if (!class_name || parallel === undefined || parallel === null || !subject || !teacher || !max_slots || !date || !time) {
return res.status(400).json({ error: 'Все поля, включая дату и время, обязательны' });
} }
try { try {
@@ -181,7 +182,7 @@ app.post('/api/admin/lessons', isAuthenticated, isAdmin, async (req, res) => {
} }
} catch (err) { } catch (err) {
console.error(err); console.error(err);
res.status(500).json({ error: 'Ошибка сохранения урока' }); res.status(500).json({ error: 'Ошибка сохранения урока: ' + err.message });
} }
}); });