cогласно расписания
This commit is contained in:
@@ -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', {
|
|
||||||
method: 'POST',
|
try {
|
||||||
headers: { 'Content-Type': 'application/json' },
|
const response = await fetch('/api/admin/lessons', {
|
||||||
body: JSON.stringify(payload)
|
method: 'POST',
|
||||||
});
|
headers: { 'Content-Type': 'application/json' },
|
||||||
document.getElementById('lessonModal').style.display = 'none';
|
body: JSON.stringify(payload)
|
||||||
loadLessons(getCurrentFilters());
|
});
|
||||||
|
const data = await response.json();
|
||||||
|
if (!response.ok) {
|
||||||
|
alert('Ошибка сохранения: ' + (data.error || 'Неизвестная ошибка'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
document.getElementById('lessonModal').style.display = 'none';
|
||||||
|
// Сбрасываем фильтры, чтобы обновлённый урок точно отобразился
|
||||||
|
resetFilters();
|
||||||
|
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();
|
||||||
|
|||||||
@@ -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 = `
|
||||||
|
|||||||
@@ -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 });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user