Skip to content

Commit a987e47

Browse files
Merge pull request #820 from Bivek01/fix/issue-812-ui-ux-bugs
fix: improve track progress visibility and UI interactions
2 parents 02f2274 + d147eba commit a987e47

4 files changed

Lines changed: 82 additions & 124 deletions

File tree

.gitignore

140 Bytes
Binary file not shown.

static/script.js

Lines changed: 42 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -696,9 +696,9 @@ function recordSearch() {
696696

697697
clearAllErrors();
698698

699-
if (skillsTextInput.value.trim()) {
700-
addSkill(skillsTextInput.value);
701-
skillsTextInput.value = "";
699+
if (skillsInput.value.trim()) {
700+
addSkill(skillsInput.value);
701+
skillsInput.value = "";
702702
hideSuggestions();
703703
}
704704

@@ -839,47 +839,16 @@ function recordSearch() {
839839
resultsSection.scrollIntoView({ behavior: "smooth" });
840840
}
841841

842-
//takes the array of projects from the api and draws them on the page as cards
843-
//if array is empty it shows the "no results" message instead
844-
function renderResults(projects, message) {
845-
console.log("Rendering results with projects:", projects);
846-
console.log("Message:", message);
847-
848-
resultsSection.style.display = "block";
849-
resultsLoadingEl.style.display = "none";
850-
// Clear out any cards from a previous search before showing new ones
851-
resultsGrid.innerHTML = "";
852-
recordSearch();
853-
854-
if (!projects || projects.length === 0) {
855-
resultsGrid.style.display = "none";
856-
resultsEmptyEl.style.display = "block";
857-
858-
// Show a friendly custom message when the user selected an interest
859-
var selectedInterest = document.getElementById("interest")?.value;
860-
if (selectedInterest) {
861-
emptyMessageEl.textContent = "No projects are currently available for this interest. Please check back later or try a different area.";
862-
} else if (message) {
863-
emptyMessageEl.textContent = message;
864-
} else {
865-
emptyMessageEl.textContent = "Try adjusting your skills or choosing a different interest area.";
866-
}
867-
868-
// Clear out previous results before rendering new ones
869-
resultsGrid.innerHTML = "";
870-
871-
// If no projects are returned, show the empty state message
872-
if (!projects || projects.length === 0) {
873-
resultsGrid.style.display = "none";
874-
resultsEmptyEl.style.display = "block";
875-
876-
projects.forEach(function (project) {
877-
resultsGrid.appendChild(buildProjectCard(project));
878-
});
842+
function truncate(text, maxLength) {
843+
text = text || "";
844+
return text.length > maxLength ? text.slice(0, maxLength) + "..." : text;
845+
}
879846

880-
recordSearch();
881-
resultsSection.scrollIntoView({ behavior: "smooth" });
882-
return;
847+
function createTag(text, type) {
848+
var span = document.createElement("span");
849+
span.className = "project-tag project-tag--" + normalize(type).replace(/[^a-z0-9_-]/g, "-");
850+
span.textContent = text;
851+
return span;
883852
}
884853

885854
function buildProjectCard(project) {
@@ -1312,33 +1281,38 @@ if (
13121281
fetchBtn.textContent = 'Fetch Skills';
13131282
}
13141283
});
1315-
}
1316-
1317-
/* ---- Scroll-to-top button ---- */
1284+
update();
1285+
})();
13181286

1319-
/* Show the button only when the user has scrolled more than 300px */
1320-
var SCROLL_THRESHOLD = 300;
1287+
(function initScrollSpy() {
1288+
var sections = document.querySelectorAll("section[id], header[id]");
1289+
var navLinks = document.querySelectorAll(".nav-link, .nav-mobile-link");
13211290

1322-
/* Get the button element; guard against pages that do not have it */
1323-
var scrollTopBtn = document.getElementById('scroll-top-btn');
1291+
if (sections.length === 0 || navLinks.length === 0) return;
13241292

1325-
/* Add or remove the .visible class based on scroll position */
1326-
function handleScroll() {
1327-
if (!scrollTopBtn) return;
1328-
if (window.pageYOffset > SCROLL_THRESHOLD) {
1329-
scrollTopBtn.classList.add('visible');
1330-
} else {
1331-
scrollTopBtn.classList.remove('visible');
1332-
}
1333-
}
1293+
var observerOptions = {
1294+
root: null,
1295+
rootMargin: "-20% 0px -70% 0px",
1296+
threshold: 0
1297+
};
13341298

1335-
/* Smooth-scroll to the very top of the page */
1336-
function scrollToTop() {
1337-
window.scrollTo({ top: 0, behavior: 'smooth' });
1338-
}
1299+
var observer = new IntersectionObserver(function (entries) {
1300+
entries.forEach(function (entry) {
1301+
if (entry.isIntersecting) {
1302+
var id = entry.target.getAttribute("id");
1303+
navLinks.forEach(function (link) {
1304+
var href = link.getAttribute("href");
1305+
if (href === "#" + id) {
1306+
link.classList.add("active");
1307+
} else if (href && href.startsWith("#")) {
1308+
link.classList.remove("active");
1309+
}
1310+
});
1311+
}
1312+
});
1313+
}, observerOptions);
13391314

1340-
/* Only wire up listeners if the button exists on this page */
1341-
if (scrollTopBtn) {
1342-
window.addEventListener('scroll', handleScroll);
1343-
scrollTopBtn.addEventListener('click', scrollToTop);
1344-
}
1315+
sections.forEach(function (sec) {
1316+
observer.observe(sec);
1317+
});
1318+
})();

static/style.css

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -662,12 +662,14 @@ html[data-entry-anim="true"] .form-card form > .btn-submit { animat
662662
opacity 0.25s ease;
663663
}
664664

665-
.nav-link:hover {
665+
.nav-link:hover,
666+
.nav-link.active {
666667
color: #ffffff;
667668
text-decoration: none;
668669
}
669670

670-
.nav-link:hover::after {
671+
.nav-link:hover::after,
672+
.nav-link.active::after {
671673
transform: translateX(-50%) scaleX(1);
672674
opacity: 1;
673675
}
@@ -788,12 +790,14 @@ html[data-entry-anim="true"] .form-card form > .btn-submit { animat
788790
opacity 0.25s ease;
789791
}
790792

791-
.nav-mobile-link:hover {
793+
.nav-mobile-link:hover,
794+
.nav-mobile-link.active {
792795
color: #ffffff;
793796
text-decoration: none;
794797
}
795798

796-
.nav-mobile-link:hover::after {
799+
.nav-mobile-link:hover::after,
800+
.nav-mobile-link.active::after {
797801
transform: scaleX(1);
798802
opacity: 1;
799803
}
@@ -3372,16 +3376,19 @@ input[type="text"]:not(.skill-input-wrap input):focus {
33723376
.profile-card,
33733377
.badge-card,
33743378
.achievement-card,
3379+
.history-card,
33753380
.leaderboard-card {
3376-
background: rgba(255, 255, 255, 0.04);
3377-
border: 1px solid rgba(148, 163, 184, 0.12);
3381+
background: var(--surface);
3382+
border: 1px solid var(--border);
33783383
border-radius: 28px;
33793384
padding: 28px;
3385+
box-shadow: var(--shadow-sm);
33803386
}
33813387

33823388
.profile-card-header,
33833389
.badge-card-header,
33843390
.achievement-card-header,
3391+
.history-card-header,
33853392
.leaderboard-card-header {
33863393
display: flex;
33873394
align-items: center;
@@ -3393,19 +3400,21 @@ input[type="text"]:not(.skill-input-wrap input):focus {
33933400
.profile-label {
33943401
display: block;
33953402
margin-bottom: 8px;
3396-
color: rgba(148, 163, 184, 1);
3403+
color: var(--text-body);
33973404
font-size: 0.92rem;
3405+
font-weight: 500;
33983406
}
33993407

34003408
.profile-card h3 {
34013409
font-size: 3rem;
34023410
margin: 0;
3411+
color: var(--text-heading);
34033412
}
34043413

34053414
.progress-meter {
34063415
width: 100%;
34073416
height: 16px;
3408-
background: rgba(148, 163, 184, 0.14);
3417+
background: var(--surface-hover);
34093418
border-radius: 999px;
34103419
overflow: hidden;
34113420
margin-bottom: 20px;
@@ -3419,9 +3428,10 @@ input[type="text"]:not(.skill-input-wrap input):focus {
34193428
width: 0;
34203429
height: 100%;
34213430
background: linear-gradient(120deg, #6366f1, #22c55e);
3422-
color: #fff;
3431+
color: #ffffff;
34233432
font-size: 0.8rem;
34243433
font-weight: 700;
3434+
text-shadow: 0 1px 2px rgba(0,0,0,0.4);
34253435
transition: width 0.4s ease;
34263436
}
34273437

@@ -3443,7 +3453,7 @@ input[type="text"]:not(.skill-input-wrap input):focus {
34433453
justify-content: space-between;
34443454
gap: 12px;
34453455
padding: 14px 0;
3446-
border-bottom: 1px solid rgba(148, 163, 184, 0.08);
3456+
border-bottom: 1px solid var(--border);
34473457
}
34483458

34493459
.progress-stats li:last-child,
@@ -3456,14 +3466,16 @@ input[type="text"]:not(.skill-input-wrap input):focus {
34563466
.progress-stats strong,
34573467
.leaderboard-list span,
34583468
.achievement-item strong {
3459-
color: #e2e8f0;
3469+
color: var(--text-body);
3470+
font-weight: 500;
34603471
}
34613472

34623473
.progress-stats span,
34633474
.leaderboard-list strong,
34643475
.achievement-item span,
34653476
.achievement-item small {
3466-
color: rgba(148, 163, 184, 1);
3477+
color: var(--text-heading);
3478+
font-weight: 700;
34673479
}
34683480

34693481
.progress-badge-grid {
@@ -3478,18 +3490,20 @@ input[type="text"]:not(.skill-input-wrap input):focus {
34783490
gap: 12px;
34793491
padding: 14px 16px;
34803492
border-radius: 18px;
3481-
background: rgba(148, 163, 184, 0.06);
3482-
color: rgba(226, 232, 240, 1);
3493+
background: var(--surface-hover);
3494+
color: var(--text-heading);
3495+
border: 1px solid var(--border);
34833496
transition: transform 0.2s ease, background 0.2s ease;
34843497
}
34853498

34863499
.progress-badge--unlocked {
34873500
background: rgba(34, 197, 94, 0.12);
3488-
color: #d1fae5;
3501+
color: var(--text-heading);
3502+
border-color: rgba(34, 197, 94, 0.3);
34893503
}
34903504

34913505
.progress-badge--locked {
3492-
opacity: 0.6;
3506+
opacity: 0.7;
34933507
}
34943508

34953509
.badge-icon {
@@ -3499,7 +3513,7 @@ input[type="text"]:not(.skill-input-wrap input):focus {
34993513
align-items: center;
35003514
justify-content: center;
35013515
border-radius: 999px;
3502-
background: rgba(148, 163, 184, 0.14);
3516+
background: var(--surface-hover);
35033517
font-size: 0.88rem;
35043518
}
35053519

@@ -3519,7 +3533,7 @@ input[type="text"]:not(.skill-input-wrap input):focus {
35193533
}
35203534

35213535
.achievement-empty {
3522-
color: rgba(148, 163, 184, 1);
3536+
color: var(--text-light);
35233537
padding: 16px 0;
35243538
}
35253539

@@ -3529,17 +3543,19 @@ input[type="text"]:not(.skill-input-wrap input):focus {
35293543
justify-content: center;
35303544
gap: 8px;
35313545
background: transparent;
3532-
border: 1px solid rgba(148, 163, 184, 0.24);
3533-
color: #e2e8f0;
3546+
border: 1px solid var(--border);
3547+
color: var(--text-body);
35343548
border-radius: 999px;
35353549
padding: 12px 18px;
35363550
cursor: pointer;
3537-
transition: background 0.2s ease, border-color 0.2s ease;
3551+
font-weight: 500;
3552+
transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
35383553
}
35393554

35403555
.btn-ghost:hover {
3541-
background: rgba(255, 255, 255, 0.06);
3542-
border-color: rgba(148, 163, 184, 0.4);
3556+
background: var(--surface-hover);
3557+
border-color: var(--text-light);
3558+
color: var(--text-heading);
35433559
}
35443560

35453561
.btn-mark-complete {

templates/index.html

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,39 +1002,7 @@ <h4 class="footer-col-title">About Us</h4>
10021002
<script src="https://unpkg.com/lenis@1.1.13/dist/lenis.min.js"></script>
10031003

10041004
<script src="/static/script.js"></script>
1005-
<script src="/static/bookmarks.js"></script>
1006-
<script>
1007-
(function () {
1008-
const themeToggle = document.getElementById("theme-toggle");
1009-
1010-
if (!themeToggle) return;
1011-
1012-
const savedTheme = localStorage.getItem("theme");
1013-
1014-
if (savedTheme === "dark") {
1015-
document.documentElement.setAttribute("data-theme", "dark");
1016-
themeToggle.textContent = "☀️";
1017-
themeToggle.setAttribute("aria-pressed", "true");
1018-
}
1019-
1020-
themeToggle.addEventListener("click", function () {
1021-
const isDark =
1022-
document.documentElement.getAttribute("data-theme") === "dark";
1023-
1024-
if (isDark) {
1025-
document.documentElement.removeAttribute("data-theme");
1026-
localStorage.setItem("theme", "light");
1027-
themeToggle.textContent = "🌙";
1028-
themeToggle.setAttribute("aria-pressed", "false");
1029-
} else {
1030-
document.documentElement.setAttribute("data-theme", "dark");
1031-
localStorage.setItem("theme", "dark");
1032-
themeToggle.textContent = "☀️";
1033-
themeToggle.setAttribute("aria-pressed", "true");
1034-
}
1035-
});
1036-
})();
1037-
</script>
1005+
10381006
</body>
10391007

10401008
</html>

0 commit comments

Comments
 (0)