From 5ac25ff77d23e8ff72906ec2070aaf5c22a1cdba Mon Sep 17 00:00:00 2001 From: Ankush Date: Wed, 22 Jul 2026 18:27:14 +0530 Subject: [PATCH 1/5] fix: language mapping and add try/catch (#19) --- script.js | 110 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 35 deletions(-) diff --git a/script.js b/script.js index fb61c9f..2a2948c 100644 --- a/script.js +++ b/script.js @@ -5,23 +5,33 @@ const repoList = document.querySelector('.repo-list'); const reposSection = document.querySelector('.repos'); const filterInput = document.querySelector('.filter-repos'); +let totalStars = 0; + // get information from github profile const getProfile = async () => { - const res = await fetch( - `https://api.github.com/users/${username}` - // { - // headers: { - // Accept: 'application/vnd.github+json', - // Authorization: 'token your-personal-access-token-here' - // } - // } - ); - const profile = await res.json(); - displayProfile(profile); + try { + const res = await fetch( + `https://api.github.com/users/${username}` + // { + // headers: { + // Accept: 'application/vnd.github+json', + // Authorization: 'token your-personal-access-token-here' + // } + // } + ); + if (!res.ok) { + throw new Error(`GitHub API error: ${res.status} ${res.statusText}`); + } + const profile = await res.json(); + displayProfile(profile); + } catch (err) { + console.error('Failed to load profile:', err); + const userInfo = document.querySelector('.user-info'); + if (userInfo) { + userInfo.innerHTML = `

Failed to load profile. ${err.message}

`; + } + } }; -getProfile(); - -let totalStars = 0; // display information from github profile const displayProfile = (profile) => { @@ -50,23 +60,38 @@ const displayProfile = (profile) => { // get list of user's public repos const getRepos = async () => { let repos = []; - let res; - for (let i = 1; i <= maxPages; i++) { - res = await fetch( - `https://api.github.com/users/${username}/repos?&sort=pushed&per_page=100&page=${i}` - // { - // headers: { - // Accept: 'application/vnd.github+json', - // Authorization: - // 'token your-personal-access-token-here' - // } - // } - ); - let data = await res.json(); - if (Array.isArray(data)) { - repos = repos.concat(data); + try { + for (let i = 1; i <= maxPages; i++) { + const res = await fetch( + `https://api.github.com/users/${username}/repos?&sort=pushed&per_page=100&page=${i}` + // { + // headers: { + // Accept: 'application/vnd.github+json', + // Authorization: + // 'token your-personal-access-token-here' + // } + // } + ); + if (!res.ok) { + throw new Error(`GitHub API error: ${res.status} ${res.statusText}`); + } + const data = await res.json(); + if (Array.isArray(data)) { + repos = repos.concat(data); + // stop early if this page wasn't full - no more pages to fetch + if (data.length < 100) { + break; + } + } else { + break; + } } + } catch (err) { + console.error('Failed to load repos:', err); + repoList.innerHTML = `

Failed to load repositories. ${err.message}

`; + return; } + repos.sort((a, b) => b.forks_count - a.forks_count); repos.sort((a, b) => b.stargazers_count - a.stargazers_count); @@ -81,7 +106,13 @@ const getRepos = async () => { displayRepos(repos); }; -getRepos(); + +// Fetch repos first so star totals are ready before/alongside the profile render, +// then fetch the profile. Both still run, but this avoids the profile card +// briefly showing a stale "0" for stars in the common case. +(async () => { + await Promise.all([getRepos(), getProfile()]); +})(); // display list of all user's public repos const displayRepos = (repos) => { @@ -103,9 +134,17 @@ const displayRepos = (repos) => { const starsHtml = repo.stargazers_count > 0 ? `⭐ ${repo.stargazers_count}` : ''; - const langHtml = repo.language - ? `${devicons[repo.language]}` - : ''; + + // Guard against languages missing from the devicons map so we never + // render the literal string "undefined" as a badge. + let langHtml = ''; + if (repo.language) { + const icon = devicons[repo.language]; + langHtml = icon + ? `${icon}` + : `${repo.language}`; + } + const forksHtml = repo.forks_count > 0 ? `${devicons['Git']} ${repo.forks_count}` : ''; @@ -200,7 +239,7 @@ const devicons = { Matlab: ' Matlab', Nim: ' Nim', Nix: ' Nix', - ObjectiveC: ' ObjectiveC', + 'Objective-C': ' Objective-C', OCaml: ' OCaml', Perl: ' Perl', PHP: ' PHP', @@ -212,6 +251,7 @@ const devicons = { Ruby: ' Ruby', Rust: ' Rust', Sass: ' Sass', + SCSS: ' SCSS', Scala: ' Scala', Shell: ' Shell', Solidity: ' Solidity', @@ -220,7 +260,7 @@ const devicons = { Swift: ' Swift', Terraform: ' Terraform', TypeScript: ' TypeScript', - 'Vim Script': ' Vim Script', + 'Vim script': ' Vim Script', Vue: ' Vue' }; From 24666191d6382b39295d50c59ad26beabc7b2891 Mon Sep 17 00:00:00 2001 From: Abhishek Keshri <25423853+2KAbhishek@users.noreply.github.com> Date: Wed, 22 Jul 2026 18:36:40 +0530 Subject: [PATCH 2/5] fix: resolve profile star-count race condition, null values, and clean up comments --- script.js | 186 +++++++++++++++++++++++++----------------------------- 1 file changed, 87 insertions(+), 99 deletions(-) diff --git a/script.js b/script.js index 2a2948c..f5549ee 100644 --- a/script.js +++ b/script.js @@ -2,119 +2,76 @@ const username = '2KAbhishek'; const maxPages = 3; const hideForks = true; const repoList = document.querySelector('.repo-list'); -const reposSection = document.querySelector('.repos'); const filterInput = document.querySelector('.filter-repos'); -let totalStars = 0; - -// get information from github profile -const getProfile = async () => { - try { - const res = await fetch( - `https://api.github.com/users/${username}` - // { - // headers: { - // Accept: 'application/vnd.github+json', - // Authorization: 'token your-personal-access-token-here' - // } - // } - ); - if (!res.ok) { - throw new Error(`GitHub API error: ${res.status} ${res.statusText}`); - } - const profile = await res.json(); - displayProfile(profile); - } catch (err) { - console.error('Failed to load profile:', err); - const userInfo = document.querySelector('.user-info'); - if (userInfo) { - userInfo.innerHTML = `

Failed to load profile. ${err.message}

`; +const fetchProfile = async () => { + const res = await fetch(`https://api.github.com/users/${username}`); + if (!res.ok) { + if (res.status === 403) { + throw new Error('GitHub API rate limit exceeded. Please try again later.'); } + throw new Error(`GitHub API error: ${res.status} ${res.statusText}`); } + return res.json(); }; -// display information from github profile -const displayProfile = (profile) => { +const displayProfile = (profile, totalStars) => { const userInfo = document.querySelector('.user-info'); + if (!userInfo) return; + + const blogUrl = profile.blog + ? (profile.blog.startsWith('http') ? profile.blog : `https://${profile.blog}`) + : `https://github.com/${profile.login}`; + + const companyHtml = profile.company ? `Work: ${profile.company}` : ''; + const locationHtml = profile.location ? `Location: ${profile.location}` : ''; + const extraInfoHtml = (companyHtml || locationHtml) + ? `

${companyHtml}${companyHtml && locationHtml ? '  |  ' : ''}${locationHtml}

` + : ''; + userInfo.innerHTML = `
- user avatar + user avatar
-

${profile.name} - ${profile.login}

-

${profile.bio}

+

${profile.name || profile.login}

+ ${profile.bio ? `

${profile.bio}

` : ''}

- Stars: ${totalStars} - Followers: ${profile.followers} - Repos: ${profile.public_repos} - Gists: ${profile.public_gists} -

-

- Work: ${profile.company} - Location: ${profile.location} + Stars: ${totalStars !== null ? totalStars : '--'} + Followers: ${profile.followers ?? 0} + Repos: ${profile.public_repos ?? 0} + Gists: ${profile.public_gists ?? 0}

+ ${extraInfoHtml}
`; }; -// get list of user's public repos -const getRepos = async () => { +const fetchRepos = async () => { let repos = []; - try { - for (let i = 1; i <= maxPages; i++) { - const res = await fetch( - `https://api.github.com/users/${username}/repos?&sort=pushed&per_page=100&page=${i}` - // { - // headers: { - // Accept: 'application/vnd.github+json', - // Authorization: - // 'token your-personal-access-token-here' - // } - // } - ); - if (!res.ok) { - throw new Error(`GitHub API error: ${res.status} ${res.statusText}`); + for (let i = 1; i <= maxPages; i++) { + const res = await fetch( + `https://api.github.com/users/${username}/repos?&sort=pushed&per_page=100&page=${i}` + ); + if (!res.ok) { + if (res.status === 403) { + throw new Error('GitHub API rate limit exceeded. Please try again later.'); } - const data = await res.json(); - if (Array.isArray(data)) { - repos = repos.concat(data); - // stop early if this page wasn't full - no more pages to fetch - if (data.length < 100) { - break; - } - } else { + throw new Error(`GitHub API error: ${res.status} ${res.statusText}`); + } + const data = await res.json(); + if (Array.isArray(data)) { + repos = repos.concat(data); + if (data.length < 100) { break; } + } else { + break; } - } catch (err) { - console.error('Failed to load repos:', err); - repoList.innerHTML = `

Failed to load repositories. ${err.message}

`; - return; - } - - repos.sort((a, b) => b.forks_count - a.forks_count); - repos.sort((a, b) => b.stargazers_count - a.stargazers_count); - - totalStars = repos - .filter((repo) => repo && !repo.fork) - .reduce((sum, repo) => sum + (repo.stargazers_count || 0), 0); - - const totalStarsElement = document.querySelector('.total-stars'); - if (totalStarsElement) { - totalStarsElement.textContent = totalStars; } - - displayRepos(repos); + return repos; }; -// Fetch repos first so star totals are ready before/alongside the profile render, -// then fetch the profile. Both still run, but this avoids the profile card -// briefly showing a stale "0" for stars in the common case. -(async () => { - await Promise.all([getRepos(), getProfile()]); -})(); - -// display list of all user's public repos const displayRepos = (repos) => { const userHome = `https://github.com/${username}`; filterInput.classList.remove('hide'); @@ -124,7 +81,7 @@ const displayRepos = (repos) => { continue; } - const langUrl = `${userHome}?tab=repositories&q=&language=${repo.language}`; + const langUrl = `${userHome}?tab=repositories&q=&language=${encodeURIComponent(repo.language || '')}`; const starsUrl = `${userHome}/${repo.name}/stargazers`; const forksUrl = `${userHome}/${repo.name}/network/members`; @@ -135,8 +92,6 @@ const displayRepos = (repos) => { ? `⭐ ${repo.stargazers_count}` : ''; - // Guard against languages missing from the devicons map so we never - // render the literal string "undefined" as a badge. let langHtml = ''; if (repo.language) { const icon = devicons[repo.language]; @@ -153,18 +108,18 @@ const displayRepos = (repos) => { ? `
${starsHtml}${langHtml}${forksHtml}
` : ''; - const homepageHtml = repo.homepage && repo.homepage !== '' - ? `${devicons['Chrome']} Live` + const homepageHtml = repo.homepage + ? `${devicons['Chrome']} Live` : ''; listItem.innerHTML = `
-

${repo.name}

- ${repo.description || 'No description provided.'} +

${repo.name}

+ ${repo.description || 'No description provided.'}
${statsHtml}
- ${devicons['Github']} Code + ${devicons['Github']} Code ${homepageHtml}
`; @@ -173,7 +128,42 @@ const displayRepos = (repos) => { } }; -// dynamic search +(async () => { + const profilePromise = fetchProfile().catch((err) => { + console.error('Failed to load profile:', err); + const userInfo = document.querySelector('.user-info'); + if (userInfo) { + userInfo.innerHTML = `

Failed to load profile: ${err.message}

`; + } + return null; + }); + + const reposPromise = fetchRepos().catch((err) => { + console.error('Failed to load repos:', err); + repoList.innerHTML = `

Failed to load repositories: ${err.message}

`; + return null; + }); + + const [profileData, reposData] = await Promise.all([profilePromise, reposPromise]); + + let totalStars = null; + + if (reposData) { + reposData.sort((a, b) => b.forks_count - a.forks_count); + reposData.sort((a, b) => b.stargazers_count - a.stargazers_count); + + totalStars = reposData + .filter((repo) => repo && !repo.fork) + .reduce((sum, repo) => sum + (repo.stargazers_count || 0), 0); + + displayRepos(reposData); + } + + if (profileData) { + displayProfile(profileData, totalStars); + } +})(); + filterInput.addEventListener('input', (e) => { const search = e.target.value; const repos = document.querySelectorAll('.repo'); @@ -205,7 +195,6 @@ filterInput.addEventListener('input', (e) => { } }); -// for programming language icons const devicons = { Git: '', Github: '', @@ -264,7 +253,6 @@ const devicons = { Vue: ' Vue' }; -// Keyboard shortcuts document.addEventListener('keydown', (e) => { if (e.key === '/' && document.activeElement !== filterInput) { e.preventDefault(); From ac9fef3b73a126d73ce52ba395a8758a82de6b44 Mon Sep 17 00:00:00 2001 From: Abhishek Keshri <25423853+2KAbhishek@users.noreply.github.com> Date: Wed, 22 Jul 2026 18:46:54 +0530 Subject: [PATCH 3/5] fix: increase header section width --- style.css | 429 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 221 insertions(+), 208 deletions(-) diff --git a/style.css b/style.css index bf9ab6d..bce82e4 100644 --- a/style.css +++ b/style.css @@ -1,340 +1,353 @@ @media (prefers-color-scheme: light) { - :root { - --text: #151515; - --accent: #1688f0; - --bg-main: #ffffff; - --bg-section: #f0f0f0; - --bg-card: #f5f5f5; - } + :root { + --text: #151515; + --accent: #1688f0; + --bg-main: #ffffff; + --bg-section: #f0f0f0; + --bg-card: #f5f5f5; + } } @media (prefers-color-scheme: dark) { - :root { - --text: #dedede; - --accent: #1688f0; - --bg-main: #000000; - --bg-section: #000000; - --bg-card: #000000; - } + :root { + --text: #dedede; + --accent: #1688f0; + --bg-main: #000000; + --bg-section: #000000; + --bg-card: #000000; + } } * { - box-sizing: border-box; + box-sizing: border-box; } body { - display: flex; - align-items: center; - justify-content: center; - margin: 0; - font-family: 'Inter', sans-serif; - background-color: var(--bg-main); - color: var(--text); - font-size: 14px; -} - -h1, h2, h3, .repo-name { - font-family: 'Inter', sans-serif; + display: flex; + align-items: center; + justify-content: center; + margin: 0; + font-family: "Inter", sans-serif; + background-color: var(--bg-main); + color: var(--text); + font-size: 14px; +} + +h1, +h2, +h3, +.repo-name { + font-family: "Inter", sans-serif; } .container { - display: flex; - justify-content: center; - flex-direction: row; - flex-wrap: wrap; - align-items: center; - width: 90%; - max-width: 1280px; + display: flex; + justify-content: center; + flex-direction: row; + flex-wrap: wrap; + align-items: center; + width: 90%; + max-width: 1280px; } .intro { - width: 100%; + width: 100%; } h4 { - width: 100%; - text-align: center; + width: 100%; + text-align: center; } .hide { - /* '!important' is to make sure that when we add the class using JS, it takes precendence */ - display: none !important; + /* '!important' is to make sure that when we add the class using JS, it takes precendence */ + display: none !important; } h1 { - background: linear-gradient(135deg, var(--accent), #796bdc); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - margin-bottom: 4px; - font-weight: 800; - font-size: 2.8em; - text-align: center; - width: 100%; + background: linear-gradient(135deg, var(--accent), #796bdc); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + margin-bottom: 4px; + font-weight: 800; + font-size: 2.8em; + text-align: center; + width: 100%; } small { - width: 100%; - text-align: center; - display: block; - margin-bottom: 20px; + width: 100%; + text-align: center; + display: block; + margin-bottom: 20px; } h2 { - width: 100%; - color: var(--text); - margin: 0; + width: 100%; + color: var(--text); + margin: 0; } img { - border: 2px solid var(--accent); - box-shadow: - 0 0px 6px var(--accent), - 0 0px 6px var(--accent); - max-width: 100%; - height: auto; + border: 2px solid var(--accent); + box-shadow: + 0 0px 6px var(--accent), + 0 0px 6px var(--accent); + max-width: 100%; + height: auto; } a { - color: var(--accent); - text-decoration: none; + color: var(--accent); + text-decoration: none; } a:hover { - color: var(--text); + color: var(--text); } .github-img { - width: 45px; - margin-right: 8px; + width: 45px; + margin-right: 8px; } ul { - list-style: none; - padding: 0; + list-style: none; + padding: 0; } .user-info { - display: flex; - flex-wrap: wrap; - justify-content: center; - background-color: var(--bg-card); - color: var(--text); - font-size: 16px; - padding: 1em; - border-top-left-radius: 20px; - border-top-right-radius: 20px; + display: flex; + flex-wrap: wrap; + justify-content: center; + background-color: var(--bg-card); + color: var(--text); + font-size: 16px; + padding: 1em; + border-top-left-radius: 20px; + border-top-right-radius: 20px; } .user-info figure { - width: 90%; - max-width: 200px; + width: 90%; + max-width: 200px; } .user-info img { - border-radius: 100%; + border-radius: 100%; } .user-info div { - display: flex; - text-align: center; - flex-wrap: wrap; - align-items: center; - width: 100%; - padding-left: 5%; + display: flex; + text-align: center; + flex-wrap: wrap; + align-items: center; + width: 100%; + padding-left: 5%; } .user-info div p { - width: 100%; - margin: 0; - padding: 0; - border-bottom: 1px solid var(--text); - padding-bottom: 18px; + width: 100%; + margin: 0; + padding: 0; + border-bottom: 1px solid var(--text); + padding-bottom: 18px; } .filter-repos, input { - background: var(--bg-card); - width: 50%; - border-radius: 20px; - min-width: 300px; - margin-top: 1em; - padding: 1em; - margin-bottom: 1em; - border: 2px solid var(--accent); - color: var(--text); - text-align: center; + background: var(--bg-card); + width: 50%; + border-radius: 20px; + min-width: 300px; + margin-top: 1em; + padding: 1em; + margin-bottom: 1em; + border: 2px solid var(--accent); + color: var(--text); + text-align: center; } .repos { - display: flex; - flex-wrap: wrap; - justify-content: center; - background-color: var(--bg-section); - margin-top: 0; - padding: 2em; - border-bottom-left-radius: 20px; - border-bottom-right-radius: 20px; - margin-bottom: 4em; - width: 100%; + display: flex; + flex-wrap: wrap; + justify-content: center; + background-color: var(--bg-section); + margin-top: 0; + padding: 2em; + border-bottom-left-radius: 20px; + border-bottom-right-radius: 20px; + margin-bottom: 4em; + width: 100%; } h3 { - margin: 4px; - width: 100%; - text-align: center; - color: var(--accent); + margin: 4px; + width: 100%; + text-align: center; + color: var(--accent); } .repo-list { - width: 100%; - display: grid; - grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); - gap: 1.5em; - margin-top: 1em; + width: 100%; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 1.5em; + margin-top: 1em; } .repo-list li { - min-height: 200px; - border-radius: 10px; - border: 2px solid var(--accent); - padding: 1.25em; - text-align: center; - background-color: var(--bg-card); - transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease; - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - gap: 0.75em; + min-height: 200px; + border-radius: 10px; + border: 2px solid var(--accent); + padding: 1.25em; + text-align: center; + background-color: var(--bg-card); + transition: + transform 0.2s ease, + box-shadow 0.2s ease, + background-color 0.2s ease; + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + gap: 0.75em; } .no-results { - grid-column: 1 / -1; - width: 100%; - text-align: center; - font-size: 1.2em; - margin-top: 2em; - color: var(--text); + grid-column: 1 / -1; + width: 100%; + text-align: center; + font-size: 1.2em; + margin-top: 2em; + color: var(--text); } .repo-list li:hover { - background-color: var(--bg-main); - box-shadow: - 0 8px 16px var(--accent), - 0 8px 16px var(--accent); - transform: translateY(-4px); + background-color: var(--bg-main); + box-shadow: + 0 8px 16px var(--accent), + 0 8px 16px var(--accent); + transform: translateY(-4px); } .link-btn { - display: inline-block; - margin: 0 0.25em; - padding: 8px 16px; - background: var(--bg-main); - border-radius: 10px; - border: 3px solid var(--accent); - color: var(--text); - transition: transform 0.2s ease, background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease; + display: inline-block; + margin: 0 0.25em; + padding: 8px 16px; + background: var(--bg-main); + border-radius: 10px; + border: 3px solid var(--accent); + color: var(--text); + transition: + transform 0.2s ease, + background-color 0.2s ease, + border-color 0.2s ease, + color 0.2s ease; } .link-btn:hover { - background: var(--accent); - border: 3px solid var(--text); - color: var(--bg-main); - transform: scale(1.05); + background: var(--accent); + border: 3px solid var(--text); + color: var(--bg-main); + transform: scale(1.05); } .link-btn i { - color: var(--accent); - transition: color 0.2s ease; + color: var(--accent); + transition: color 0.2s ease; } .link-btn:hover i { - color: var(--bg-main); + color: var(--bg-main); } .repo-list p { - padding: 0.5em; - margin: 0.5em 0; + padding: 0.5em; + margin: 0.5em 0; } @media (min-width: 700px) { - .user-info div { - width: 45%; - text-align: left; - } + .user-info div { + flex: 0.7; + text-align: left; + } } @media (max-width: 700px) { - .user-info div p { - margin: 10px; - } + .user-info div p { + margin: 10px; + } } .repo-name { - font-size: 1.75em; + font-size: 1.75em; } .repo-description { - font-size: 0.95em; - opacity: 0.8; - line-height: 1.5; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - overflow: hidden; - text-overflow: ellipsis; - margin-bottom: 0.5em; - height: 3em; + font-size: 0.95em; + opacity: 0.8; + line-height: 1.5; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis; + margin-bottom: 0.5em; + height: 3em; } .repo-header { - width: 100%; - display: flex; - flex-direction: column; - align-items: center; - gap: 0.5em; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5em; } .repo-stats { - width: 100%; - display: flex; - flex-wrap: wrap; - justify-content: center; - gap: 0.25em; - margin: 0.5em 0; + width: 100%; + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 0.25em; + margin: 0.5em 0; } .repo-actions { - width: 100%; - display: flex; - justify-content: center; - gap: 0.5em; - margin-top: auto; + width: 100%; + display: flex; + justify-content: center; + gap: 0.5em; + margin-top: auto; } span { - margin: 0 0.5em; + margin: 0 0.5em; } .repo-badge { - display: inline-flex; - align-items: center; - padding: 6px 12px; - border-radius: 20px; - background-color: var(--bg-section); - font-size: 0.9em; - border: 1px solid var(--accent); - color: var(--text); - margin: 0.25em !important; - transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease; + display: inline-flex; + align-items: center; + padding: 6px 12px; + border-radius: 20px; + background-color: var(--bg-section); + font-size: 0.9em; + border: 1px solid var(--accent); + color: var(--text); + margin: 0.25em !important; + transition: + background-color 0.2s ease, + border-color 0.2s ease, + color 0.2s ease; } .repo-badge:hover { - background-color: var(--accent); - color: var(--bg-main); - border-color: var(--text); + background-color: var(--accent); + color: var(--bg-main); + border-color: var(--text); } .repo-badge i { - margin-right: 4px; + margin-right: 4px; } From badf577a1c862c195faf31ccad259e381ca0a923 Mon Sep 17 00:00:00 2001 From: Abhishek Keshri <25423853+2KAbhishek@users.noreply.github.com> Date: Wed, 22 Jul 2026 18:53:59 +0530 Subject: [PATCH 4/5] fix: add total forks, link profile stats, remove subtitle, and adjust spacing --- index.html | 1 - script.js | 27 ++++++++++++++++++++------- style.css | 7 ------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/index.html b/index.html index 5985d0e..b00a7d9 100644 --- a/index.html +++ b/index.html @@ -26,7 +26,6 @@

All Of My Projects

- Some useful, some stupid, all fun!
diff --git a/script.js b/script.js index f5549ee..db3cd5d 100644 --- a/script.js +++ b/script.js @@ -15,13 +15,14 @@ const fetchProfile = async () => { return res.json(); }; -const displayProfile = (profile, totalStars) => { +const displayProfile = (profile, totalStars, totalForks) => { const userInfo = document.querySelector('.user-info'); if (!userInfo) return; + const userHome = `https://github.com/${profile.login}`; const blogUrl = profile.blog ? (profile.blog.startsWith('http') ? profile.blog : `https://${profile.blog}`) - : `https://github.com/${profile.login}`; + : userHome; const companyHtml = profile.company ? `Work: ${profile.company}` : ''; const locationHtml = profile.location ? `Location: ${profile.location}` : ''; @@ -29,6 +30,12 @@ const displayProfile = (profile, totalStars) => { ? `

${companyHtml}${companyHtml && locationHtml ? '  |  ' : ''}${locationHtml}

` : ''; + const starsText = `${totalStars !== null ? totalStars : '--'}`; + const forksText = `${totalForks !== null ? totalForks : '--'}`; + const followersLink = `${profile.followers ?? 0}`; + const reposLink = `${profile.public_repos ?? 0}`; + const gistsLink = `${profile.public_gists ?? 0}`; + userInfo.innerHTML = `
user avatar @@ -37,10 +44,11 @@ const displayProfile = (profile, totalStars) => {

${profile.name || profile.login}

${profile.bio ? `

${profile.bio}

` : ''}

- Stars: ${totalStars !== null ? totalStars : '--'} - Followers: ${profile.followers ?? 0} - Repos: ${profile.public_repos ?? 0} - Gists: ${profile.public_gists ?? 0} + Stars: ${starsText}  |  + Forks: ${forksText}  |  + Followers: ${followersLink}  |  + Repos: ${reposLink}  |  + Gists: ${gistsLink}

${extraInfoHtml} @@ -147,6 +155,7 @@ const displayRepos = (repos) => { const [profileData, reposData] = await Promise.all([profilePromise, reposPromise]); let totalStars = null; + let totalForks = null; if (reposData) { reposData.sort((a, b) => b.forks_count - a.forks_count); @@ -156,11 +165,15 @@ const displayRepos = (repos) => { .filter((repo) => repo && !repo.fork) .reduce((sum, repo) => sum + (repo.stargazers_count || 0), 0); + totalForks = reposData + .filter((repo) => repo && !repo.fork) + .reduce((sum, repo) => sum + (repo.forks_count || 0), 0); + displayRepos(reposData); } if (profileData) { - displayProfile(profileData, totalStars); + displayProfile(profileData, totalStars, totalForks); } })(); diff --git a/style.css b/style.css index bce82e4..eacd2ab 100644 --- a/style.css +++ b/style.css @@ -75,13 +75,6 @@ h1 { width: 100%; } -small { - width: 100%; - text-align: center; - display: block; - margin-bottom: 20px; -} - h2 { width: 100%; color: var(--text); From 0186db75a31c215e8fc98d0e0bf9270ae1b32774 Mon Sep 17 00:00:00 2001 From: Abhishek Keshri <25423853+2KAbhishek@users.noreply.github.com> Date: Wed, 22 Jul 2026 18:56:12 +0530 Subject: [PATCH 5/5] fix: unify profile stat colors and show username in parentheses --- script.js | 4 +++- style.css | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/script.js b/script.js index db3cd5d..f23401a 100644 --- a/script.js +++ b/script.js @@ -36,12 +36,14 @@ const displayProfile = (profile, totalStars, totalForks) => { const reposLink = `${profile.public_repos ?? 0}`; const gistsLink = `${profile.public_gists ?? 0}`; + const displayName = profile.name ? `${profile.name} (${profile.login})` : profile.login; + userInfo.innerHTML = `
user avatar
-

${profile.name || profile.login}

+

${displayName}

${profile.bio ? `

${profile.bio}

` : ''}

Stars: ${starsText}  |  diff --git a/style.css b/style.css index eacd2ab..7d9f010 100644 --- a/style.css +++ b/style.css @@ -147,6 +147,14 @@ ul { padding-bottom: 18px; } +.user-info div p a { + color: inherit; +} + +.user-info div p a:hover { + color: var(--accent); +} + .filter-repos, input { background: var(--bg-card);