поправил паралель
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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">×</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">
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
148
public/main.js
148
public/main.js
@@ -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">×</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();
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user