From ebd5335ef19cc6acc4851fb81548f387b9205983 Mon Sep 17 00:00:00 2001 From: kalugin66 Date: Tue, 14 Apr 2026 12:00:46 +0500 Subject: [PATCH] =?UTF-8?q?=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D0=B0=D1=80=D0=B0=D0=BB=D0=B5=D0=BB=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/admin.html | 2 + public/index.html | 23 +++++-- public/info.html | 2 + public/main.js | 148 ++++++++++++++++++++++++++++++++++++++++++---- public/style.css | 25 ++++++++ 5 files changed, 184 insertions(+), 16 deletions(-) diff --git a/public/admin.html b/public/admin.html index aabc5a6..7deb8a1 100644 --- a/public/admin.html +++ b/public/admin.html @@ -9,6 +9,8 @@

Панель администратора

+ +
diff --git a/public/index.html b/public/index.html index 4e1b230..04e859f 100644 --- a/public/index.html +++ b/public/index.html @@ -7,10 +7,25 @@ -
-

День открытых дверей

-

Выберите урок, на который хотите записаться

-
+
+

День открытых дверей

+

Выберите урок, на который хотите записаться

+
+
+ + +
diff --git a/public/info.html b/public/info.html index 8796ae5..0e766f1 100644 --- a/public/info.html +++ b/public/info.html @@ -74,6 +74,8 @@

Список записавшихся родителей

+ +
diff --git a/public/main.js b/public/main.js index bbe7551..48c205c 100644 --- a/public/main.js +++ b/public/main.js @@ -1,7 +1,130 @@ -// public/main.js – страница записи родителей +// 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 = ` + + `; + 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([ @@ -116,13 +239,12 @@ function renderLessons(lessons) { } 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 = `

Время: Согласно расписания

`; -} + if (lesson.topic && lesson.topic.includes('Консультация') && lesson.date && lesson.time) { + timeHtml = `

Дата/время: ${escapeHtml(lesson.date)} ${escapeHtml(lesson.time)}

`; + } else { + timeHtml = `

Время: Согласно расписания

`; + } return `
@@ -192,11 +314,11 @@ function openModal(lessonId) { if (!lesson) return; let timeInfo = ''; -if (lesson.topic && lesson.topic.includes('Консультация') && lesson.date && lesson.time) { - timeInfo = `${lesson.date} ${lesson.time}`; -} else { - 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 = ` @@ -219,7 +341,9 @@ function escapeHtml(str) { }); } +// ---------- Инициализация ---------- document.addEventListener('DOMContentLoaded', async () => { + await checkAuthAndRender(); await loadFilterOptions(); await loadLessons(); setupModal(); diff --git a/public/style.css b/public/style.css index 03f3158..f5871fe 100644 --- a/public/style.css +++ b/public/style.css @@ -251,4 +251,29 @@ form input, form textarea { } .danger-btn:hover { background: #991b1b; +} +.employee-btn, .logout-btn, .user-links a { + background: #2c3e66; + color: white; + border: none; + padding: 6px 12px; + border-radius: 20px; + text-decoration: none; + font-size: 0.9rem; + cursor: pointer; + display: inline-block; + margin: 0 5px; +} +.employee-btn:hover, .logout-btn:hover, .user-links a:hover { + background: #1e3a8a; +} +.user-links { + display: flex; + gap: 12px; + align-items: center; + justify-content: flex-end; +} +#authContainer { + text-align: right; + margin-top: 10px; } \ No newline at end of file