const PAGE_SIZE = 20; let page = 1; let total = 0; let searchTimer = null; let groupsLoaded = false; function lessonDateText(iso) { const s = String(iso || '').slice(0, 10); if (!s) return ''; const d = new Date(s + 'T00:00:00'); if (Number.isNaN(d.getTime())) return s; return d.toLocaleDateString('ru-RU', { day: '2-digit', month: '2-digit', year: '2-digit' }); } function lessonWhenText(r) { const date = lessonDateText(r.lesson_date); const time = r.lesson_time ? String(r.lesson_time).slice(0, 5) : ''; return time ? `${date}, ${time}` : date; } function lessonAuthorText(r) { const name = r.author_name || r.author_username; if (!name) return ''; const upd = r.updated_at && r.created_at && new Date(r.updated_at).getTime() - new Date(r.created_at).getTime() > 60000; return upd ? `${name} · изменён ${notifyTime(r.updated_at)}` : name; } function lessonItemHtml(r) { const isToday = String(r.lesson_date).slice(0, 10) === lessonTodayIso(); const author = lessonAuthorText(r); return `
${esc(r.group_name || '')} ${esc(lessonWhenText(r))} ${isToday ? 'сегодня' : ''}
${isAdmin() ? `` : ''}
${esc(r.text || '')}
${author ? `
${esc(author)}
` : ''}
`; } function renderLessons(items) { const list = document.getElementById('lessonsList'); const state = document.getElementById('lessonsState'); list.innerHTML = items.length ? items.map(lessonItemHtml).join('') : '
Отчётов пока нет
'; if (state) { state.textContent = total ? `Показано ${items.length} из ${total}` : ''; } renderIcons(); } async function loadLessons() { const q = new URLSearchParams(); const gid = document.getElementById('groupFilter').value; const df = document.getElementById('dateFrom').value; const dt = document.getElementById('dateTo').value; const search = document.getElementById('searchInput').value.trim(); if (gid) q.set('group_id', gid); if (df) q.set('date_from', df); if (dt) q.set('date_to', dt); if (search) q.set('search', search); q.set('limit', String(PAGE_SIZE)); q.set('offset', String((page - 1) * PAGE_SIZE)); const list = document.getElementById('lessonsList'); try { const res = await fetch(`${API}/api/lesson-reports?${q.toString()}`, { headers: hdr() }); if (!res.ok) { list.innerHTML = `
Ошибка загрузки (${res.status})
`; return; } const data = await res.json(); total = Number(data.total) || 0; const maxPage = Math.max(1, Math.ceil(total / PAGE_SIZE)); if (page > maxPage) { page = maxPage; return loadLessons(); } renderLessons(data.items || []); renderPager(document.getElementById('pager'), page, maxPage, p => { page = p; loadLessons(); }); } catch { list.innerHTML = '
Ошибка сети
'; } } async function loadGroupFilter() { if (groupsLoaded) return; const sel = document.getElementById('groupFilter'); const groups = await loadLessonGroups(); groups.forEach(g => { const o = document.createElement('option'); o.value = g.id; o.textContent = g.branch_name ? `${g.name} (${g.branch_name})` : g.name; sel.appendChild(o); }); groupsLoaded = true; } async function deleteLesson(id) { if (!confirm('Удалить отчёт о занятии?')) return; const res = await fetch(`${API}/api/lesson-reports/${id}`, { method: 'DELETE', headers: hdr() }); const data = await res.json().catch(() => ({})); if (!res.ok) { showToast(data.error || 'Не удалось удалить отчёт'); return; } showToast('Отчёт удалён'); loadLessons(); } function onLessonReportSaved() { loadLessons(); } document.getElementById('lessonsList').addEventListener('click', e => { const edit = e.target.closest('[data-edit]'); if (edit) { openLessonModal({ id: edit.dataset.edit }); return; } const del = e.target.closest('[data-del]'); if (del) { deleteLesson(del.dataset.del); } }); document.getElementById('addLessonBtn').addEventListener('click', () => { openLessonModal({ groupId: document.getElementById('groupFilter').value }); }); document.getElementById('groupFilter').addEventListener('change', () => { page = 1; loadLessons(); }); document.getElementById('dateFrom').addEventListener('change', () => { page = 1; loadLessons(); }); document.getElementById('dateTo').addEventListener('change', () => { page = 1; loadLessons(); }); document.getElementById('searchInput').addEventListener('input', () => { clearTimeout(searchTimer); searchTimer = setTimeout(() => { page = 1; loadLessons(); }, 350); }); (async () => { if (!(await checkAuth())) return; buildSidebar(document.body.dataset.page); await loadGroupFilter(); loadLessons(); })();