@@ -98,100 +98,140 @@ const DashboardContent: React.FC = () => {
9898 setLeaderboardError ( null ) ;
9999
100100 try {
101- console . log ( '🔄 Fetching leaderboard data from API...' ) ;
101+ console . log ( '🔄 Fetching leaderboard data from RecodeHive GitHub API...' ) ;
102102
103- const response = await fetch ( 'https://gssoc24-leaderboard-backend-production-dfe3.up.railway.app/OSLeaderboard' ) ;
103+ // Fetch all repositories from RecodeHive organization
104+ const reposResponse = await fetch ( 'https://api.github.com/orgs/recodehive/repos?type=public&per_page=100' ) ;
104105
105- if ( ! response . ok ) {
106- throw new Error ( `API request failed: ${ response . status } ` ) ;
106+ if ( ! reposResponse . ok ) {
107+ throw new Error ( `GitHub API request failed: ${ reposResponse . status } ` ) ;
107108 }
108109
109- const data = await response . json ( ) ;
110- console . log ( '📊 API Response:' , data ) ;
110+ const repos = await reposResponse . json ( ) ;
111+ console . log ( '📊 GitHub Repos Response:' , repos ) ;
111112
112- if ( ! data . leaderboard || ! Array . isArray ( data . leaderboard ) ) {
113- throw new Error ( 'Invalid API response format' ) ;
113+ if ( ! Array . isArray ( repos ) ) {
114+ throw new Error ( 'Invalid GitHub API response format' ) ;
114115 }
115116
116- // Transform API data to match our LeaderboardEntry interface
117- const transformedData : LeaderboardEntry [ ] = data . leaderboard
118- . filter ( item => item . login && item . score !== undefined ) // Filter out entries without login or score
119- . map ( ( item , index ) => {
120- const score = item . score || 0 ;
121- const prCount = item . pr_urls ? item . pr_urls . length : 0 ;
122- const achievements = generateAchievements ( score , prCount ) ;
117+ // Collect all contributors from all repositories
118+ const contributorsMap = new Map < string , {
119+ login : string ;
120+ avatar_url : string ;
121+ html_url : string ;
122+ contributions : number ;
123+ repositories : number ;
124+ } > ( ) ;
125+
126+ // Fetch contributors for each repository
127+ for ( const repo of repos ) {
128+ try {
129+ const contributorsResponse = await fetch ( `https://api.github.com/repos/${ repo . full_name } /contributors?per_page=100` ) ;
123130
124- // Add badges for special tags
125- if ( item . postManTag ) achievements . push ( "📮 Postman Badge" ) ;
126- if ( item . web3hack ) achievements . push ( "🌐 Web3 Hacker" ) ;
131+ if ( contributorsResponse . ok ) {
132+ const contributors = await contributorsResponse . json ( ) ;
133+
134+ if ( Array . isArray ( contributors ) ) {
135+ contributors . forEach ( contributor => {
136+ if ( contributor . login && contributor . type === 'User' ) {
137+ const existing = contributorsMap . get ( contributor . login ) ;
138+ if ( existing ) {
139+ existing . contributions += contributor . contributions ;
140+ existing . repositories += 1 ;
141+ } else {
142+ contributorsMap . set ( contributor . login , {
143+ login : contributor . login ,
144+ avatar_url : contributor . avatar_url ,
145+ html_url : contributor . html_url ,
146+ contributions : contributor . contributions ,
147+ repositories : 1 ,
148+ } ) ;
149+ }
150+ }
151+ } ) ;
152+ }
153+ }
154+ } catch ( error ) {
155+ console . warn ( `Error fetching contributors for ${ repo . name } :` , error ) ;
156+ }
157+ }
158+
159+ // Transform contributors data to match our LeaderboardEntry interface
160+ const transformedData : LeaderboardEntry [ ] = Array . from ( contributorsMap . values ( ) )
161+ . filter ( contributor => contributor . contributions > 0 )
162+ . map ( ( contributor , index ) => {
163+ const score = contributor . contributions * 10 ; // Convert contributions to score
164+ const achievements = generateAchievements ( score , contributor . contributions ) ;
127165
128166 return {
129167 rank : index + 1 ,
130- name : item . login , // Using login as name since that's what's available
131- username : item . login ,
132- avatar : item . avatar_url || `https://avatars.githubusercontent.com/u/ ${ Math . floor ( Math . random ( ) * 100000 ) } ?v=4` ,
133- contributions : prCount ,
134- repositories : Math . floor ( prCount / 3 ) || 1 , // Estimate repos based on PRs
168+ name : contributor . login ,
169+ username : contributor . login ,
170+ avatar : contributor . avatar_url ,
171+ contributions : contributor . contributions ,
172+ repositories : contributor . repositories ,
135173 score,
136174 achievements,
137- github_url : item . url || `https://github.com/ ${ item . login } ` ,
138- streak : item . streak || 0 ,
139- postManTag : item . postManTag || false ,
140- web3hack : item . web3hack || false ,
175+ github_url : contributor . html_url ,
176+ streak : Math . floor ( Math . random ( ) * 10 ) + 1 , // Random streak for demo
177+ postManTag : false ,
178+ web3hack : false ,
141179 } ;
142180 } )
143- . sort ( ( a , b ) => b . score - a . score ) // Sort by score descending
181+ . sort ( ( a , b ) => b . contributions - a . contributions ) // Sort by contributions descending
144182 . map ( ( item , index ) => ( { ...item , rank : index + 1 } ) ) ; // Update ranks after sorting
145183
146- console . log ( '✅ Successfully processed leaderboard data:' , transformedData ) ;
184+ console . log ( '✅ Successfully processed RecodeHive contributors data:' , transformedData ) ;
147185 setLeaderboardData ( transformedData ) ;
148186
149187 } catch ( error ) {
150- console . error ( '❌ Error fetching leaderboard data:' , error ) ;
188+ console . error ( '❌ Error fetching RecodeHive contributors data:' , error ) ;
151189 setLeaderboardError ( error . message ) ;
152190
153191 // Fallback demo data with similar structure
154192 console . log ( '📝 Loading demo data as fallback...' ) ;
155193 const demoData : LeaderboardEntry [ ] = [
156194 {
157195 rank : 1 ,
158- name : "ShivanshPlays " ,
159- username : "ShivanshPlays " ,
160- avatar : "https://avatars.githubusercontent.com/u/112249407 ?v=4" ,
161- contributions : 158 ,
196+ name : "sanjay-kv " ,
197+ username : "sanjay-kv " ,
198+ avatar : "https://avatars.githubusercontent.com/u/30715153 ?v=4" ,
199+ contributions : 250 ,
162200 repositories : 25 ,
163- score : 7900 ,
164- achievements : [ "🏆 Top Contributor" , "📮 Postman Badge " , "🌐 Web3 Hacker " ] ,
165- github_url : "https://github.com/ShivanshPlays " ,
166- streak : 9 ,
167- postManTag : true ,
168- web3hack : true ,
201+ score : 2500 ,
202+ achievements : [ "🏆 Top Contributor" , "👑 Founder " , "🚀 Maintainer " ] ,
203+ github_url : "https://github.com/sanjay-kv " ,
204+ streak : 15 ,
205+ postManTag : false ,
206+ web3hack : false ,
169207 } ,
170208 {
171209 rank : 2 ,
172- name : "IkkiOcean " ,
173- username : "IkkiOcean " ,
174- avatar : "https://avatars.githubusercontent.com/u/76002919 ?v=4" ,
175- contributions : 145 ,
210+ name : "vansh-codes " ,
211+ username : "vansh-codes " ,
212+ avatar : "https://avatars.githubusercontent.com/u/114163734 ?v=4" ,
213+ contributions : 180 ,
176214 repositories : 22 ,
177- score : 7850 ,
178- achievements : [ "🚀 Rising Star" , "📮 Postman Badge " , "🌐 Web3 Hacker " ] ,
179- github_url : "https://github.com/IkkiOcean " ,
215+ score : 1800 ,
216+ achievements : [ "🚀 Rising Star" , "💪 Active Contributor " , "⭐ Star Contributor " ] ,
217+ github_url : "https://github.com/vansh-codes " ,
180218 streak : 8 ,
181- postManTag : true ,
182- web3hack : true ,
219+ postManTag : false ,
220+ web3hack : false ,
183221 } ,
184222 {
185223 rank : 3 ,
186- name : "Community Member " ,
187- username : "member3 " ,
188- avatar : "https://avatars.githubusercontent.com/u/79542825 ?v=4" ,
224+ name : "Hemu21 " ,
225+ username : "Hemu21 " ,
226+ avatar : "https://avatars.githubusercontent.com/u/106808387 ?v=4" ,
189227 contributions : 120 ,
190228 repositories : 18 ,
191- score : 6500 ,
192- achievements : [ "💪 Power User" , "⭐ Star Contributor" ] ,
193- github_url : "https://github.com/member3 " ,
229+ score : 1200 ,
230+ achievements : [ "💪 Power User" , "⭐ Star Contributor" , "🔥 Consistent" ] ,
231+ github_url : "https://github.com/Hemu21 " ,
194232 streak : 5 ,
233+ postManTag : false ,
234+ web3hack : false ,
195235 }
196236 ] ;
197237 setLeaderboardData ( demoData ) ;
@@ -621,10 +661,10 @@ const DashboardContent: React.FC = () => {
621661 transition = { { duration : 0.6 } }
622662 >
623663 < h1 className = "leaderboard-page-title" >
624- 🏆 Community < span className = "highlight" > Leaderboard </ span >
664+ 🏆 RecodeHive < span className = "highlight" > Contributors </ span >
625665 </ h1 >
626666 < p className = "leaderboard-page-subtitle" >
627- Live rankings from GSSoC '24 API • Updated automatically
667+ Live rankings from RecodeHive GitHub Organization • Updated automatically
628668 </ p >
629669 < div className = "refresh-section" >
630670 < button
@@ -645,7 +685,7 @@ const DashboardContent: React.FC = () => {
645685 animate = { { opacity : 1 } }
646686 >
647687 < div className = "loading-spinner-large" > ⏳</ div >
648- < p > Loading leaderboard data from GSSoC API...</ p >
688+ < p > Loading leaderboard data from RecodeHive GitHub API...</ p >
649689 </ motion . div >
650690 ) }
651691
@@ -661,9 +701,9 @@ const DashboardContent: React.FC = () => {
661701 < div className = "error-help" >
662702 < p > < strong > This could be due to:</ strong > </ p >
663703 < ul >
664- < li > API server is temporarily down</ li >
704+ < li > GitHub API server is temporarily down</ li >
665705 < li > Network connectivity issues</ li >
666- < li > API rate limiting</ li >
706+ < li > GitHub API rate limiting</ li >
667707 </ ul >
668708 < p > Please try refreshing in a moment!</ p >
669709 </ div >
0 commit comments