feat(journal): карточка отчёта по ученику в модалке

- новая модалка #reportCardModal с фото, именем, текстом записи и бейджами
- кнопка «Карточка отчёта» (иконка contact) в плитке и в карточке журнала
- закрытие по клику по оверлею и по Escape
- imgModal поднят над карточкой, чтобы просмотр фото открывался поверх неё
This commit is contained in:
dev
2026-10-04 21:53:05 +03:00
parent 19be1cc9ef
commit 8fc6ea804a
3 changed files with 217 additions and 0 deletions
+45
View File
@@ -48,6 +48,42 @@ function mainPhotoPath(e) {
return null;
}
function openReportCard(id) {
const e = currentEntries.find(x => x.id === id);
if (!e) return;
const mp = mainPhotoPath(e);
const photo = document.getElementById('reportCardPhoto');
const noPhoto = document.getElementById('reportCardNoPhoto');
if (mp) {
photo.src = thumbSrc(mp);
photo.dataset.img = `${API}${mp}`;
photo.alt = e.student_name || '';
photo.hidden = false;
noPhoto.hidden = true;
} else {
photo.src = '';
delete photo.dataset.img;
photo.alt = '';
photo.hidden = true;
noPhoto.hidden = false;
}
document.getElementById('reportCardName').textContent = e.student_name || '';
document.getElementById('reportCardText').textContent = e.description || '';
const groupBadge = document.getElementById('reportCardTime');
const group = e.group_name || '';
groupBadge.textContent = group;
groupBadge.parentElement.hidden = !group;
const toolBadge = document.getElementById('reportCardModule').parentElement;
const tool = e.module_name || '';
document.getElementById('reportCardModule').textContent = tool;
toolBadge.hidden = !tool;
document.getElementById('reportCardModal').classList.add('open');
}
function closeReportCard() {
document.getElementById('reportCardModal').classList.remove('open');
}
function filesHTML(files) {
if (!files || !files.length) return '';
return `<div class="entry-files">${files.map(f => {
@@ -126,6 +162,7 @@ function gridEntryHTML(e) {
${filesHTML(e.files)}
<div class="time">${fmtFull(e.created_at)}</div>
</div>
<button class="edit" data-report="${e.id}" title="Карточка отчёта"><i data-lucide="contact"></i></button>
<button class="edit" data-edit="${e.id}" title="Редактировать">✎</button>
${mp ? `<button class="edit" data-enhance="${e.id}" title="Улучшить фото">✦</button>` : ''}
<button class="del" data-del="${e.id}" title="Удалить">&times;</button>
@@ -150,6 +187,7 @@ function cardEntryHTML(e) {
<div class="foot">
<span>${fmtFull(e.created_at)}</span>
<span>
<button class="edit" data-report="${e.id}" title="Карточка отчёта"><i data-lucide="contact"></i></button>
<button class="edit" data-edit="${e.id}" title="Редактировать">✎</button>
${mp ? `<button class="edit" data-enhance="${e.id}" title="Улучшить фото">✦</button>` : ''}
<button class="del" data-del="${e.id}" title="Удалить">&times;</button>
@@ -1514,10 +1552,17 @@ function copyLink() { copyText(createdLinkUrl); }
document.getElementById('imgModal').addEventListener('click', e => e.currentTarget.classList.remove('open'));
document.getElementById('editModal').addEventListener('click', e => { if (e.target === e.currentTarget) closeEdit(); });
document.getElementById('linkModal').addEventListener('click', e => { if (e.target === e.currentTarget) closeLinkCreate(); });
document.getElementById('reportCardModal').addEventListener('click', e => { if (e.target === e.currentTarget) closeReportCard(); });
document.addEventListener('keydown', e => {
if (e.key !== 'Escape') return;
if (document.getElementById('reportCardModal').classList.contains('open')) closeReportCard();
});
document.getElementById('grid').addEventListener('click', e => {
const det = e.target.closest('[data-detach]');
if (det) { detachFile(parseInt(det.dataset.detach, 10)); return; }
const rp = e.target.closest('[data-report]');
if (rp) { openReportCard(parseInt(rp.dataset.report, 10)); return; }
const ed = e.target.closest('[data-edit]');
if (ed) { openEdit(parseInt(ed.dataset.edit, 10)); return; }
const en = e.target.closest('[data-enhance]');