From edf736b2e6086d997da8c8d5b75dcc043654ca4f Mon Sep 17 00:00:00 2001 From: shinee Date: Fri, 3 Jul 2026 02:42:29 +0530 Subject: [PATCH 1/2] fix: prevent rank change tooltip from overlapping sticky header --- frontend/styles/main.css | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/styles/main.css b/frontend/styles/main.css index 108c72a1..0ae71419 100644 --- a/frontend/styles/main.css +++ b/frontend/styles/main.css @@ -2861,7 +2861,8 @@ body::-webkit-scrollbar-thumb { .rank-change[data-tooltip]::before { content: attr(data-tooltip); position: absolute; - bottom: 140%; + bottom: 140%; /* Default position */ + top: auto; left: 50%; transform: translateX(-50%); background: var(--bg-raised); @@ -2879,6 +2880,11 @@ body::-webkit-scrollbar-thumb { transition: opacity 0.15s ease-in-out; box-shadow: 0 0 15px rgba(0, 255, 65, 0.2); } +/* Prevent tooltip from overlapping the sticky header */ +.leaderboard-row:nth-child(-n + 3) .rank-change[data-tooltip]::before { + top: 140%; + bottom: auto; +} .rank-change[data-tooltip]:hover::before { opacity: 1; From 028e319fd2661538c28a69e4d3c3477a95da5576 Mon Sep 17 00:00:00 2001 From: shinee Date: Fri, 3 Jul 2026 23:20:36 +0530 Subject: [PATCH 2/2] fix: sync today's solved counts with live LeetCode data --- scripts/fetch-user-info.js | 47 +++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/scripts/fetch-user-info.js b/scripts/fetch-user-info.js index 76af9ca3..a27f390e 100644 --- a/scripts/fetch-user-info.js +++ b/scripts/fetch-user-info.js @@ -1,4 +1,5 @@ async function fetchUserInfo(username) { + let liveSolved = null; const usernameRegex = /^[a-zA-Z0-9_-]+$/; if (!username || !usernameRegex.test(username)) { throw new Error("Invalid username format"); @@ -50,23 +51,47 @@ async function fetchUserInfo(username) { } // 2. Fetch live profile ranking from the wrapper API - const livePromise = fetch(liveApiUrl).then(async (res) => { - if (res.ok) { - const apiData = await res.json(); - ranking = apiData.ranking || 0; - contest = apiData.contest || null; - } else { - throw new Error(`LeetCode API wrapper returned status ${res.status}`); - } - }); + const res = await fetch(liveApiUrl); + + if (!res.ok) { + throw new Error(`LeetCode API wrapper returned status ${res.status}`); + } + + const apiData = await res.json(); + + liveSolved = { + easy: apiData.easySolved, + medium: apiData.mediumSolved, + hard: apiData.hardSolved, + }; - // Wait for the live API task to complete - await livePromise; + ranking = apiData.ranking || 0; + contest = apiData.contest || null; // Ensure history is sorted chronologically // Guard against a corrupted history file (e.g. non-array `history` field) history = Array.isArray(history) ? history : []; history.sort((a, b) => new Date(a.date) - new Date(b.date)); + const today = new Date().toISOString().split("T")[0]; + let latestEntry = null; + + for (let i = history.length - 1; i >= 0; i--) { + const entry = history[i]; + + if ( + typeof entry.date === "string" && + entry.date.startsWith(today) + ) { + latestEntry = entry; + break; + } + } + + if (latestEntry && liveSolved) { + latestEntry.easy = liveSolved.easy; + latestEntry.medium = liveSolved.medium; + latestEntry.hard = liveSolved.hard; + } return { username,