From d8898803f6d2a5449b4fca42a50840d7fa2b4c19 Mon Sep 17 00:00:00 2001 From: 2823sanskar Date: Sat, 30 May 2026 11:01:51 +0530 Subject: [PATCH] fix: restore View Code popup and repair broken script.js syntax The View Code button failed because script.js had unclosed braces that prevented the entire file from loading. This adds the missing code renderer, fixes the form submit handler, and styles the starter template as a centered popup modal. --- static/script.js | 93 ++++++++++++++++++++++-------------------- static/style.css | 31 ++++++++------ templates/project.html | 10 ++--- 3 files changed, 73 insertions(+), 61 deletions(-) diff --git a/static/script.js b/static/script.js index f97e5a0d..907e1fcb 100644 --- a/static/script.js +++ b/static/script.js @@ -478,22 +478,20 @@ if (clearFiltersBtn) { // ---------------------------------------------------------- form.addEventListener("submit", function (evt) { - evt.preventDefault(); //stop the browser from reloading the page on form submit - clearAllErrors() - + evt.preventDefault(); + clearAllErrors(); + if (skillsTextInput.value.trim()) { addSkill(skillsTextInput.value); skillsTextInput.value = ""; hideSuggestions(); } - if (!validateForm()) return; //stop - anything missing/invalid + if (!validateForm()) return; setLoadingState(true); - // Allow browser to paint spinner before request starts requestAnimationFrame(function () { - var payload = { skills: skillsHidden.value.trim() || skillsTextInput.value.trim(), level: document.getElementById("level").value, @@ -506,57 +504,44 @@ if (clearFiltersBtn) { headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) }) - .then(function (res) { - return res.json(); - }) + .then(function (res) { return res.json(); }) .then(function (data) { - setLoadingState(false); if (data.error) { var generalErr = document.getElementById("form-error-general"); - - if (generalErr) { - generalErr.textContent = data.error; - } - + if (generalErr) generalErr.textContent = data.error; return; } renderResults(data.projects || [], data.message); }) .catch(function () { - setLoadingState(false); - //combine form values into an object to send to server/api - var payload = { - // Prefer the hidden input value; fall back to raw text box if hidden input is empty - skills: skillsHidden.value.trim() || skillsTextInput.value.trim(), - level: document.getElementById("level").value, - interest: document.getElementById("interest").value, - time: document.getElementById("time").value - }; + var generalErr = document.getElementById("form-error-general"); + if (generalErr) { + generalErr.textContent = "Something went wrong. Please try again."; + } + }); + }); }); - // Manages the loading state of the form and results section(whats visible or not) + // Manages the loading state of the form and results section function setLoadingState(isLoading) { - // Disable the button so the user can't accidentally submit twice submitBtn.disabled = isLoading; submitBtn.setAttribute("aria-busy", isLoading); btnLabel.style.display = isLoading ? "none" : "inline"; btnLoading.style.display = isLoading ? "inline-flex" : "none"; if (isLoading) { - // Show the results section with only the loading indicator visible resultsSection.style.display = "block"; resultsLoadingEl.style.display = "block"; resultsGrid.style.display = "none"; resultsEmptyEl.style.display = "none"; - // Scroll down so the user can see the spinner without manually scrolling resultsSection.scrollIntoView({ behavior: "smooth" }); } else { - resultsLoadingEl.style.display = "none"; - resultsGrid.style.display = "grid"; //switch back to gird layout + resultsLoadingEl.style.display = "none"; + resultsGrid.style.display = "grid"; } } @@ -565,25 +550,15 @@ if (clearFiltersBtn) { // Render result cards // ---------------------------------------------------------- - //takes the array of projects from the api and draws them on the page as cards - //if array is empty it shows the "no results" message instead function renderResults(projects, message) { resultsSection.style.display = "block"; resultsLoadingEl.style.display = "none"; - // Clear out any cards from a previous search before showing new ones resultsGrid.innerHTML = ""; if (!projects || projects.length === 0) { - resultsGrid.style.display = "none"; - resultsEmptyEl.style.display = "block"; resultsGrid.style.display = "none"; resultsEmptyEl.style.display = "block"; - if (message && emptyMessageEl) emptyMessageEl.textContent = message; - if (!projects || projects.length === 0) { //if no projects returned from api, show the "no results" message and hide the grid - resultsGrid.style.display = "none"; - resultsEmptyEl.style.display = "block"; - // Show a friendly custom message when the user selected an interest var selectedInterest = document.getElementById("interest")?.value; if (selectedInterest) { emptyMessageEl.textContent = "No projects are currently available for this interest. Please check back later or try a different area."; @@ -600,7 +575,6 @@ if (clearFiltersBtn) { resultsEmptyEl.style.display = "none"; resultsGrid.style.display = "grid"; - //build a card for each project and add it to the grid projects.forEach(function (project) { resultsGrid.appendChild(buildProjectCard(project)); }); @@ -681,6 +655,30 @@ if (clearFiltersBtn) { } // end isIndexPage +// ============================================================ +// Code viewer helpers (detail page) +// ============================================================ +function renderCodeWithLineNumbers(code) { + var lines = (code || "").split("\n"); + return lines.map(function (line, index) { + var row = document.createElement("div"); + row.className = "code-line"; + + var lineNum = document.createElement("span"); + lineNum.className = "line-number"; + lineNum.textContent = String(index + 1); + + var lineContent = document.createElement("span"); + lineContent.className = "line-content"; + lineContent.textContent = line; + + row.appendChild(lineNum); + row.appendChild(lineContent); + return row; + }); +} + + // ============================================================ // DETAIL PAGE // ============================================================ @@ -726,7 +724,12 @@ if (isDetailPage) { if (codeContentEl) codeContentEl.textContent = "Loading starter code..."; fetch("/project/" + PROJECT_ID + "/code") - .then(function (res) { return res.json(); }) + .then(function (res) { + return res.json().then(function (data) { + if (!res.ok) throw new Error(data.error || "Failed to load starter code."); + return data; + }); + }) .then(function (data) { if (data.error) { if (codeContentEl) codeContentEl.textContent = "Error: " + data.error; @@ -742,9 +745,11 @@ if (isDetailPage) { // Mark as fetched so we don't hit the API again on the next open codeFetched = true; }) - .catch(function () { + .catch(function (err) { if (codeContentEl) { - codeContentEl.textContent = "Could not load starter code. Try downloading it instead."; + codeContentEl.textContent = err && err.message + ? "Error: " + err.message + : "Could not load starter code. Try downloading it instead."; } }); } diff --git a/static/style.css b/static/style.css index b399ee5f..0d3057a1 100644 --- a/static/style.css +++ b/static/style.css @@ -2374,12 +2374,13 @@ select:focus { text-decoration: none; } -/* ---- Code Panel (slide-up) -------------------------------- */ +/* ---- Code Panel (centered popup modal) -------------------- */ .code-panel-overlay { display: none; position: fixed; inset: 0; - background: rgba(10, 15, 80, 0.6); + background: rgba(10, 15, 80, 0.65); + backdrop-filter: blur(4px); z-index: 300; } @@ -2389,22 +2390,27 @@ select:focus { .code-panel { position: fixed; - bottom: 0; - left: 0; - right: 0; - height: 72vh; + top: 50%; + left: 50%; + width: min(920px, calc(100vw - 32px)); + height: min(80vh, 720px); background: #0d1117; - border-radius: var(--r-lg) var(--r-lg) 0 0; - box-shadow: 0 -8px 48px rgba(0, 0, 0, 0.45); + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: var(--r-lg); + box-shadow: 0 24px 80px rgba(0, 0, 0, 0.55); z-index: 301; display: flex; flex-direction: column; - transform: translateY(100%); - transition: transform 0.3s ease; + transform: translate(-50%, -50%) scale(0.94); + opacity: 0; + pointer-events: none; + transition: transform 0.25s ease, opacity 0.25s ease; } .code-panel.active { - transform: translateY(0); + transform: translate(-50%, -50%) scale(1); + opacity: 1; + pointer-events: auto; } .code-panel-header { @@ -2680,7 +2686,8 @@ select:focus { } .code-panel { - height: 82vh; + width: calc(100vw - 24px); + height: min(88vh, 720px); } .footer-inner { diff --git a/templates/project.html b/templates/project.html index 2cc33378..7970993d 100644 --- a/templates/project.html +++ b/templates/project.html @@ -76,7 +76,7 @@

{{ project.title }}

Download Starter Code - + Download @@ -270,9 +270,9 @@