121 lines
4.1 KiB
JavaScript
121 lines
4.1 KiB
JavaScript
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 ──────────────────────
|
|
var openMobileCourseId = null;
|
|
|
|
function toggleMobileCourseLayouts(courseId) {
|
|
var card = document.getElementById('m-course-' + courseId);
|
|
if (!card) return;
|
|
|
|
var isOpen = card.classList.contains('is-open');
|
|
|
|
// Close previously open card
|
|
if (openMobileCourseId !== null && openMobileCourseId !== courseId) {
|
|
var prevCard = document.getElementById('m-course-' + openMobileCourseId);
|
|
if (prevCard) prevCard.classList.remove('is-open');
|
|
openMobileCourseId = null;
|
|
}
|
|
|
|
if (isOpen) {
|
|
card.classList.remove('is-open');
|
|
openMobileCourseId = null;
|
|
return;
|
|
}
|
|
|
|
card.classList.add('is-open');
|
|
openMobileCourseId = courseId;
|
|
|
|
// Lazy-load layouts on first expand
|
|
var 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');
|
|
}
|
|
}
|