From f8555c34942ec37442bb1aa2a519b8bb65b498cb Mon Sep 17 00:00:00 2001 From: Mansoor Khan <22OO1CSO56mansoorkhan@gmail.com> Date: Sun, 10 May 2026 20:28:47 +0530 Subject: [PATCH 1/3] Added search filter for the result --- static/script.js | 45 +++++++++++++++++++++++++++++++++++++++++++- static/style.css | 26 +++++++++++++++++++++++++ templates/index.html | 7 ++++++- 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/static/script.js b/static/script.js index 1ceb1e63..8081a7f2 100644 --- a/static/script.js +++ b/static/script.js @@ -267,10 +267,14 @@ if (isIndexPage) { resultsSection.style.display = "block"; resultsLoadingEl.style.display = "none"; resultsGrid.innerHTML = ""; + + // Store current projects for reference + currentProjects = projects || []; if (!projects || projects.length === 0) { resultsGrid.style.display = "none"; resultsEmptyEl.style.display = "block"; + showSearchInput(false); // Hide search when no results if (message && emptyMessageEl) emptyMessageEl.textContent = message; resultsSection.scrollIntoView({ behavior: "smooth" }); return; @@ -283,6 +287,10 @@ if (isIndexPage) { resultsGrid.appendChild(buildProjectCard(project)); }); + // Show search input and setup filter (only once) + showSearchInput(true); + if (!searchInput) setupFilter(); + resultsSection.scrollIntoView({ behavior: "smooth" }); } @@ -347,6 +355,41 @@ if (isIndexPage) { return text.length > maxLength ? text.slice(0, maxLength) + "..." : text; } + // ---------------------------------------------------------- + // Filter projects based on search input + // ---------------------------------------------------------- + var searchInput = null; + var currentProjects = []; + + function setupFilter() { + searchInput = document.getElementById("results-search"); + if (!searchInput) return; + + searchInput.addEventListener("input", function (e) { + var searchTerm = e.target.value.trim().toLowerCase(); + var cards = resultsGrid.querySelectorAll(".project-card"); + + cards.forEach(function (card) { + var title = card.querySelector(".project-card-title")?.textContent.toLowerCase() || ""; + var desc = card.querySelector(".project-card-desc")?.textContent.toLowerCase() || ""; + + if (searchTerm === "" || title.includes(searchTerm) || desc.includes(searchTerm)) { + card.style.display = ""; + } else { + card.style.display = "none"; + } + }); + }); + } + + function showSearchInput(show) { + var wrap = document.getElementById("results-search-wrap"); + if (wrap) { + wrap.style.display = show ? "block" : "none"; + if (show && searchInput) searchInput.value = ""; + } + } + } // end isIndexPage @@ -416,4 +459,4 @@ if (isDetailPage) { if (evt.key === "Escape") closeCodePanel(); }); -} // end isDetailPage +} // end isDetailPage \ No newline at end of file diff --git a/static/style.css b/static/style.css index 188419b8..2842ef1a 100644 --- a/static/style.css +++ b/static/style.css @@ -1533,3 +1533,29 @@ select:focus { .container { padding: 0 20px; } .section-sub { margin-bottom: 40px; } } +/* ---- Results Search Input --------------------------------- */ +.results-search-wrap { + max-width: 480px; + margin: 0 auto 32px auto; +} + +.results-search-input { + width: 100%; + padding: 12px 18px; + font-family: var(--font-body); + font-size: 0.95rem; + border: 1.5px solid var(--border); + border-radius: var(--r-full); + background: var(--white); + transition: border-color var(--t), box-shadow var(--t); +} + +.results-search-input:focus { + outline: none; + border-color: var(--indigo-500); + box-shadow: 0 0 0 3px rgba(79, 110, 247, 0.12); +} + +.results-search-input::placeholder { + color: var(--gray-400); +} \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index 5338a4a3..e052b0bc 100644 --- a/templates/index.html +++ b/templates/index.html @@ -371,6 +371,11 @@

No Projects Found

+ + +
@@ -441,4 +446,4 @@ - + \ No newline at end of file From d3b56519bafe922017be53d95c34fd02e1538975 Mon Sep 17 00:00:00 2001 From: Mansoor Khan <22OO1CSO56mansoorkhan@gmail.com> Date: Fri, 15 May 2026 11:15:56 +0530 Subject: [PATCH 2/3] Resolve merge conflicts --- static/script.js | 99 ++++++++++++++------------------------------ static/style.css | 13 ++++++ templates/index.html | 19 ++++++--- 3 files changed, 58 insertions(+), 73 deletions(-) diff --git a/static/script.js b/static/script.js index 8bede7fb..72cfb75d 100644 --- a/static/script.js +++ b/static/script.js @@ -356,7 +356,7 @@ if (isIndexPage) { } // ---------------------------------------------------------- - // Filter projects based on search input + // Filter projects based on search input (title, description, AND skills) // ---------------------------------------------------------- var searchInput = null; var currentProjects = []; @@ -370,10 +370,29 @@ if (isIndexPage) { var cards = resultsGrid.querySelectorAll(".project-card"); cards.forEach(function (card) { + // Get title and description var title = card.querySelector(".project-card-title")?.textContent.toLowerCase() || ""; var desc = card.querySelector(".project-card-desc")?.textContent.toLowerCase() || ""; - if (searchTerm === "" || title.includes(searchTerm) || desc.includes(searchTerm)) { + // Get all skill/tag text from project-tag elements + var tags = card.querySelectorAll(".project-tag"); + var tagTexts = ""; + tags.forEach(function(tag) { + tagTexts += tag.textContent.toLowerCase() + " "; + }); + + // Also specifically look for skill tags (project-tag--skill class) + var skillTags = card.querySelectorAll(".project-tag--skill"); + var skillTexts = ""; + skillTags.forEach(function(skill) { + skillTexts += skill.textContent.toLowerCase() + " "; + }); + + // Combine all searchable text + var searchableText = title + " " + desc + " " + tagTexts + " " + skillTexts; + + // Check if search term matches ANY content + if (searchTerm === "" || searchableText.includes(searchTerm)) { card.style.display = ""; } else { card.style.display = "none"; @@ -386,7 +405,16 @@ if (isIndexPage) { var wrap = document.getElementById("results-search-wrap"); if (wrap) { wrap.style.display = show ? "block" : "none"; - if (show && searchInput) searchInput.value = ""; + if (show && searchInput) { + searchInput.value = ""; + // Reset any hidden cards when showing search + if (resultsGrid) { + var cards = resultsGrid.querySelectorAll(".project-card"); + cards.forEach(function(card) { + card.style.display = ""; + }); + } + } } } @@ -459,69 +487,4 @@ if (isDetailPage) { if (evt.key === "Escape") closeCodePanel(); }); - // ---------------------------------------------------------- - // Copy Code button - // ---------------------------------------------------------- - var btnCopyCode = document.getElementById("btn-copy-code"); - var copyToast = document.getElementById("copy-toast"); - var toastTimeout = null; - - function showCopySuccess() { - if (!btnCopyCode) return; - - // Swap icons on the button - var copyIcon = btnCopyCode.querySelector(".copy-icon"); - var checkIcon = btnCopyCode.querySelector(".check-icon"); - var btnLabel = btnCopyCode.querySelector(".copy-btn-label"); - - if (copyIcon) copyIcon.style.display = "none"; - if (checkIcon) checkIcon.style.display = "inline"; - if (btnLabel) btnLabel.textContent = "Copied!"; - btnCopyCode.classList.add("copied"); - btnCopyCode.disabled = true; - - // Show toast - if (copyToast) { - copyToast.classList.add("show"); - } - - // Auto-reset after 2.5 s - clearTimeout(toastTimeout); - toastTimeout = setTimeout(function () { - if (copyIcon) copyIcon.style.display = "inline"; - if (checkIcon) checkIcon.style.display = "none"; - if (btnLabel) btnLabel.textContent = "Copy Code"; - btnCopyCode.classList.remove("copied"); - btnCopyCode.disabled = false; - if (copyToast) copyToast.classList.remove("show"); - }, 2500); - } - - if (btnCopyCode) { - btnCopyCode.addEventListener("click", function () { - var code = codeContentEl ? codeContentEl.textContent : ""; - if (!code || code === "Loading..." || code === "Loading starter code...") return; - - // Use Clipboard API with textarea fallback - if (navigator.clipboard && navigator.clipboard.writeText) { - navigator.clipboard.writeText(code).then(showCopySuccess).catch(function () { - fallbackCopy(code); - }); - } else { - fallbackCopy(code); - } - }); - } - - function fallbackCopy(text) { - var ta = document.createElement("textarea"); - ta.value = text; - ta.style.cssText = "position:fixed;top:-9999px;left:-9999px;opacity:0"; - document.body.appendChild(ta); - ta.focus(); - ta.select(); - try { document.execCommand("copy"); showCopySuccess(); } catch (e) { /* silent fail */ } - document.body.removeChild(ta); - } - } // end isDetailPage \ No newline at end of file diff --git a/static/style.css b/static/style.css index bfaa77df..6cd3b7b3 100644 --- a/static/style.css +++ b/static/style.css @@ -1612,4 +1612,17 @@ select:focus { .results-search-input::placeholder { color: var(--gray-400); +} + +/* ---- Accessibility ----------------------------------------- */ +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; } \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index 5fd2acca..cd7f7340 100644 --- a/templates/index.html +++ b/templates/index.html @@ -260,11 +260,13 @@

Find Your Next Project

id="skills-input" placeholder="Type a skill and press Enter..." autocomplete="off" + aria-required="true" + aria-describedby="skills-hint skills-error" /> - Or click a popular skill below to add it + Or click a popular skill below to add it
@@ -285,7 +287,7 @@

Find Your Next Project

- @@ -298,7 +300,7 @@

Find Your Next Project

- @@ -315,7 +317,7 @@

Find Your Next Project

- @@ -371,7 +373,14 @@

No Projects Found

From d6ef9656657243d98833fc1b8ec247d1be41a2f3 Mon Sep 17 00:00:00 2001 From: Mansoor Khan <22OO1CSO56mansoorkhan@gmail.com> Date: Wed, 20 May 2026 14:32:58 +0530 Subject: [PATCH 3/3] Removed merge conflicts + addded correct feat --- static/script.js | 26 ++---- static/style.css | 101 ++++++++++++++------ templates/index.html | 215 +++++++++++++------------------------------ 3 files changed, 139 insertions(+), 203 deletions(-) diff --git a/static/script.js b/static/script.js index 80d068f4..affa6609 100644 --- a/static/script.js +++ b/static/script.js @@ -603,23 +603,16 @@ if (clearFiltersBtn) { //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"; - resultsGrid.innerHTML = ""; - - // Store current projects for reference - currentProjects = projects || []; + 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 - if (!projects || projects.length === 0) { - resultsGrid.style.display = "none"; - resultsEmptyEl.style.display = "block"; showSearchInput(false); // Hide search when no results if (message && emptyMessageEl) emptyMessageEl.textContent = message; resultsSection.scrollIntoView({ behavior: "smooth" }); @@ -737,15 +730,8 @@ if (clearFiltersBtn) { tagTexts += tag.textContent.toLowerCase() + " "; }); - // Also specifically look for skill tags (project-tag--skill class) - var skillTags = card.querySelectorAll(".project-tag--skill"); - var skillTexts = ""; - skillTags.forEach(function(skill) { - skillTexts += skill.textContent.toLowerCase() + " "; - }); - // Combine all searchable text - var searchableText = title + " " + desc + " " + tagTexts + " " + skillTexts; + var searchableText = title + " " + desc + " " + tagTexts; // Check if search term matches ANY content if (searchTerm === "" || searchableText.includes(searchTerm)) { @@ -1025,4 +1011,4 @@ function scrollToTop() { if (scrollTopBtn) { window.addEventListener('scroll', handleScroll); scrollTopBtn.addEventListener('click', scrollToTop); -} +} \ No newline at end of file diff --git a/static/style.css b/static/style.css index 934f011b..c3a04ff8 100644 --- a/static/style.css +++ b/static/style.css @@ -2563,31 +2563,44 @@ select:focus { margin-bottom: 40px; } } -/* ---- Results Search Input --------------------------------- */ -.results-search-wrap { - max-width: 480px; - margin: 0 auto 32px auto; + +.github-input-reveal input { + border: 1px solid var(--border); + border-radius: var(--r-xs); + font-family: var(--font-body); } -.results-search-input { - width: 100%; - padding: 12px 18px; - font-family: var(--font-body); - font-size: 0.95rem; - border: 1.5px solid var(--border); - border-radius: var(--r-full); - background: var(--white); - transition: border-color var(--t), box-shadow var(--t); +.github-input-reveal input:focus { + border-color: var(--indigo-400); + outline: none; + background: var(--white); } -.results-search-input:focus { - outline: none; - border-color: var(--indigo-500); - box-shadow: 0 0 0 3px rgba(79, 110, 247, 0.12); +#btn-show-github { + border: 1px solid transparent; + transition: all var(--t); + color: var(--indigo-600); + background: var(--indigo-50); } -.results-search-input::placeholder { - color: var(--gray-400); +#btn-show-github:hover { + background: var(--indigo-100); + border-color: rgba(79, 110, 247, 0.2); +} + +#github-modal-overlay.active { + display: flex !important; /* Overrides the 'none' display */ + backdrop-filter: blur(4px); + animation: fadeIn 0.2s ease; +} + +#github-modal-overlay .sidebar-card { + transform: scale(0.9); + transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1); +} + +#github-modal-overlay.active .sidebar-card { + transform: scale(1); } @keyframes fadeIn { @@ -2804,17 +2817,6 @@ select:focus { #scroll-top-btn.visible { display: flex; -/* ---- Accessibility ----------------------------------------- */ -.visually-hidden { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - white-space: nowrap; - border-width: 0; } @@ -2843,4 +2845,43 @@ select:focus { flex: 1; white-space: pre; color: #e6edf3; +} +/* ---- Results Search Input --------------------------------- */ +.results-search-wrap { + max-width: 480px; + margin: 0 auto 32px auto; +} + +.results-search-input { + width: 100%; + padding: 12px 18px; + font-family: var(--font-body); + font-size: 0.95rem; + border: 1.5px solid var(--border); + border-radius: var(--r-full); + background: var(--white); + transition: border-color var(--t), box-shadow var(--t); +} + +.results-search-input:focus { + outline: none; + border-color: var(--indigo-500); + box-shadow: 0 0 0 3px rgba(79, 110, 247, 0.12); +} + +.results-search-input::placeholder { + color: var(--gray-400); +} + +/* ---- Accessibility ----------------------------------------- */ +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; } \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index baba127e..7f9b7c2d 100644 --- a/templates/index.html +++ b/templates/index.html @@ -75,7 +75,6 @@

roadmaps and ready-to-run starter code.

-
Start Finding Projects See How It Works @@ -89,11 +88,6 @@

- - - -

Starter Code Ready @@ -114,12 +108,6 @@

date = datetime.now() with open(DATA_FILE) as f: - def add_expense(category, - amount): - # Save entry to CSV - date = datetime.now() - with open(DATA_FILE) as f: writer.writerow([date, ...])   def monthly_summary(): @@ -133,13 +121,6 @@

- - - - -

7-Step Roadmap @@ -209,46 +190,32 @@

Python - JavaScript - HTML / CSS - Flask - SQL - React - Node.js - pandas - C++ - Java - TypeScript - Go - Rust - C# - Kotlin

@@ -256,7 +223,6 @@

- @@ -276,10 +242,6 @@

Enter Your Skills

- - -
02
@@ -290,10 +252,6 @@

Set Your Preferences

- - -
03
@@ -314,24 +272,12 @@

Everything You Need to Start Building

Every recommendation comes with practical resources — not just a project name.

-
- - - - - - - - -

Personalized Matches

Projects are scored against your exact skills, level, and interest — not pulled from a generic list.

@@ -343,13 +289,6 @@

Personalized Matches

- - - - -

Step-by-Step Roadmaps

Each project includes a numbered roadmap so you always know what to build next, without guessing.

@@ -363,20 +302,9 @@

Step-by-Step Roadmaps

Starter Code Included

-

Download a working template for every project. Skip the blank-page problem and start - building immediately.

- - - - -
-

Starter Code Included

-

Download a working template for every project. Skip the blank-page problem and start building immediately. -

+

Download a working template for every project. Skip the blank-page problem and start building immediately.

Get starter code
-
@@ -413,22 +341,18 @@

Find Your Next Project

- - autocomplete="off" - aria-required="true" - aria-describedby="skills-hint skills-error" - /> + autocomplete="off" />
- Or click a popular skill below to add it + + Add one or more skills you are comfortable with. Example: Python, React, SQL, Git. +
@@ -449,7 +373,6 @@

Find Your Next Project

- @@ -457,7 +380,7 @@

Find Your Next Project

- @@ -479,7 +402,7 @@

Find Your Next Project

- @@ -488,57 +411,57 @@

Find Your Next Project

- - - - Pick the domain you want to explore such as Web Development, Automation, or Games. - -
+ + Pick the domain you want to explore such as Web Development, Automation, or Games. + +
+
-
- +
-
+ + Include coding, debugging, learning, and reviewing time in your estimate. +
- - - -

+ +

- -
- + + - + +
+ - - -
- - - - - + + + + - \ No newline at end of file