function toggleAccordion(accordionId) { const content = document.getElementById(accordionId); const icon = document.getElementById(`${accordionId}-icon`); if (content.classList.contains('expanded')) { content.classList.remove('expanded'); icon.classList.remove('expanded'); } else { content.classList.add('expanded'); icon.classList.add('expanded'); } } function toggleCourseLayouts(courseId) { const layoutsRow = document.getElementById(`layouts-${courseId}`); const layoutsContainer = document.getElementById(`layouts-container-${courseId}`); if (layoutsRow.style.display === 'table-row') { layoutsRow.style.display = 'none'; return; } layoutsRow.style.display = 'table-row'; if (layoutsContainer.dataset.loaded === 'true') { return; } htmx.ajax('GET', `/partials/course-layouts/${courseId}`, {target: `#layouts-container-${courseId}`, swap: 'innerHTML'}); layoutsContainer.dataset.loaded = 'true'; } // ── Mobile course card toggle ────────────────────── let openMobileCourseId = null; function toggleMobileCourseLayouts(courseId) { const card = document.getElementById('m-course-' + courseId); if (!card) return; const isOpen = card.classList.contains('is-open'); // Close previously open card if (openMobileCourseId !== null && openMobileCourseId !== courseId) { const prevCard = document.getElementById('m-course-' + openMobileCourseId); if (prevCard) { prevCard.classList.remove('is-open'); prevCard.setAttribute('aria-expanded', 'false'); } openMobileCourseId = null; } if (isOpen) { card.classList.remove('is-open'); card.setAttribute('aria-expanded', 'false'); openMobileCourseId = null; return; } card.classList.add('is-open'); card.setAttribute('aria-expanded', 'true'); openMobileCourseId = courseId; // Lazy-load layouts on first expand const container = document.getElementById('m-layouts-container-' + courseId); if (container && container.dataset.loaded !== 'true') { htmx.ajax('GET', '/partials/course-layouts/' + courseId, { target: '#m-layouts-container-' + courseId, swap: 'innerHTML' }); container.dataset.loaded = 'true'; } } async function scrapeCourses() { const btn = document.getElementById('scrape-courses-btn'); btn.disabled = true; btn.textContent = 'Scraping...'; try { const response = await fetch('/api/scrape-courses', { method: 'POST' }); const data = await response.json(); if (data.success) { alert(data.message); htmx.ajax('GET', '/partials/course-table', '#courses-table'); } else { alert('Failed to scrape courses'); } } catch (error) { console.error('Error scraping courses:', error); alert('Error scraping courses'); } finally { btn.disabled = false; btn.textContent = 'Scrape Courses'; } } async function scrapeLayouts(courseId, courseName) { const icon = document.querySelector(`#row-${courseId} .refresh-icon`); icon.classList.add('spinning'); try { const response = await fetch(`/api/scrape-layouts/${courseId}`, { method: 'POST' }); const data = await response.json(); if (response.status === 409) { alert(data.message || 'Scrape already in progress for this course. Please wait.'); } else if (data.success) { const layoutsContainer = document.getElementById(`layouts-container-${courseId}`); layoutsContainer.dataset.loaded = 'false'; const layoutsRow = document.getElementById(`layouts-${courseId}`); if (layoutsRow.style.display === 'table-row') { htmx.ajax('GET', `/partials/course-layouts/${courseId}`, {target: `#layouts-container-${courseId}`, swap: 'innerHTML'}); layoutsContainer.dataset.loaded = 'true'; } alert(data.message); } else { alert('Failed to scrape layouts'); } } catch (error) { console.error('Error scraping layouts:', error); alert('Error scraping layouts'); } finally { icon.classList.remove('spinning'); } }