поправил паралель

This commit is contained in:
2026-04-14 12:00:46 +05:00
parent 8c326ef06a
commit ebd5335ef1
5 changed files with 184 additions and 16 deletions

View File

@@ -9,6 +9,8 @@
<header> <header>
<h1>Панель администратора</h1> <h1>Панель администратора</h1>
<div id="userInfo"></div> <div id="userInfo"></div>
<button onclick="location.href='/'" class="nav-btn">🏠 Главная</button>
<button onclick="location.href='/info'" class="nav-btn">📊 Список записей</button>
<button id="logoutBtn">Выйти</button> <button id="logoutBtn">Выйти</button>
</header> </header>
<main> <main>

View File

@@ -7,10 +7,25 @@
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="style.css">
</head> </head>
<body> <body>
<header> <header>
<h1>День открытых дверей</h1> <h1>День открытых дверей</h1>
<p>Выберите урок, на который хотите записаться</p> <h1>Выберите урок, на который хотите записаться</h1>
</header> <div id="authContainer" style="margin-top: 10px;"></div>
</header>
<!-- Модальное окно авторизации -->
<div id="authModal" class="modal">
<div class="modal-content">
<span class="close">&times;</span>
<h3>Вход для сотрудников</h3>
<form id="authForm">
<label>Логин: <input type="text" id="authUsername" required></label>
<label>Пароль: <input type="password" id="authPassword" required></label>
<button type="submit">Войти</button>
<div id="authError" class="error" style="color:red; margin-top:10px;"></div>
</form>
</div>
</div>
<main> <main>
<div class="filters"> <div class="filters">
<div class="filter-group"> <div class="filter-group">

View File

@@ -74,6 +74,8 @@
<header> <header>
<h1>Список записавшихся родителей</h1> <h1>Список записавшихся родителей</h1>
<div id="userInfo"></div> <div id="userInfo"></div>
<button onclick="location.href='/'" class="nav-btn">🏠 Главная</button>
<button onclick="location.href='/admin'" class="nav-btn">📋 Админка</button>
<button id="logoutBtn">Выйти</button> <button id="logoutBtn">Выйти</button>
</header> </header>
<main class="info-container"> <main class="info-container">

View File

@@ -1,7 +1,130 @@
// public/main.js страница записи родителей // public/main.js страница записи родителей с авторизацией для сотрудников
let allLessons = []; 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 = '<button id="employeeBtn" class="employee-btn">👨‍💼 Для сотрудников</button>';
const btn = document.getElementById('employeeBtn');
if (btn) btn.addEventListener('click', showAuthModal);
} else {
const role = currentUser.role;
let links = '';
if (role === 'admin') {
links = '<a href="/admin" class="admin-link">📋 Админка</a> | <a href="/info" class="info-link">📊 Список записей</a>';
} else if (role === 'user') {
links = '<a href="/info" class="info-link">📊 Список записей</a>';
} else {
links = '<span>Доступ не определён</span>';
}
container.innerHTML = `
<div class="user-links">
${links}
<button id="logoutBtnHeader" class="logout-btn">🚪 Выйти</button>
</div>
`;
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 = `
<div class="modal-content">
<span class="close">&times;</span>
<h3>Вход для сотрудников</h3>
<form id="authForm">
<label>Логин: <input type="text" id="authUsername" required></label>
<label>Пароль: <input type="password" id="authPassword" required></label>
<button type="submit">Войти</button>
<div id="authError" class="error" style="color:red; margin-top:10px;"></div>
</form>
</div>
`;
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() { async function loadFilterOptions() {
try { try {
const [classes, teachers, topics] = await Promise.all([ const [classes, teachers, topics] = await Promise.all([
@@ -116,13 +239,12 @@ function renderLessons(lessons) {
} }
container.innerHTML = lessons.map(lesson => { container.innerHTML = lessons.map(lesson => {
// Определяем, что показывать в строке времени
let timeHtml = ''; let timeHtml = '';
if (lesson.topic && lesson.topic.includes('Консультация') && 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 +314,11 @@ function openModal(lessonId) {
if (!lesson) return; if (!lesson) return;
let timeInfo = ''; let timeInfo = '';
if (lesson.topic && lesson.topic.includes('Консультация') && 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 = `
@@ -219,7 +341,9 @@ function escapeHtml(str) {
}); });
} }
// ---------- Инициализация ----------
document.addEventListener('DOMContentLoaded', async () => { document.addEventListener('DOMContentLoaded', async () => {
await checkAuthAndRender();
await loadFilterOptions(); await loadFilterOptions();
await loadLessons(); await loadLessons();
setupModal(); setupModal();

View File

@@ -251,4 +251,29 @@ form input, form textarea {
} }
.danger-btn:hover { .danger-btn:hover {
background: #991b1b; 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;
} }