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+ const token = "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" ; // Replace with your GitHub PAT
4+ var theme ;
35document . addEventListener ( "DOMContentLoaded" , function ( ) {
46 let contributors = [ ] ;
5- const token = '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' ; // Replace with your GitHub PAT
67
78 fetch ( "https://raw.githubusercontent.com/recodehive/awesome-github-profiles/main/.all-contributorsrc" )
89 . then ( ( response ) => response . json ( ) )
910 . then ( ( data ) => {
1011 contributors = data . contributors ;
11-
12+
1213 // Populate dropdowns with contributor names
1314 const select1 = document . getElementById ( 'contributorSelect1' ) ;
1415 const select2 = document . getElementById ( 'contributorSelect2' ) ;
15-
16+
1617 contributors . forEach ( ( da ) => {
1718 const option = document . createElement ( 'option' ) ;
1819 option . value = da . login ;
1920 option . textContent = da . name || da . login ;
20-
21+
2122 select1 . appendChild ( option . cloneNode ( true ) ) ;
2223 select2 . appendChild ( option . cloneNode ( true ) ) ;
2324 } ) ;
@@ -38,40 +39,225 @@ document.addEventListener("DOMContentLoaded", function () {
3839 headers : {
3940 'Authorization' : `token ${ token } `
4041 }
41- } ) . then ( response => response . json ( ) )
42+ } ) . then ( response => response . json ( ) ) ,
4243 ] )
43- . then ( ( [ data1 , data2 ] ) => {
44- // Show the table
45- document . getElementById ( 'comparisonTable' ) . classList . remove ( 'hidden' ) ;
44+ . then ( ( [ data1 , data2 ] ) => {
45+ // Show the table
46+ document
47+ . getElementById ( "comparisonTable" )
48+ . classList . remove ( "hidden" ) ;
4649
47- // Fill the table with data
48- document . getElementById ( ' login1' ) . textContent = data1 . login ;
49- document . getElementById ( ' login2' ) . textContent = data2 . login ;
50+ // Fill the table with data
51+ document . getElementById ( " login1" ) . textContent = data1 . login ;
52+ document . getElementById ( " login2" ) . textContent = data2 . login ;
5053
51- document . getElementById ( ' name1' ) . textContent = data1 . name || ' N/A' ;
52- document . getElementById ( ' name2' ) . textContent = data2 . name || ' N/A' ;
54+ document . getElementById ( " name1" ) . textContent = data1 . name || " N/A" ;
55+ document . getElementById ( " name2" ) . textContent = data2 . name || " N/A" ;
5356
54- document . getElementById ( ' bio1' ) . textContent = data1 . bio || ' N/A' ;
55- document . getElementById ( ' bio2' ) . textContent = data2 . bio || ' N/A' ;
57+ document . getElementById ( " bio1" ) . textContent = data1 . bio || " N/A" ;
58+ document . getElementById ( " bio2" ) . textContent = data2 . bio || " N/A" ;
5659
57- document . getElementById ( ' location1' ) . textContent = data1 . location || ' N/A' ;
58- document . getElementById ( ' location2' ) . textContent = data2 . location || ' N/A' ;
60+ document . getElementById ( " location1" ) . textContent = data1 . location || " N/A" ;
61+ document . getElementById ( " location2" ) . textContent = data2 . location || " N/A" ;
5962
60- document . getElementById ( ' repos1' ) . textContent = data1 . public_repos || ' N/A' ;
61- document . getElementById ( ' repos2' ) . textContent = data2 . public_repos || ' N/A' ;
63+ document . getElementById ( " repos1" ) . textContent = data1 . public_repos || " N/A" ;
64+ document . getElementById ( " repos2" ) . textContent = data2 . public_repos || " N/A" ;
6265
63- document . getElementById ( ' followers1' ) . textContent = data1 . followers || ' N/A' ;
64- document . getElementById ( ' followers2' ) . textContent = data2 . followers || ' N/A' ;
66+ document . getElementById ( " followers1" ) . textContent = data1 . followers || " N/A" ;
67+ document . getElementById ( " followers2" ) . textContent = data2 . followers || " N/A" ;
6568
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- } ) ;
69+ document . getElementById ( "following1" ) . textContent = data1 . following || "N/A" ;
70+ document . getElementById ( "following2" ) . textContent = data2 . following || "N/A" ;
71+ const themeToggleCheckbox = document . querySelector ( "#theme-toggle" ) ;
72+ theme = localStorage . getItem ( "theme" ) || "light" ;
73+ themeToggleCheckbox . addEventListener ( "change" , ( ) => {
74+ theme = localStorage . getItem ( "theme" ) || "light" ;
75+
76+ if ( login1 && login2 && login1 !== login2 ) {
77+ compareUsers ( login1 , login2 ) ;
78+ }
79+ } ) ;
80+ if ( login1 && login2 && login1 !== login2 ) {
81+ compareUsers ( login1 , login2 ) ;
82+ }
83+ } )
84+ . catch ( ( error ) => {
85+ console . error ( "Error:" , error ) ;
86+ } ) ;
7287 } else {
73- alert ( ' Please select two different contributors.' ) ;
88+ alert ( " Please select two different contributors." ) ;
7489 }
7590 } ) ;
76- } ) ;
7791
92+
93+ async function fetchGitHubUserDetails ( username ) {
94+ const headers = {
95+ Accept : "application/vnd.github.v3+json" ,
96+ Authorization : `token ${ token } ` ,
97+ } ;
98+
99+ try {
100+ // Fetch basic user details (public repos, followers, following)
101+ const userResponse = await fetch (
102+ `https://api.github.com/users/${ username } ` ,
103+ { headers }
104+ ) ;
105+ const userData = await userResponse . json ( ) ;
106+
107+ // Fetch issues created by the user
108+ const issuesResponse = await fetch (
109+ `https://api.github.com/search/issues?q=author:${ username } +type:issue` ,
110+ { headers }
111+ ) ;
112+ const issuesData = await issuesResponse . json ( ) ;
113+ const issuesCount = issuesData . total_count ;
114+
115+ // Fetch pull requests created by the user
116+ const prsResponse = await fetch (
117+ `https://api.github.com/search/issues?q=author:${ username } +type:pr` ,
118+ { headers }
119+ ) ;
120+ const prsData = await prsResponse . json ( ) ;
121+ const prsCount = prsData . total_count ;
122+
123+ return {
124+ public_repos : userData . public_repos ,
125+ followers : userData . followers ,
126+ following : userData . following ,
127+ issuesCount,
128+ prsCount,
129+ login : userData . login , // Store the username for display
130+ } ;
131+ } catch ( error ) {
132+ console . error ( `Error fetching details for ${ username } :` , error ) ;
133+ }
134+ }
135+
136+ function getChartColors ( ) {
137+ if ( theme === "dark" ) {
138+ return {
139+ borderColor1 : "rgba(54, 162, 235, 1)" ,
140+ pointBackgroundColor1 : "rgba(54, 162, 235, 1)" ,
141+ borderColor2 : "rgba(255, 99, 132, 1)" ,
142+ pointBackgroundColor2 : "rgba(255, 99, 132, 1)" ,
143+ gridColor : "rgba(255, 255, 255, 0.3)" , // Lighter grid color for dark mode
144+ tickColor : "#fff" , // White ticks for dark mode
145+ legendColor : "#fff" , // White legend labels for dark mode
146+ } ;
147+ } else {
148+ return {
149+ borderColor1 : "rgba(54, 162, 235, 1)" ,
150+ pointBackgroundColor1 : "rgba(54, 162, 235, 1)" ,
151+ borderColor2 : "rgba(255, 99, 132, 1)" ,
152+ pointBackgroundColor2 : "rgba(255, 99, 132, 1)" ,
153+ gridColor : "rgba(200, 200, 200, 0.3)" , // Darker grid color for light mode
154+ tickColor : "#333" , // Dark ticks for light mode
155+ legendColor : "#333" , // Dark legend labels for light mode
156+ } ;
157+ }
158+ }
159+
160+ async function compareUsers ( username1 , username2 ) {
161+
162+ const user1Data = await fetchGitHubUserDetails ( username1 ) ;
163+ const user2Data = await fetchGitHubUserDetails ( username2 ) ;
164+
165+ if ( user1Data && user2Data ) {
166+ displayComparison ( user1Data , user2Data ) ;
167+ } else {
168+ console . error ( "Failed to retrieve data for one or both users." ) ;
169+ }
170+ }
171+
172+ function displayComparison ( user1Data , user2Data ) {
173+ document . getElementById ( "result-container" ) . classList . remove ( "hidden" ) ;
174+ const ctx = document . getElementById ( "profileChart" ) . getContext ( "2d" ) ;
175+ const chartColors = getChartColors ( ) ;
176+
177+ if ( window . profileChart instanceof Chart ) {
178+ window . profileChart . destroy ( ) ;
179+ }
180+
181+ window . profileChart = new Chart ( ctx , {
182+ type : "line" ,
183+ data : {
184+ labels : [
185+ "Public Repos" ,
186+ "Followers" ,
187+ "Following" ,
188+ "Issues" ,
189+ "Pull Requests" ,
190+ ] ,
191+ datasets : [
192+ {
193+ label : user1Data . login ,
194+ data : [
195+ user1Data . public_repos ,
196+ user1Data . followers ,
197+ user1Data . following ,
198+ user1Data . issuesCount ,
199+ user1Data . prsCount ,
200+ ] ,
201+ // backgroundColor: chartColors.backgroundColor1,
202+ borderColor : chartColors . borderColor1 ,
203+ borderWidth : 3 ,
204+ pointRadius : 5 ,
205+ pointBackgroundColor : chartColors . pointBackgroundColor1 ,
206+ pointBorderColor : "#fff" ,
207+ pointHoverRadius : 8 ,
208+ pointBorderWidth : 2 , // Border width of points
209+ fill : false , // Fill under the line
210+ tension : 0 , // Smoothness of the line (0 for straight, higher for curves)
211+ } ,
212+ {
213+ label : user2Data . login ,
214+ data : [
215+ user2Data . public_repos ,
216+ user2Data . followers ,
217+ user2Data . following ,
218+ user2Data . issuesCount ,
219+ user2Data . prsCount ,
220+ ] ,
221+ // backgroundColor: chartColors.backgroundColor2,
222+ borderColor : chartColors . borderColor2 ,
223+ borderWidth : 3 ,
224+ pointRadius : 5 ,
225+ pointBackgroundColor : chartColors . pointBackgroundColor2 ,
226+ pointBorderColor : "#fff" ,
227+ pointHoverRadius : 8 ,
228+ pointBorderWidth : 2 ,
229+ fill : false ,
230+ tension : 0 ,
231+ } ,
232+ ] ,
233+ } ,
234+ options : {
235+ responsive : true ,
236+ maintainAspectRatio : false , // /Ensuring it's responsive
237+ scales : {
238+ x : {
239+ ticks : {
240+ color : chartColors . tickColor ,
241+ } ,
242+ } ,
243+ y : {
244+ beginAtZero : true ,
245+ ticks : {
246+ color : chartColors . tickColor ,
247+ } ,
248+ grid : {
249+ color : chartColors . gridColor ,
250+ } ,
251+ } ,
252+ } ,
253+ plugins : {
254+ legend : {
255+ labels : {
256+ color : chartColors . legendColor ,
257+ } ,
258+ } ,
259+ } ,
260+ } ,
261+ } ) ;
262+ }
263+ } ) ;
0 commit comments