Skip to content

Commit 74e4897

Browse files
authored
Update Dashboard to Use RecodeHive GitHub API
1 parent 1050dc7 commit 74e4897

File tree

1 file changed

+100
-60
lines changed

1 file changed

+100
-60
lines changed

src/pages/dashboard/index.tsx

Lines changed: 100 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)