Кривая модалка занятий по teacherId добавлена, требует доработки, также код users.js требует унификации+оптимизации(новая модалка вкинута в конец)
This commit is contained in:
@@ -860,4 +860,199 @@ tbody tr:hover {
|
||||
/* используем success или зелёный */
|
||||
border-color: var(--success, #10b981);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* ===== View Lessons Modal ===== */
|
||||
.view-lessons-modal {
|
||||
width: 50% !important; /* Половина экрана */
|
||||
max-width: 50% !important;
|
||||
background: var(--bg-primary);
|
||||
border: 1px solid var(--bg-card-border);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 2rem;
|
||||
position: relative;
|
||||
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
|
||||
margin: 0;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
.modal-header h2 {
|
||||
margin: 0;
|
||||
font-size: 1.3rem;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* Контейнер для занятий */
|
||||
.lessons-container {
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
/* Карточка занятия */
|
||||
.lesson-card {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--bg-card-border);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 1.2rem;
|
||||
margin-bottom: 1rem;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.lesson-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.lesson-card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 0.8rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px dashed var(--bg-card-border);
|
||||
}
|
||||
|
||||
.lesson-group {
|
||||
font-weight: 700;
|
||||
color: var(--accent);
|
||||
font-size: 1rem;
|
||||
background: rgba(99, 102, 241, 0.1);
|
||||
padding: 0.3rem 0.8rem;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.lesson-time {
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.9rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
}
|
||||
|
||||
.lesson-time::before {
|
||||
content: "🕒";
|
||||
font-size: 0.9rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.lesson-card-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.lesson-subject {
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
font-size: 1.1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.lesson-subject::before {
|
||||
content: "📚";
|
||||
font-size: 1rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.lesson-details {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.8rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.lesson-detail-item {
|
||||
background: var(--bg-input);
|
||||
padding: 0.3rem 0.8rem;
|
||||
border-radius: 15px;
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-secondary);
|
||||
border: 1px solid var(--bg-card-border);
|
||||
}
|
||||
|
||||
/* День недели как разделитель */
|
||||
.lesson-day-divider {
|
||||
margin: 1.5rem 0 1rem 0;
|
||||
font-weight: 700;
|
||||
color: var(--accent);
|
||||
font-size: 1.1rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
border-bottom: 2px solid var(--accent-glow);
|
||||
padding-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
.lesson-day-divider:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* Загрузка и пустые состояния */
|
||||
.loading-lessons, .no-lessons {
|
||||
text-align: center;
|
||||
color: var(--text-secondary);
|
||||
padding: 3rem;
|
||||
font-size: 1rem;
|
||||
background: var(--bg-card);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
/* Светлая тема */
|
||||
[data-theme="light"] .lesson-card {
|
||||
background: white;
|
||||
border-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
[data-theme="light"] .lesson-group {
|
||||
background: rgba(99, 102, 241, 0.05);
|
||||
}
|
||||
|
||||
/* Адаптивность */
|
||||
@media (max-width: 1200px) {
|
||||
.view-lessons-modal {
|
||||
width: 70% !important;
|
||||
max-width: 70% !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.view-lessons-modal {
|
||||
width: 90% !important;
|
||||
max-width: 90% !important;
|
||||
}
|
||||
|
||||
.lesson-card-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-view-lessons {
|
||||
padding: 0.35rem 0.7rem;
|
||||
background: rgba(99, 102, 241, 0.1);
|
||||
border: 1px solid rgba(99, 102, 241, 0.2);
|
||||
border-radius: var(--radius-sm);
|
||||
color: var(--accent);
|
||||
font-family: inherit;
|
||||
font-size: 0.8rem;
|
||||
cursor: pointer;
|
||||
transition: all var(--transition);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.btn-view-lessons:hover {
|
||||
background: rgba(99, 102, 241, 0.2);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
@@ -172,8 +172,13 @@ export async function initUsers() {
|
||||
<td>${u.id}</td>
|
||||
<td>${escapeHtml(u.username)}</td>
|
||||
<td><span class="badge ${ROLE_BADGE[u.role] || ''}">${ROLE_LABELS[u.role] || escapeHtml(u.role)}</span></td>
|
||||
<td><button class="btn-delete" data-id="${u.id}">Удалить</button></td>
|
||||
<td><button class="btn-add-lesson" data-id="${u.id}">Добавить занятие</button></td>
|
||||
<td>
|
||||
<button class="btn-delete" data-id="${u.id}">Удалить</button>
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn-add-lesson" data-id="${u.id}">Добавить занятие</button>
|
||||
<button class="btn-view-lessons" data-id="${u.id}" data-name="${escapeHtml(u.username)}" style="margin-left: 0.5rem;">👁️ Занятия</button>
|
||||
</td>
|
||||
</tr>`).join('');
|
||||
}
|
||||
|
||||
@@ -351,4 +356,158 @@ export async function initUsers() {
|
||||
|
||||
// Загружаем все данные при инициализации
|
||||
await Promise.all([loadUsers(), loadGroups(), loadSubjects(), loadClassrooms()]);
|
||||
}
|
||||
|
||||
|
||||
// Элементы второго модального окна
|
||||
const modalViewLessons = document.getElementById('modal-view-lessons');
|
||||
const modalViewLessonsClose = document.getElementById('modal-view-lessons-close');
|
||||
const lessonsContainer = document.getElementById('lessons-container');
|
||||
const modalTeacherName = document.getElementById('modal-teacher-name');
|
||||
|
||||
// Функция для загрузки и отображения занятий преподавателя
|
||||
async function loadTeacherLessons(teacherId, teacherName) {
|
||||
try {
|
||||
lessonsContainer.innerHTML = '<div class="loading-lessons">Загрузка занятий...</div>';
|
||||
|
||||
// Устанавливаем имя преподавателя в заголовок
|
||||
if (teacherName) {
|
||||
modalTeacherName.textContent = `Занятия преподавателя: ${teacherName}`;
|
||||
} else {
|
||||
modalTeacherName.textContent = 'Занятия преподавателя';
|
||||
}
|
||||
|
||||
// Загружаем занятия
|
||||
const lessons = await api.get(`/api/users/lessons/${teacherId}`);
|
||||
|
||||
if (!lessons || lessons.length === 0) {
|
||||
lessonsContainer.innerHTML = '<div class="no-lessons">У преподавателя пока нет занятий</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Группируем занятия по дням недели
|
||||
const daysOrder = ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'];
|
||||
const lessonsByDay = {};
|
||||
|
||||
lessons.forEach(lesson => {
|
||||
if (!lessonsByDay[lesson.day]) {
|
||||
lessonsByDay[lesson.day] = [];
|
||||
}
|
||||
lessonsByDay[lesson.day].push(lesson);
|
||||
});
|
||||
|
||||
// Сортируем занятия в каждом дне по времени
|
||||
Object.keys(lessonsByDay).forEach(day => {
|
||||
lessonsByDay[day].sort((a, b) => {
|
||||
// Простая сортировка по времени (можно улучшить)
|
||||
return a.time.localeCompare(b.time);
|
||||
});
|
||||
});
|
||||
|
||||
// Формируем HTML
|
||||
let html = '';
|
||||
|
||||
daysOrder.forEach(day => {
|
||||
if (lessonsByDay[day]) {
|
||||
html += `<div class="lesson-day-divider">${day}</div>`;
|
||||
|
||||
lessonsByDay[day].forEach(lesson => {
|
||||
html += `
|
||||
<div class="lesson-card">
|
||||
<div class="lesson-card-header">
|
||||
<span class="lesson-group">${escapeHtml(lesson.groupName)}</span>
|
||||
<span class="lesson-time">${escapeHtml(lesson.time)}</span>
|
||||
</div>
|
||||
<div class="lesson-card-body">
|
||||
<div class="lesson-subject">${escapeHtml(lesson.subjectName)}</div>
|
||||
<div class="lesson-details">
|
||||
<span class="lesson-detail-item">${escapeHtml(lesson.typeLesson)}</span>
|
||||
<span class="lesson-detail-item">${escapeHtml(lesson.lessonFormat)}</span>
|
||||
<span class="lesson-detail-item">${escapeHtml(lesson.week)}</span>
|
||||
<span class="lesson-detail-item">${escapeHtml(lesson.classroomName)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
lessonsContainer.innerHTML = html;
|
||||
|
||||
} catch (e) {
|
||||
lessonsContainer.innerHTML = `<div class="no-lessons">Ошибка загрузки: ${escapeHtml(e.message)}</div>`;
|
||||
console.error('Ошибка загрузки занятий:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// Функция открытия модального окна
|
||||
function openViewLessonsModal(teacherId, teacherName) {
|
||||
loadTeacherLessons(teacherId, teacherName);
|
||||
modalViewLessons.classList.add('open');
|
||||
// Блокируем скролл страницы
|
||||
document.body.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
// Функция закрытия модального окна
|
||||
function closeViewLessonsModal() {
|
||||
modalViewLessons.classList.remove('open');
|
||||
document.body.style.overflow = '';
|
||||
}
|
||||
|
||||
// Обработчик кликов по таблице (добавляем в существующий)
|
||||
// Найдите в коде usersTbody.addEventListener('click', ...) и добавьте в него:
|
||||
|
||||
// ДОЛЖНО ПОЛУЧИТЬСЯ ТАК:
|
||||
usersTbody.addEventListener('click', async (e) => {
|
||||
const deleteBtn = e.target.closest('.btn-delete');
|
||||
if (deleteBtn) {
|
||||
if (!confirm('Удалить пользователя?')) return;
|
||||
try {
|
||||
await api.delete('/api/users/' + deleteBtn.dataset.id);
|
||||
loadUsers();
|
||||
} catch (e) {
|
||||
alert(e.message || 'Ошибка удаления');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const addLessonBtn = e.target.closest('.btn-add-lesson');
|
||||
if (addLessonBtn) {
|
||||
e.preventDefault();
|
||||
if (modalAddLesson) {
|
||||
openAddLessonModal(addLessonBtn.dataset.id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// НОВЫЙ ОБРАБОТЧИК для кнопки просмотра занятий
|
||||
const viewLessonsBtn = e.target.closest('.btn-view-lessons');
|
||||
if (viewLessonsBtn) {
|
||||
e.preventDefault();
|
||||
const teacherId = viewLessonsBtn.dataset.id;
|
||||
const teacherName = viewLessonsBtn.dataset.name;
|
||||
openViewLessonsModal(teacherId, teacherName);
|
||||
}
|
||||
});
|
||||
|
||||
// Обработчики закрытия модального окна
|
||||
if (modalViewLessonsClose) {
|
||||
modalViewLessonsClose.addEventListener('click', closeViewLessonsModal);
|
||||
}
|
||||
|
||||
// Закрытие по клику на overlay
|
||||
if (modalViewLessons) {
|
||||
modalViewLessons.addEventListener('click', (e) => {
|
||||
if (e.target === modalViewLessons) {
|
||||
closeViewLessonsModal();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Закрытие по Escape
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && modalViewLessons?.classList.contains('open')) {
|
||||
closeViewLessonsModal();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -154,5 +154,18 @@
|
||||
<div class="form-alert" id="add-lesson-alert" role="alert" style="margin-top: 1rem;"></div>
|
||||
</form>
|
||||
</div>
|
||||
<!-- View Teacher Lessons Modal -->
|
||||
<div class="modal-overlay" id="modal-view-lessons">
|
||||
<div class="modal-content view-lessons-modal">
|
||||
<div class="modal-header">
|
||||
<h2 id="modal-teacher-name">Занятия преподавателя</h2>
|
||||
<button class="modal-close" id="modal-view-lessons-close">×</button>
|
||||
</div>
|
||||
|
||||
<div class="lessons-container" id="lessons-container">
|
||||
<!-- Фильтры по дням (добавим позже) -->
|
||||
<div class="loading-lessons">Загрузка занятий...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user