Создание кнопки "Добавить занятие" с модальным окном с выбором дня,недели и тд.

This commit is contained in:
alekan
2026-03-02 23:27:20 +03:00
parent 0e03dcb2d6
commit 2004766855
3 changed files with 323 additions and 12 deletions

View File

@@ -584,4 +584,50 @@ tbody tr:hover {
.modal-close:hover {
color: var(--error);
}
.btn-add-lesson {
padding: 0.35rem 0.7rem;
background: rgba(16, 185, 129, 0.1);
border: 1px solid rgba(16, 185, 129, 0.2);
border-radius: var(--radius-sm);
color: var(--success);
font-family: inherit;
font-size: 0.8rem;
cursor: pointer;
transition: background var(--transition), transform var(--transition);
position: relative;
overflow: hidden;
}
.btn-add-lesson:hover {
background: rgba(16, 185, 129, 0.2);
transform: scale(1.05);
}
/* Кнопки-переключатели для недели */
.btn-checkbox {
display: inline-block;
cursor: pointer;
}
.btn-checkbox input {
position: absolute;
opacity: 0;
width: 0;
height: 0;
}
.checkbox-btn {
display: inline-block;
padding: 0.5rem 1rem;
background: var(--bg-secondary);
border: 1px solid var(--bg-card-border);
border-radius: var(--radius-sm);
color: var(--text-primary);
transition: all var(--transition);
user-select: none;
}
.btn-checkbox input:checked + .checkbox-btn {
background: var(--success, #10b981); /* используем success или зелёный */
border-color: var(--success, #10b981);
color: white;
}

View File

@@ -7,7 +7,91 @@ const ROLE_BADGE = { ADMIN: 'badge-admin', TEACHER: 'badge-teacher', STUDENT: 'b
export async function initUsers() {
const usersTbody = document.getElementById('users-tbody');
const createForm = document.getElementById('create-form');
const createAlert = document.getElementById('create-alert');
// Элементы модального окна добавления занятия
const modalAddLesson = document.getElementById('modal-add-lesson');
const modalAddLessonClose = document.getElementById('modal-add-lesson-close');
const addLessonForm = document.getElementById('add-lesson-form');
const lessonGroupSelect = document.getElementById('lesson-group');
const lessonDisciplineSelect = document.getElementById('lesson-discipline');
const lessonUserId = document.getElementById('lesson-user-id');
const lessonDaySelect = document.getElementById('lesson-day');
const weekUpper = document.getElementById('week-upper');
const weekLower = document.getElementById('week-lower');
// NEW: получаем элемент выбора времени
const lessonTimeSelect = document.getElementById('lesson-time');
// Переменные для хранения загруженных данных
let groups = [];
let subjects = [];
// NEW: массивы с временными слотами
const weekdaysTimes = [
"8:00-9:30",
"9:40-11:10",
"11:40-13:10",
"13:20-14:50",
"15:00-16:30",
"16:50-18:20",
"18:30-19:00"
];
const saturdayTimes = [
"8:20-9:50",
"10:00-11:30",
"11:40-13:10",
"13:20-14:50"
];
// Загрузка групп с сервера
async function loadGroups() {
try {
groups = await api.get('/api/groups');
renderGroupOptions();
} catch (e) {
console.error('Ошибка загрузки групп:', e);
}
}
// Загрузка дисциплин
async function loadSubjects() {
try {
subjects = await api.get('/api/subjects');
renderSubjectOptions();
} catch (e) {
console.error('Ошибка загрузки дисциплин:', e);
}
}
// Заполнение select группами
function renderGroupOptions() {
lessonGroupSelect.innerHTML = '<option value="">Выберите группу</option>' +
groups.map(g => `<option value="${g.id}">${escapeHtml(g.name)}</option>`).join('');
}
// Заполнение select дисциплинами
function renderSubjectOptions() {
lessonDisciplineSelect.innerHTML = '<option value="">Выберите дисциплину</option>' +
subjects.map(s => `<option value="${s.id}">${escapeHtml(s.name)}</option>`).join('');
}
// NEW: функция обновления списка времени в зависимости от дня
function updateTimeOptions(dayValue) {
let times = [];
if (dayValue === "Суббота") {
times = saturdayTimes;
} else if (dayValue && dayValue !== '') {
times = weekdaysTimes;
} else {
lessonTimeSelect.innerHTML = '<option value="">Сначала выберите день</option>';
lessonTimeSelect.disabled = true;
return;
}
lessonTimeSelect.innerHTML = '<option value="">Выберите время</option>' +
times.map(t => `<option value="${t}">${t}</option>`).join('');
lessonTimeSelect.disabled = false;
}
async function loadUsers() {
try {
@@ -29,9 +113,93 @@ export async function initUsers() {
<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>
</tr>`).join('');
}
// Сброс формы модального окна
function resetLessonForm() {
addLessonForm.reset();
lessonUserId.value = '';
if (weekUpper) weekUpper.checked = false;
if (weekLower) weekLower.checked = false;
// NEW: сбрасываем селект времени
lessonTimeSelect.innerHTML = '<option value="">Сначала выберите день</option>';
lessonTimeSelect.disabled = true;
hideAlert('add-lesson-alert');
}
// Открытие модалки с установкой userId
function openAddLessonModal(userId) {
lessonUserId.value = userId;
// NEW: сбрасываем выбранный день и время
lessonDaySelect.value = '';
updateTimeOptions('');
modalAddLesson.classList.add('open');
}
// Обработчик отправки формы добавления занятия
addLessonForm.addEventListener('submit', async (e) => {
e.preventDefault();
hideAlert('add-lesson-alert');
const userId = lessonUserId.value;
const groupId = lessonGroupSelect.value;
const subjectId = lessonDisciplineSelect.value;
const dayOfWeek = lessonDaySelect.value;
const timeSlot = lessonTimeSelect.value; // NEW: получаем выбранное время
// Проверка обязательных полей
if (!groupId) {
showAlert('add-lesson-alert', 'Выберите группу', 'error');
return;
}
if (!subjectId) {
showAlert('add-lesson-alert', 'Выберите дисциплину', 'error');
return;
}
if (!dayOfWeek) {
showAlert('add-lesson-alert', 'Выберите день недели', 'error');
return;
}
// NEW: проверка времени
if (!timeSlot) {
showAlert('add-lesson-alert', 'Выберите время', 'error');
return;
}
// Определяем выбранный тип недели
const weekUpperChecked = weekUpper?.checked || false;
const weekLowerChecked = weekLower?.checked || false;
let weekType = null;
if (weekUpperChecked && weekLowerChecked) {
weekType = 'Обе';
} else if (weekUpperChecked) {
weekType = 'Верхняя';
} else if (weekLowerChecked) {
weekType = 'Нижняя';
}
try {
// Отправляем данные на сервер
const response = await api.post('/api/users/lessons/create', {
teacherId: parseInt(userId),
groupId: parseInt(groupId),
lessonTypeId: parseInt(subjectId),
day: dayOfWeek,
week: weekType,
time: timeSlot // передаём время
});
showAlert('add-lesson-alert', 'Занятие добавлено', 'success');
setTimeout(() => {
modalAddLesson.classList.remove('open');
resetLessonForm();
}, 1500);
} catch (e) {
showAlert('add-lesson-alert', e.message || 'Ошибка добавления занятия', 'error');
}
});
createForm.addEventListener('submit', async (e) => {
e.preventDefault();
hideAlert('create-alert');
@@ -50,18 +218,52 @@ export async function initUsers() {
}
});
// Обработчик кликов по таблице
usersTbody.addEventListener('click', async (e) => {
const btn = e.target.closest('.btn-delete');
if (!btn) return;
if (!confirm('Удалить пользователя?')) return;
try {
await api.delete('/api/users/' + btn.dataset.id);
loadUsers();
} catch (e) {
alert(e.message || 'Ошибка удаления');
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);
}
}
});
// Initial load
loadUsers();
}
// NEW: обработчик изменения дня недели для обновления списка времени
lessonDaySelect.addEventListener('change', function() {
updateTimeOptions(this.value);
});
// Закрытие модалки по крестику
if (modalAddLessonClose) {
modalAddLessonClose.addEventListener('click', () => {
modalAddLesson.classList.remove('open');
resetLessonForm();
});
}
// Закрытие по клику на overlay
if (modalAddLesson) {
modalAddLesson.addEventListener('click', (e) => {
if (e.target === modalAddLesson) {
modalAddLesson.classList.remove('open');
resetLessonForm();
}
});
}
// Загружаем все данные при инициализации
await Promise.all([loadUsers(), loadGroups(), loadSubjects()]);
}

View File

@@ -45,3 +45,66 @@
</table>
</div>
</div>
<!-- Add Lesson Modal -->
<div class="modal-overlay" id="modal-add-lesson">
<div class="modal-content card">
<h2>Добавить занятие</h2>
<button class="modal-close" id="modal-add-lesson-close">&times;</button>
<form id="add-lesson-form">
<input type="hidden" id="lesson-user-id">
<div class="form-group" style="margin-top: 1rem;">
<label for="lesson-group">Группа</label>
<select id="lesson-group" required>
<option value="">Выберите группу</option>
</select>
</div>
<div class="form-group" style="margin-top: 1rem;">
<label for="lesson-discipline">Дисциплина</label>
<select id="lesson-discipline" required>
<option value="">Выберите дисциплину</option>
</select>
</div>
<div class="form-row" style="margin-top: 1rem;">
<div class="form-group" style="flex: 1;">
<label for="lesson-day">День недели</label>
<select id="lesson-day" required>
<option value="">Выберите день</option>
<option value="Понедельник">Понедельник</option>
<option value="Вторник">Вторник</option>
<option value="Среда">Среда</option>
<option value="Четверг">Четверг</option>
<option value="Пятница">Пятница</option>
<option value="Суббота">Суббота</option>
</select>
</div>
<div class="form-group" style="flex: 1;">
<label>Неделя</label>
<div style="display: flex; gap: 0.5rem;">
<label class="btn-checkbox">
<input type="checkbox" name="weekType" value="Верхняя" id="week-upper">
<span class="checkbox-btn">Верхняя</span>
</label>
<label class="btn-checkbox">
<input type="checkbox" name="weekType" value="Нижняя" id="week-lower">
<span class="checkbox-btn">Нижняя</span>
</label>
</div>
</div>
</div>
<div class="form-group" style="margin-top: 1rem;">
<label for="lesson-time">Время занятия</label>
<select id="lesson-time" required disabled>
<option value="">Сначала выберите день</option>
</select>
</div>
<button type="submit" class="btn-primary" style="width: 100%; margin-top: 1rem;">Сохранить</button>
<div class="form-alert" id="add-lesson-alert" role="alert"></div>
</form>
</div>
</div>