Skip to content

Commit aae2175

Browse files
Merge pull request steam-bell-92#1714 from nishtha-agarwal-211/fix/dashboard-redesign-1505
fix(dashboard): redesign stats dashboard with glassmorphism grid and interactive filtering
2 parents a703ac5 + ff3f41f commit aae2175

3 files changed

Lines changed: 235 additions & 48 deletions

File tree

web-app/css/styles.css

Lines changed: 132 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,48 +1299,149 @@ main>.hero-section:has(.hero-code-snippets) {
12991299
}
13001300

13011301

1302-
/* ── Hero Meta ─────────────────────────────────────────────── */
1303-
.hero-meta {
1302+
/* ── Stats Dashboard ───────────────────────────────────────── */
1303+
.stats-dashboard {
1304+
display: grid;
1305+
grid-template-columns: repeat(6, 1fr);
1306+
gap: 1rem;
1307+
width: 100%;
1308+
max-width: 1200px;
1309+
margin: 2rem auto 0;
1310+
padding: 0 1rem;
1311+
box-sizing: border-box;
1312+
}
1313+
1314+
.stats-card {
13041315
display: flex;
1305-
gap: 0.8rem;
1306-
flex-wrap: wrap;
1316+
flex-direction: column;
1317+
align-items: center;
13071318
justify-content: center;
1308-
font-family: var(--font-mono);
1309-
font-size: 0.78rem;
1310-
color: var(--text-secondary);
1311-
margin: 1.25rem 0 0;
1319+
background: rgba(255, 255, 255, 0.45);
1320+
backdrop-filter: blur(16px);
1321+
-webkit-backdrop-filter: blur(16px);
1322+
border: 1px solid rgba(255, 255, 255, 0.5);
1323+
border-radius: 16px;
1324+
padding: 1.25rem 1rem;
1325+
cursor: pointer;
1326+
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
1327+
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.05);
1328+
outline: none;
1329+
font-family: inherit;
1330+
color: inherit;
1331+
box-sizing: border-box;
13121332
}
13131333

