diff --git a/frontend/admin/css/components.css b/frontend/admin/css/components.css
index 6f55d8d..4084a73 100755
--- a/frontend/admin/css/components.css
+++ b/frontend/admin/css/components.css
@@ -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);
}
\ No newline at end of file
diff --git a/frontend/admin/js/views/users.js b/frontend/admin/js/views/users.js
index 57991c4..ef01e89 100755
--- a/frontend/admin/js/views/users.js
+++ b/frontend/admin/js/views/users.js
@@ -172,8 +172,13 @@ export async function initUsers() {
${u.id} |
${escapeHtml(u.username)} |
${ROLE_LABELS[u.role] || escapeHtml(u.role)} |
- |
- |
+
+
+ |
+
+
+
+ |
`).join('');
}
@@ -351,4 +356,158 @@ export async function initUsers() {
// Загружаем все данные при инициализации
await Promise.all([loadUsers(), loadGroups(), loadSubjects(), loadClassrooms()]);
-}
\ No newline at end of file
+
+
+// Элементы второго модального окна
+ 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 = 'Загрузка занятий...
';
+
+ // Устанавливаем имя преподавателя в заголовок
+ if (teacherName) {
+ modalTeacherName.textContent = `Занятия преподавателя: ${teacherName}`;
+ } else {
+ modalTeacherName.textContent = 'Занятия преподавателя';
+ }
+
+ // Загружаем занятия
+ const lessons = await api.get(`/api/users/lessons/${teacherId}`);
+
+ if (!lessons || lessons.length === 0) {
+ lessonsContainer.innerHTML = 'У преподавателя пока нет занятий
';
+ 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 += `${day}
`;
+
+ lessonsByDay[day].forEach(lesson => {
+ html += `
+
+
+
+
${escapeHtml(lesson.subjectName)}
+
+ ${escapeHtml(lesson.typeLesson)}
+ ${escapeHtml(lesson.lessonFormat)}
+ ${escapeHtml(lesson.week)}
+ ${escapeHtml(lesson.classroomName)}
+
+
+
+ `;
+ });
+ }
+ });
+
+ lessonsContainer.innerHTML = html;
+
+ } catch (e) {
+ lessonsContainer.innerHTML = `Ошибка загрузки: ${escapeHtml(e.message)}
`;
+ 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();
+ }
+ });
+}
diff --git a/frontend/admin/views/users.html b/frontend/admin/views/users.html
index 826aebc..3eb70b2 100755
--- a/frontend/admin/views/users.html
+++ b/frontend/admin/views/users.html
@@ -154,5 +154,18 @@
+
+
+
+
+
+
+
Загрузка занятий...
+
+
+
\ No newline at end of file