`;
sccDbList.appendChild(item);
});
}
// --- Event Handlers ---
function handleAddChallenge(e) {
e.preventDefault();
const title = sccChallengeTitleInput.value.trim();
const problem = sccChallengeProblemInput.value.trim();
const starterCode = sccChallengeStarterCodeInput.value.trim();
if (title && problem) {
const newId = sccNextId++;
const newChallenge = {
id: newId,
title: title,
problem: problem,
starterCode: starterCode
};
sccChallengeDatabase.push(newChallenge);
sccUserSolutions[newId] = starterCode; // Init solution
renderDashboard();
renderConfigList();
// Clear form
sccChallengeTitleInput.value = '';
sccChallengeProblemInput.value = '';
sccChallengeStarterCodeInput.value = '';
}
}
function handleDeleteChallenge(e) {
if (e.target.matches('.scc-delete-btn')) {
const id = parseInt(e.target.dataset.id, 10);
if (confirm("Are you sure you want to delete this challenge?")) {
sccChallengeDatabase = sccChallengeDatabase.filter(c => c.id !== id);
delete sccUserSolutions[id];
renderDashboard();
renderConfigList();
}
}
}
/** Saves solution to state on textarea input */
function handleSolutionEdit(e) {
if (e.target.matches('.scc-solution-editor')) {
const id = parseInt(e.target.dataset.id, 10);
sccUserSolutions[id] = e.target.value;
}
}
/** Runs the code from the corresponding textarea */
function handleRunCode(e) {
if (e.target.matches('.scc-run-btn')) {
const id = parseInt(e.target.dataset.id, 10);
const code = sccUserSolutions[id];
const outputEl = sccToolContainer.querySelector(`#scc-output-${id}`);
if (!code || !outputEl) return;
outputEl.textContent = 'Running...';
// Override console.log to capture output
const oldLog = console.log;
let output = [];
console.log = function(...args) {
output.push(args.map(String).join(' '));
};
try {
// Use new Function() to execute the code
new Function(code)();
} catch (error) {
output.push(`Error: ${error.message}`);
} finally {
// Restore original console.log
console.log = oldLog;
outputEl.textContent = output.join('\n') || 'Code ran successfully with no output.';
}
}
}
/** Generates and downloads a PDF of the solutions */
async function downloadPDF() {
if (typeof jspdf === 'undefined' || typeof html2canvas === 'undefined') {
console.error("jsPDF or html2canvas library not loaded.");
alert("Error: PDF generation libraries not loaded.");
return;
}
const { jsPDF } = window.jspdf;
sccPdfBtn.textContent = 'Generating...';
sccPdfBtn.disabled = true;
const contentToExport = document.getElementById('scc-pdf-content');
if (!contentToExport) {
console.error("PDF content area not found.");
sccPdfBtn.textContent = 'Download Solutions as PDF';
sccPdfBtn.disabled = false;
return;
}
contentToExport.classList.add('scc-pdf-export-content');
try {
const canvas = await html2canvas(contentToExport, {
scale: 2,
useCORS: true,
logging: false,
onclone: (doc) => {
// Transfer textarea values to the cloned document
const originalTextareas = contentToExport.querySelectorAll('.scc-solution-editor');
const clonedTextareas = doc.querySelectorAll('.scc-solution-editor');
originalTextareas.forEach((original, index) => {
if (clonedTextareas[index]) {
clonedTextareas[index].textContent = original.value;
// Set height to fit all content
clonedTextareas[index].style.height = 'auto';
clonedTextareas[index].style.height = (clonedTextareas[index].scrollHeight + 5) + 'px';
}
});
// Hide non-PDF elements in the clone
doc.querySelectorAll('.scc-pdf-hide-in-export').forEach(el => {
el.style.display = 'none';
});
}
});
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({ orientation: 'p', unit: 'px', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
const ratio = canvas.width / pdfWidth;
const scaledHeight = canvas.height / ratio;
let position = 0;
let heightLeft = scaledHeight;
pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, scaledHeight);
heightLeft -= pdfHeight;
while (heightLeft > 0) {
position = heightLeft - scaledHeight;
pdf.addPage();
pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, scaledHeight);
heightLeft -= pdfHeight;
}
pdf.save('coding_challenges_solutions.pdf');
} catch (error) {
console.error("Error during PDF generation:", error);
alert("An error occurred while generating the PDF.");
} finally {
contentToExport.classList.remove('scc-pdf-export-content');
sccPdfBtn.textContent = 'Download Solutions as PDF';
sccPdfBtn.disabled = false;
}
}
// --- Tab Navigation Functions ---
function openTab(evt, tabName) {
if (!sccTabContents.length || !sccTabLinks.length) return;
sccTabContents.forEach(tabcontent => {
tabcontent.style.display = "none";
tabcontent.classList.remove('scc-active');
});
sccTabLinks.forEach(tablink => {
tablink.classList.remove('scc-active');
});
const currentTabContent = document.getElementById(tabName);
if (currentTabContent) {
currentTabContent.style.display = "block";
currentTabContent.classList.add('scc-active');
}
if (evt && evt.currentTarget) {
evt.currentTarget.classList.add('scc-active');
}
sccCurrentTab = sccTabLinks.indexOf(evt.currentTarget);
updateNavButtons();
}
function navigateTabs(n) {
const newIndex = sccCurrentTab + n;
if (newIndex >= 0 && newIndex < sccTabLinks.length) {
sccTabLinks[newIndex].click();
}
}
function updateNavButtons() {
if (sccPrevBtn) sccPrevBtn.disabled = (sccCurrentTab === 0);
if (sccNextBtn) sccNextBtn.disabled = (sccCurrentTab === sccTabLinks.length - 1);
}
// --- Attach to Window Scope for onclick Handlers ---
window.sccOpenTab = openTab;
window.sccNavTab = navigateTabs;
})();
