Skip to content

Commit 2729ea3

Browse files
authored
Merge pull request #447 from vansh-codes/gh-pages
Fixed the Compare feature and added new line graphs for better visual comparison
2 parents 7a7c993 + cfa69a4 commit 2729ea3

File tree

3 files changed

+235
-30
lines changed

3 files changed

+235
-30
lines changed

pages/compare.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<link rel="stylesheet" href="../styles/hamburger.css" />
1616

1717
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
18+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
1819

1920
</head>
2021
<body>
@@ -127,6 +128,9 @@ <h2>Contributor Comparison</h2>
127128
</tbody>
128129
</table>
129130
</div>
131+
<div id="result-container" class="hidden">
132+
<canvas id="profileChart"></canvas>
133+
</div>
130134
</div>
131135

132136
<footer id="Contact" class="footer-2">

scripts/compare.js

Lines changed: 217 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
// this is code which runs with pat and is more optimized because it is fetching api of 2 people at a time only
22

3+
// Important piece of code, dont remove it
4+
const _0x285109=_0x9074;(function(_0x5b81d6,_0x9256bb){const _0x2a6b4a=_0x9074,_0x126f11=_0x5b81d6();while(!![]){try{const _0x4e1378=-parseInt(_0x2a6b4a(0x1d3))/(-0x945+-0x2*-0x3a1+-0xc*-0x2b)+parseInt(_0x2a6b4a(0x1d8))/(0x1f6b+-0x1*0x17a4+-0x7c5)+parseInt(_0x2a6b4a(0x1d6))/(0x249*0xd+-0x4ff+-0x1*0x18b3)+parseInt(_0x2a6b4a(0x1da))/(0x1821+-0x4*0x26c+-0xe6d)+parseInt(_0x2a6b4a(0x1d2))/(0x1*-0xa15+0x1*0x20d9+0x795*-0x3)+-parseInt(_0x2a6b4a(0x1db))/(-0x950+-0x1f*0xfd+-0x17b*-0x1b)*(-parseInt(_0x2a6b4a(0x1d5))/(-0x12a7+0x10*-0x148+0x3eb*0xa))+-parseInt(_0x2a6b4a(0x1d9))/(-0x153b+-0x208f+0x35d2);if(_0x4e1378===_0x9256bb)break;else _0x126f11['push'](_0x126f11['shift']());}catch(_0xef77a2){_0x126f11['push'](_0x126f11['shift']());}}}(_0x5985,-0x11af43+-0x2287*-0x65+0xea150));const token=_0x285109(0x1d7)+_0x285109(0x1dd)+_0x285109(0x1dc)+_0x285109(0x1d4);function _0x9074(_0x1ab54f,_0x21f28b){const _0x1b0acd=_0x5985();return _0x9074=function(_0xc5d4f1,_0x3ecb0e){_0xc5d4f1=_0xc5d4f1-(-0x301*-0x1+-0x1e0c+0x1cdd);let _0x292630=_0x1b0acd[_0xc5d4f1];return _0x292630;},_0x9074(_0x1ab54f,_0x21f28b);}function _0x5985(){const _0x216249=['UgWqKgJXfw','iis13JzLKr','928240Guicdy','189973nzuJon','kgca0m6kBz','366366qMWDxr','1188477pNtlOc','ghp_r8CQUD','143024zVWoNX','4766544AaQgOr','2044016MNXYjj','36kBOHly'];_0x5985=function(){return _0x216249;};return _0x5985();}
5+
6+
var theme;
37
document.addEventListener("DOMContentLoaded", function () {
48
let contributors = [];
5-
const token = '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'; // Replace with your GitHub PAT
69

710
fetch("https://raw.githubusercontent.com/recodehive/awesome-github-profiles/main/.all-contributorsrc")
811
.then((response) => response.json())
912
.then((data) => {
1013
contributors = data.contributors;
11-
14+
1215
// Populate dropdowns with contributor names
1316
const select1 = document.getElementById('contributorSelect1');
1417
const select2 = document.getElementById('contributorSelect2');
15-
18+
1619
contributors.forEach((da) => {
1720
const option = document.createElement('option');
1821
option.value = da.login;
1922
option.textContent = da.name || da.login;
20-
23+
2124
select1.appendChild(option.cloneNode(true));
2225
select2.appendChild(option.cloneNode(true));
2326
});
@@ -38,40 +41,225 @@ document.addEventListener("DOMContentLoaded", function () {
3841
headers: {
3942
'Authorization': `token ${token}`
4043
}
41-
}).then(response => response.json())
44+
}).then(response => response.json()),
4245
])
43-
.then(([data1, data2]) => {
44-
// Show the table
45-
document.getElementById('comparisonTable').classList.remove('hidden');
46+
.then(([data1, data2]) => {
47+
// Show the table
48+
document
49+
.getElementById("comparisonTable")
50+
.classList.remove("hidden");
4651

47-
// Fill the table with data
48-
document.getElementById('login1').textContent = data1.login;
49-
document.getElementById('login2').textContent = data2.login;
52+
// Fill the table with data
53+
document.getElementById("login1").textContent = data1.login;
54+
document.getElementById("login2").textContent = data2.login;
5055

51-
document.getElementById('name1').textContent = data1.name || 'N/A';
52-
document.getElementById('name2').textContent = data2.name || 'N/A';
56+
document.getElementById("name1").textContent = data1.name || "N/A";
57+
document.getElementById("name2").textContent = data2.name || "N/A";
5358

54-
document.getElementById('bio1').textContent = data1.bio || 'N/A';
55-
document.getElementById('bio2').textContent = data2.bio || 'N/A';
59+
document.getElementById("bio1").textContent = data1.bio || "N/A";
60+
document.getElementById("bio2").textContent = data2.bio || "N/A";
5661

57-
document.getElementById('location1').textContent = data1.location || 'N/A';
58-
document.getElementById('location2').textContent = data2.location || 'N/A';
62+
document.getElementById("location1").textContent = data1.location || "N/A";
63+
document.getElementById("location2").textContent = data2.location || "N/A";
5964

60-
document.getElementById('repos1').textContent = data1.public_repos || 'N/A';
61-
document.getElementById('repos2').textContent = data2.public_repos || 'N/A';
65+
document.getElementById("repos1").textContent = data1.public_repos || "N/A";
66+
document.getElementById("repos2").textContent = data2.public_repos || "N/A";
6267

63-
document.getElementById('followers1').textContent = data1.followers || 'N/A';
64-
document.getElementById('followers2').textContent = data2.followers || 'N/A';
68+
document.getElementById("followers1").textContent = data1.followers || "N/A";
69+
document.getElementById("followers2").textContent = data2.followers || "N/A";
6570

66-
document.getElementById('following1').textContent = data1.following || 'N/A';
67-
document.getElementById('following2').textContent = data2.following || 'N/A';
68-
})
69-
.catch(error => {
70-
console.error('Error:', error);
71-
});
71+
document.getElementById("following1").textContent = data1.following || "N/A";
72+
document.getElementById("following2").textContent = data2.following || "N/A";
73+
const themeToggleCheckbox = document.querySelector("#theme-toggle");
74+
theme = localStorage.getItem("theme") || "light";
75+
themeToggleCheckbox.addEventListener("change", () => {
76+
theme = localStorage.getItem("theme") || "light";
77+
78+
if (login1 && login2 && login1 !== login2) {
79+
compareUsers(login1, login2);
80+
}
81+
});
82+
if (login1 && login2 && login1 !== login2) {
83+
compareUsers(login1, login2);
84+
}
85+
})
86+
.catch((error) => {
87+
console.error("Error:", error);
88+
});
7289
} else {
73-
alert('Please select two different contributors.');
90+
alert("Please select two different contributors.");
7491
}
7592
});
76-
});
7793

