Simple Coding Challenges

Simple Coding Challenges

My Challenge Solutions

No challenges added yet. Go to the Data Configuration tab to add some!

Add a New Challenge

Challenge Database

${c.problem.substring(0, 70)}...

`; 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; })();