1314-
.hero-meta span {
1315-
padding: 0.6rem 0.95rem;
1316-
border-radius: 12px;
1317-
background: rgba(255, 255, 255, 0.78);
1318-
border: 1px solid rgba(128, 104, 85, 0.08);
1319-
font-size: 0.82rem;
1320-
box-shadow: 0 2px 6px rgba(146, 111, 74, 0.04);
1321-
display: inline-flex;
1322-
align-items: center;
1323-
gap: 0.45rem;
1334+
[data-theme="dark"] .stats-card {
1335+
background: rgba(255, 255, 255, 0.03);
1336+
border: 1px solid rgba(255, 255, 255, 0.08);
1337+
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
13241338
}
13251339

1326-
.hero-meta strong {
1327-
color: var(--text);
1328-
font-weight: 600;
1340+
/* Hover and focus styles */
1341+
.stats-card:hover,
1342+
.stats-card:focus-visible {
1343+
transform: translateY(-5px) scale(1.03);
1344+
background: rgba(255, 255, 255, 0.6);
1345+
border-color: rgba(34, 197, 94, 0.5); /* Glowing green border on hover */
1346+
box-shadow: 0 0 15px rgba(34, 197, 94, 0.3), 0 12px 40px rgba(31, 38, 135, 0.08);
13291347
}
13301348

1331-
.hero-meta span::before {
1332-
content: "";
1333-
width: 4px;
1334-
height: 4px;
1349+
[data-theme="dark"] .stats-card:hover,
1350+
[data-theme="dark"] .stats-card:focus-visible {
1351+
background: rgba(255, 255, 255, 0.07);
1352+
border-color: rgba(74, 222, 128, 0.6); /* Green glowing border in dark mode */
1353+
box-shadow: 0 0 20px rgba(74, 222, 128, 0.3), 0 12px 40px rgba(0, 0, 0, 0.5);
1354+
}
1355+
1356+
/* Active/selected state filter highlight */
1357+
.stats-card.active {
1358+
background: rgba(255, 255, 255, 0.7);
1359+
border-color: rgba(34, 197, 94, 0.8);
1360+
box-shadow: 0 0 20px rgba(34, 197, 94, 0.4), 0 8px 24px rgba(31, 38, 135, 0.06);
1361+
}
1362+
1363+
[data-theme="dark"] .stats-card.active {
1364+
background: rgba(255, 255, 255, 0.09);
1365+
border-color: rgba(74, 222, 128, 0.9);
1366+
box-shadow: 0 0 25px rgba(74, 222, 128, 0.5), 0 8px 24px rgba(0, 0, 0, 0.4);
1367+
}
1368+
1369+
/* Accents and text elements */
1370+
.stats-icon {
1371+
margin-bottom: 0.75rem;
1372+
display: flex;
1373+
align-items: center;
1374+
justify-content: center;
1375+
width: 44px;
1376+
height: 44px;
13351377
border-radius: 50%;
1336-
background: var(--accent);
1337-
opacity: 0.6;
1378+
background: rgba(34, 197, 94, 0.1);
1379+
color: #22c55e;
1380+
transition: transform 0.3s ease;
13381381
}
13391382

1340-
[data-theme="dark"] .hero-meta span {
1341-
background: rgba(255, 255, 255, 0.08);
1342-
border-color: rgba(255, 239, 223, 0.1);
1343-
box-shadow: none;
1383+
[data-theme="dark"] .stats-icon {
1384+
background: rgba(74, 222, 128, 0.15);
1385+
color: #4ade80;
1386+
}
1387+
1388+
.stats-icon svg {
1389+
width: 20px;
1390+
height: 20px;
1391+
stroke-width: 2.25;
1392+
}
1393+
1394+
.stats-card:hover .stats-icon {
1395+
transform: rotate(8deg) scale(1.1);
1396+
}
1397+
1398+
.stats-info {
1399+
display: flex;
1400+
flex-direction: column;
1401+
align-items: center;
1402+
}
1403+
1404+
/* customized green accents for metrics counters */
1405+
.stats-info strong {
1406+
font-size: 1.75rem;
1407+
font-weight: 700;
1408+
line-height: 1.2;
1409+
color: #166534; /* customized dark-green accent */
1410+
transition: all 0.3s ease;
1411+
}
1412+
1413+
[data-theme="dark"] .stats-info strong {
1414+
color: #4ade80; /* customized light-green/neon accent for dark mode */
1415+
}
1416+
1417+
.stats-info span {
1418+
font-size: 0.8rem;
1419+
font-weight: 500;
1420+
color: var(--text-secondary);
1421+
text-transform: uppercase;
1422+
letter-spacing: 0.05em;
1423+
margin-top: 0.25rem;
1424+
text-align: center;
1425+
}
1426+
1427+
@media (max-width: 1024px) {
1428+
.stats-dashboard {
1429+
grid-template-columns: repeat(3, 1fr);
1430+
gap: 1rem;
1431+
}
1432+
}
1433+
1434+
@media (max-width: 640px) {
1435+
.stats-dashboard {
1436+
grid-template-columns: repeat(2, 1fr);
1437+
gap: 0.75rem;
1438+
}
1439+
}
1440+
1441+
@media (max-width: 400px) {
1442+
.stats-dashboard {
1443+
grid-template-columns: 1fr;
1444+
}
13441445
}
13451446

13461447

web-app/index.html

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -237,17 +237,61 @@ <h1 class="hero-title">
237237
</a>
238238
</div>
239239

240-
<div class="hero-meta">
241-
<div>
242-
<span><strong id="heroProjectCount">0</strong> total projects</span>
243-
<span><strong id="heroGameCount">0</strong> games</span>
244-
<span><strong id="heroMathCount">0</strong> maths</span>
245-
<span><strong id="heroUtilityCount">0</strong> utilities</span>
246-
</div>
247-
<div>
248-
<span data-filter="favorites"><strong id="heroFavoriteCount">0</strong>Favorites</span>
249-
<span><strong id="heroViewedCount">0</strong>Recently Viewed</span>
250-
</div>
240+
<div class="stats-dashboard">
241+
<button class="stats-card active" data-filter="all" type="button" aria-label="Show all projects">
242+
<div class="stats-icon">
243+
<svg data-lucide="layers"></svg>
244+
</div>
245+
<div class="stats-info">
246+
<strong id="heroProjectCount">0</strong>
247+
<span>Total Projects</span>
248+
</div>
249+
</button>
250+
<button class="stats-card" data-filter="games" type="button" aria-label="Filter games">
251+
<div class="stats-icon">
252+
<svg data-lucide="gamepad-2"></svg>
253+
</div>
254+
<div class="stats-info">
255+
<strong id="heroGameCount">0</strong>
256+
<span>Games</span>
257+
</div>
258+
</button>
259+
<button class="stats-card" data-filter="math" type="button" aria-label="Filter mathematics projects">
260+
<div class="stats-icon">
261+
<svg data-lucide="calculator"></svg>
262+
</div>
263+
<div class="stats-info">
264+
<strong id="heroMathCount">0</strong>
265+
<span>Maths</span>
266+
</div>
267+
</button>
268+
<button class="stats-card" data-filter="utilities" type="button" aria-label="Filter utilities">
269+
<div class="stats-icon">
270+
<svg data-lucide="wrench"></svg>
271+
</div>
272+
<div class="stats-info">
273+
<strong id="heroUtilityCount">0</strong>
274+
<span>Utilities</span>
275+
</div>
276+
</button>
277+
<button class="stats-card" data-filter="favorites" type="button" aria-label="Filter favorite projects">
278+
<div class="stats-icon">
279+
<svg data-lucide="star"></svg>
280+
</div>
281+
<div class="stats-info">
282+
<strong id="heroFavoriteCount">0</strong>
283+
<span>Favorites</span>
284+
</div>
285+
</button>
286+
<button class="stats-card" data-filter="recent" type="button" aria-label="Scroll to recently viewed projects">
287+
<div class="stats-icon">
288+
<svg data-lucide="history"></svg>
289+
</div>
290+
<div class="stats-info">
291+
<strong id="heroViewedCount">0</strong>
292+
<span>Recently Viewed</span>
293+
</div>
294+
</button>
251295
</div>
252296
</div>
253297
</section>
@@ -1011,7 +1055,7 @@ <h3>${proj.title}</h3>
10111055
animateCounter("statsGames",games);
10121056
animateCounter("statsMath",math);
10131057
animateCounter("statsUtilities",utils);
1014-
const viewed= JSON.parse(localStorage.getItem("recentlyViewed")||"[]");
1058+
const viewed= JSON.parse(localStorage.getItem("recentProjects")||"[]");
10151059
animateCounter("heroViewedCount",viewed.length);
10161060

10171061
console.log(

web-app/js/main.js

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,13 @@ document.addEventListener("DOMContentLoaded", function () {
588588
currentCategory = category;
589589
syncSidebarTabs(category);
590590
syncStickyTabs(category);
591+
592+
// Sync stats cards highlight
593+
var statsCards = document.querySelectorAll(".stats-card");
594+
statsCards.forEach(function (card) {
595+
card.classList.toggle("active", card.getAttribute("data-filter") === category);
596+
});
597+
591598
var visibleCount = 0;
592599
var favorites = JSON.parse(localStorage.getItem("favorites") || "[]");
593600
projectCards.forEach(function (card) {
@@ -647,6 +654,10 @@ document.addEventListener("DOMContentLoaded", function () {
647654
function showPlaygroundSection() {
648655
playgroundActive = true;
649656
syncStickyTabs("playground");
657+
var statsCards = document.querySelectorAll(".stats-card");
658+
statsCards.forEach(function (card) {
659+
card.classList.remove("active");
660+
});
650661
if (projectsSection) projectsSection.style.display = "none";
651662
if (playgroundSection) {
652663
playgroundSection.style.display = "";
@@ -766,6 +777,35 @@ document.addEventListener("DOMContentLoaded", function () {
766777
});
767778
});
768779

780+
/* ── Stats Cards ──────────────────────────────────────────── */
781+
var statsCards = document.querySelectorAll(".stats-card");
782+
statsCards.forEach(function (card) {
783+
card.addEventListener("click", function () {
784+
var category = card.getAttribute("data-filter");
785+
786+
// Update active highlight class on stats cards
787+
statsCards.forEach(function (c) {
788+
c.classList.toggle("active", c === card);
789+
});
790+
791+
if (category === "recent") {
792+
var section = document.getElementById("recentlyViewedSection");
793+
if (section) {
794+
section.scrollIntoView({ behavior: "smooth", block: "start" });
795+
}
796+
} else {
797+
showProjectsSection();
798+
applyCategoryFilter(category);
799+
if (projectsSection) {
800+
projectsSection.scrollIntoView({
801+
behavior: "smooth",
802+
block: "start",
803+
});
804+
}
805+
}
806+
});
807+
});
808+
769809
/* ── Sticky Filter Bar Visibility ─────────────────────────── */
770810
if (stickyFilterBar && heroSection) {
771811
var heroObserver = new IntersectionObserver(
@@ -1793,11 +1833,13 @@ card.appendChild(badge);
17931833
const historyBadge =
17941834
document.getElementById("historyCountBadge");
17951835

1796-
if(historyBadge){
1797-
1798-
historyBadge.textContent=`(${recent.length})`;
1799-
1800-
}
1836+
if(historyBadge){
1837+
historyBadge.textContent=`(${recent.length})`;
1838+
}
1839+
const heroViewedCount = document.getElementById("heroViewedCount");
1840+
if (heroViewedCount) {
1841+
heroViewedCount.textContent = String(recent.length);
1842+
}
18011843
console.log("[DEBUG] recentProjects array:", recent); if (recent.length === 0) {
18021844
section.style.display = "none";
18031845
return;

0 commit comments

Comments
 (0)