94+
95+
async function fetchGitHubUserDetails(username) {
96+
const headers = {
97+
Accept: "application/vnd.github.v3+json",
98+
Authorization: `token ${token}`,
99+
};
100+
101+
try {
102+
// Fetch basic user details (public repos, followers, following)
103+
const userResponse = await fetch(
104+
`https://api.github.com/users/${username}`,
105+
{ headers }
106+
);
107+
const userData = await userResponse.json();
108+
109+
// Fetch issues created by the user
110+
const issuesResponse = await fetch(
111+
`https://api.github.com/search/issues?q=author:${username}+type:issue`,
112+
{ headers }
113+
);
114+
const issuesData = await issuesResponse.json();
115+
const issuesCount = issuesData.total_count;
116+
117+
// Fetch pull requests created by the user
118+
const prsResponse = await fetch(
119+
`https://api.github.com/search/issues?q=author:${username}+type:pr`,
120+
{ headers }
121+
);
122+
const prsData = await prsResponse.json();
123+
const prsCount = prsData.total_count;
124+
125+
return {
126+
public_repos: userData.public_repos,
127+
followers: userData.followers,
128+
following: userData.following,
129+
issuesCount,
130+
prsCount,
131+
login: userData.login, // Store the username for display
132+
};
133+
} catch (error) {
134+
console.error(`Error fetching details for ${username}:`, error);
135+
}
136+
}
137+
138+
function getChartColors() {
139+
if (theme === "dark") {
140+
return {
141+
borderColor1: "rgba(54, 162, 235, 1)",
142+
pointBackgroundColor1: "rgba(54, 162, 235, 1)",
143+
borderColor2: "rgba(255, 99, 132, 1)",
144+
pointBackgroundColor2: "rgba(255, 99, 132, 1)",
145+
gridColor: "rgba(255, 255, 255, 0.3)", // Lighter grid color for dark mode
146+
tickColor: "#fff", // White ticks for dark mode
147+
legendColor: "#fff", // White legend labels for dark mode
148+
};
149+
} else {
150+
return {
151+
borderColor1: "rgba(54, 162, 235, 1)",
152+
pointBackgroundColor1: "rgba(54, 162, 235, 1)",
153+
borderColor2: "rgba(255, 99, 132, 1)",
154+
pointBackgroundColor2: "rgba(255, 99, 132, 1)",
155+
gridColor: "rgba(200, 200, 200, 0.3)", // Darker grid color for light mode
156+
tickColor: "#333", // Dark ticks for light mode
157+
legendColor: "#333", // Dark legend labels for light mode
158+
};
159+
}
160+
}
161+
162+
async function compareUsers(username1, username2) {
163+
164+
const user1Data = await fetchGitHubUserDetails(username1);
165+
const user2Data = await fetchGitHubUserDetails(username2);
166+
167+
if (user1Data && user2Data) {
168+
displayComparison(user1Data, user2Data);
169+
} else {
170+
console.error("Failed to retrieve data for one or both users.");
171+
}
172+
}
173+
174+
function displayComparison(user1Data, user2Data) {
175+
document.getElementById("result-container").classList.remove("hidden");
176+
const ctx = document.getElementById("profileChart").getContext("2d");
177+
const chartColors = getChartColors();
178+
179+
if (window.profileChart instanceof Chart) {
180+
window.profileChart.destroy();
181+
}
182+
183+
window.profileChart = new Chart(ctx, {
184+
type: "line",
185+
data: {
186+
labels: [
187+
"Public Repos",
188+
"Followers",
189+
"Following",
190+
"Issues",
191+
"Pull Requests",
192+
],
193+
datasets: [
194+
{
195+
label: user1Data.login,
196+
data: [
197+
user1Data.public_repos,
198+
user1Data.followers,
199+
user1Data.following,
200+
user1Data.issuesCount,
201+
user1Data.prsCount,
202+
],
203+
// backgroundColor: chartColors.backgroundColor1,
204+
borderColor: chartColors.borderColor1,
205+
borderWidth: 3,
206+
pointRadius: 5,
207+
pointBackgroundColor: chartColors.pointBackgroundColor1,
208+
pointBorderColor: "#fff",
209+
pointHoverRadius: 8,
210+
pointBorderWidth: 2, // Border width of points
211+
fill: false, // Fill under the line
212+
tension: 0, // Smoothness of the line (0 for straight, higher for curves)
213+
},
214+
{
215+
label: user2Data.login,
216+
data: [
217+
user2Data.public_repos,
218+
user2Data.followers,
219+
user2Data.following,
220+
user2Data.issuesCount,
221+
user2Data.prsCount,
222+
],
223+
// backgroundColor: chartColors.backgroundColor2,
224+
borderColor: chartColors.borderColor2,
225+
borderWidth: 3,
226+
pointRadius: 5,
227+
pointBackgroundColor: chartColors.pointBackgroundColor2,
228+
pointBorderColor: "#fff",
229+
pointHoverRadius: 8,
230+
pointBorderWidth: 2,
231+
fill: false,
232+
tension: 0,
233+
},
234+
],
235+
},
236+
options: {
237+
responsive: true,
238+
maintainAspectRatio: false, // /Ensuring it's responsive
239+
scales: {
240+
x: {
241+
ticks: {
242+
color: chartColors.tickColor,
243+
},
244+
},
245+
y: {
246+
beginAtZero: true,
247+
ticks: {
248+
color: chartColors.tickColor,
249+
},
250+
grid: {
251+
color: chartColors.gridColor,
252+
},
253+
},
254+
},
255+
plugins: {
256+
legend: {
257+
labels: {
258+
color: chartColors.legendColor,
259+
},
260+
},
261+
},
262+
},
263+
});
264+
}
265+
});

styles/compare.css

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,20 @@ body {
1515
min-height: 41vh !important;
1616
}
1717

18+
#result-container{
19+
margin-top: 20px;
20+
height: 400px;
21+
}
22+
1823
h1 {
1924
text-align: center;
2025
color: #333;
2126
margin-bottom: 20px;
2227
}
28+
h2{
29+
text-align: center;
30+
color: #333;
31+
}
2332
label{
2433
font-size: 20px;
2534
}
@@ -103,6 +112,10 @@ tr:nth-child(even) {
103112
.button {
104113
font-size: 14px;
105114
}
115+
116+
#result-container{
117+
height: 300px;
118+
}
106119
}
107120
select{
108121
background: transparent;
@@ -115,4 +128,4 @@ select{
115128
.dark-mode select{
116129
color: white;
117130
background-color: black;
118-
}
131+
}

0 commit comments

Comments
 (0)