diff --git a/public/admin.js b/public/admin.js index 8fd0127..d7d7037 100644 --- a/public/admin.js +++ b/public/admin.js @@ -489,6 +489,7 @@ function copyText(text) { let lessonModalGroups = null; let lessonModalGroupsPromise = null; +let lessonGroupTouched = false; function lessonTodayIso() { return todayIso(); @@ -498,6 +499,49 @@ function lessonNowTime() { return nowHm(); } +function lessonDowFromIso(iso) { + const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(String(iso || '')); + if (!m) return -1; + return new Date(Date.UTC(Number(m[1]), Number(m[2]) - 1, Number(m[3]))).getUTCDay(); +} + +function lessonMinutes(hm) { + const m = /^\s*(\d{1,2}):(\d{2})/.exec(String(hm || '')); + if (!m) return null; + return Number(m[1]) * 60 + Number(m[2]); +} + +function lessonGroupForDateTime(isoDate, hmTime) { + const groups = lessonModalGroups || []; + const dow = lessonDowFromIso(isoDate); + const minutes = lessonMinutes(hmTime); + if (dow < 0 || minutes == null) return null; + let best = null; + let bestStart = -1; + for (const g of groups) { + if (g.day_of_week == null || !g.time_start || !g.time_end) continue; + if (Number(g.day_of_week) !== dow) continue; + const start = lessonMinutes(g.time_start); + const end = lessonMinutes(g.time_end); + if (start == null || end == null || end < start) continue; + if (minutes < start || minutes > end) continue; + if (start > bestStart) { bestStart = start; best = g; } + } + return best; +} + +function applyLessonGroupAuto(modal) { + if (lessonGroupTouched) return null; + const groupSel = modal.querySelector('#lessonGroup'); + if (!groupSel) return null; + const g = lessonGroupForDateTime(modal.querySelector('#lessonDate').value, modal.querySelector('#lessonTime').value); + if (!g) return null; + const value = String(g.id); + if (!Array.from(groupSel.options).some(o => o.value === value)) return null; + groupSel.value = value; + return g; +} + async function loadLessonGroups() { if (lessonModalGroups) return lessonModalGroups; if (!lessonModalGroupsPromise) { @@ -576,8 +620,15 @@ function ensureLessonModal() { const id = modal.querySelector('#lessonId').value; if (id) openLessonVersions(id); }); - groupSel.addEventListener('change', () => prefetchLessonForGroupDate()); - modal.querySelector('#lessonDate').addEventListener('change', () => prefetchLessonForGroupDate()); + groupSel.addEventListener('change', () => { lessonGroupTouched = true; prefetchLessonForGroupDate(); }); + modal.querySelector('#lessonDate').addEventListener('change', () => { + applyLessonGroupAuto(modal); + prefetchLessonForGroupDate(); + }); + modal.querySelector('#lessonTime').addEventListener('change', () => { + applyLessonGroupAuto(modal); + prefetchLessonForGroupDate(); + }); modal.querySelector('#lessonDupGo').addEventListener('click', () => { const id = modal.querySelector('#lessonDup').dataset.id; if (!id) return; @@ -718,6 +769,7 @@ function updateLessonAiRow(modal, r) { function resetLessonModalFields(modal) { lessonDupSeq++; + lessonGroupTouched = false; modal.querySelector('#lessonId').value = ''; showLessonDuplicate(modal, null); modal.querySelector('#lessonDate').value = lessonTodayIso(); @@ -857,6 +909,7 @@ async function openLessonModal(opts = {}) { resetLessonModalFields(modal); const wanted = opts.groupId ? String(opts.groupId) : previous; if (wanted && groups.some(g => String(g.id) === wanted)) groupSel.value = wanted; + if (!opts.id && !opts.groupId) applyLessonGroupAuto(modal); if (opts.text) { const textEl = modal.querySelector('#lessonText');