This commit is contained in:
Калугин Олег Александрович
2026-04-13 12:06:31 +00:00
committed by GitVerse
parent ae3227f127
commit 2d007d2359
8 changed files with 318 additions and 99 deletions

115
public/k.js Normal file
View File

@@ -0,0 +1,115 @@
// public/k.js управление привязкой учителей к корпусам
let currentUser = null;
let teachersList = []; // [{ id, name, subject, campus }]
document.addEventListener('DOMContentLoaded', async () => {
await checkAuth();
await loadTeachers();
setupEventListeners();
});
async function checkAuth() {
try {
const res = await fetch('/api/me');
const data = await res.json();
if (!data.authenticated || data.user.role !== 'admin') {
window.location.href = '/login.html';
return;
}
currentUser = data.user;
document.getElementById('userInfo').innerHTML = `👋 ${currentUser.full_name} (${currentUser.role})`;
} catch (err) {
window.location.href = '/login.html';
}
}
async function loadTeachers() {
try {
const res = await fetch('/api/teachers');
teachersList = await res.json();
renderTable();
} catch (err) {
console.error(err);
document.getElementById('tableBody').innerHTML = '<tr><td colspan="3">Ошибка загрузки</td></tr>';
}
}
function renderTable() {
const tbody = document.getElementById('tableBody');
if (!teachersList.length) {
tbody.innerHTML = '<tr><td colspan="3">Нет учителей</td></tr>';
return;
}
tbody.innerHTML = teachersList.map(teacher => `
<tr data-id="${teacher.id}">
<td>${escapeHtml(teacher.name)}</td>
<td>${escapeHtml(teacher.subject || '—')}</td>
<td>
<select class="campus-select" data-id="${teacher.id}">
<option value="" ${teacher.campus === '' ? 'selected' : ''}>Оба корпуса</option>
<option value="Феофанова 10" ${teacher.campus === 'Феофанова 10' ? 'selected' : ''}>Феофанова 10</option>
<option value="Цветоносная 2" ${teacher.campus === 'Цветоносная 2' ? 'selected' : ''}>Цветоносная 2</option>
</select>
</td>
</tr>
`).join('');
}
async function saveAllChanges() {
const updates = [];
document.querySelectorAll('.campus-select').forEach(select => {
const teacherId = parseInt(select.dataset.id);
const newCampus = select.value;
updates.push({ id: teacherId, campus: newCampus });
});
const messageDiv = document.getElementById('message');
messageDiv.style.display = 'block';
messageDiv.className = 'message';
messageDiv.innerHTML = 'Сохранение...';
try {
const res = await fetch('/api/teachers/campus/batch', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ updates })
});
const data = await res.json();
if (res.ok) {
messageDiv.className = 'message success';
messageDiv.innerHTML = '✅ Изменения сохранены';
setTimeout(() => messageDiv.style.display = 'none', 3000);
// обновляем локальные данные
teachersList = teachersList.map(t => {
const update = updates.find(u => u.id === t.id);
if (update) t.campus = update.campus;
return t;
});
} else {
throw new Error(data.error || 'Ошибка сохранения');
}
} catch (err) {
messageDiv.className = 'message error';
messageDiv.innerHTML = `❌ Ошибка: ${err.message}`;
setTimeout(() => messageDiv.style.display = 'none', 3000);
}
}
function setupEventListeners() {
document.getElementById('saveAllBtn')?.addEventListener('click', saveAllChanges);
document.getElementById('logoutBtn')?.addEventListener('click', async () => {
await fetch('/api/logout', { method: 'POST' });
window.location.href = '/';
});
}
function escapeHtml(str) {
if (!str) return '';
return str.replace(/[&<>]/g, function(m) {
if (m === '&') return '&amp;';
if (m === '<') return '&lt;';
if (m === '>') return '&gt;';
return m;
});
}