Skip to content

Commit 2e17921

Browse files
.
1 parent e343082 commit 2e17921

File tree

2 files changed

+255
-153
lines changed

2 files changed

+255
-153
lines changed

contributors.html

Lines changed: 122 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -809,118 +809,107 @@ <h4>Connect With Us</h4>
809809
let contributorsData = [];
810810
let filteredContributors = [];
811811

812-
// Fetch contributors from GitHub API
813-
async function fetchContributors() {
814-
try {
815-
const url = `https://api.github.com/repos/${owner}/${repo}/contributors`;
816-
const response = await fetch(url);
812+
// GitHub API headers
813+
const apiHeaders = {
814+
'Accept': 'application/vnd.github.v3+json',
815+
'User-Agent': 'AnimateItNow-Contributors'
816+
};
817+
818+
// Fetch all pages of contributors
819+
async function fetchAllContributors() {
820+
let allContributors = [];
821+
let page = 1;
822+
const perPage = 100;
823+
824+
while (true) {
825+
try {
826+
const url = `https://api.github.com/repos/${owner}/${repo}/contributors?per_page=${perPage}&page=${page}`;
827+
const response = await fetch(url, { headers: apiHeaders });
828+
829+
// Check rate limit
830+
const remaining = response.headers.get('X-RateLimit-Remaining');
831+
const resetTime = response.headers.get('X-RateLimit-Reset');
832+
833+
if (response.status === 403) {
834+
if (resetTime) {
835+
const resetDate = new Date(parseInt(resetTime) * 1000);
836+
throw new Error(`GitHub API rate limit exceeded. Please try again after ${resetDate.toLocaleTimeString()}`);
837+
}
838+
throw new Error(`GitHub API error! Status: ${response.status}. Rate limit may be exceeded.`);
839+
}
817840

818-
if (!response.ok) {
819-
throw new Error(`GitHub API error! Status: ${response.status}`);
820-
}
841+
if (!response.ok) {
842+
throw new Error(`GitHub API error! Status: ${response.status}`);
843+
}
821844

822-
const contributors = await response.json();
845+
const contributors = await response.json();
823846

824-
// If no data fetched, use dummy data for demonstration
825-
if (!Array.isArray(contributors) || contributors.length === 0) {
826-
console.warn(
827-
"No data fetched from GitHub. Using dummy data for demonstration."
828-
);
829-
return getDummyContributors();
830-
}
847+
if (!Array.isArray(contributors) || contributors.length === 0) {
848+
break; // No more pages
849+
}
831850

832-
return contributors;
833-
} catch (error) {
834-
console.error("Error fetching contributors:", error);
835-
// Return dummy data if fetch fails
836-
return getDummyContributors();
851+
allContributors = allContributors.concat(contributors);
852+
853+
// If we got less than perPage, we're on the last page
854+
if (contributors.length < perPage) {
855+
break;
856+
}
857+
858+
page++;
859+
860+
// Safety limit
861+
if (page > 10) break;
862+
} catch (error) {
863+
console.error("Error fetching contributors:", error);
864+
throw error;
865+
}
837866
}
867+
868+
return allContributors;
838869
}
839870

840-
// Get dummy contributors for demonstration
841-
function getDummyContributors() {
842-
return [
843-
{
844-
login: "anuj",
845-
id: 1,
846-
avatar_url: "https://via.placeholder.com/100/4f8cff/ffffff?text=A",
847-
html_url: "https://github.com/anuj",
848-
contributions: 150,
849-
type: "User",
850-
},
851-
{
852-
login: "alice",
853-
id: 2,
854-
avatar_url: "https://via.placeholder.com/100/2563eb/ffffff?text=A",
855-
html_url: "https://github.com/alice",
856-
contributions: 89,
857-
type: "User",
858-
},
859-
{
860-
login: "bob",
861-
id: 3,
862-
avatar_url: "https://via.placeholder.com/100/1dc5c8/ffffff?text=B",
863-
html_url: "https://github.com/bob",
864-
contributions: 76,
865-
type: "User",
866-
},
867-
{
868-
login: "charlie",
869-
id: 4,
870-
avatar_url: "https://via.placeholder.com/100/4f8cff/ffffff?text=C",
871-
html_url: "https://github.com/charlie",
872-
contributions: 64,
873-
type: "User",
874-
},
875-
{
876-
login: "diana",
877-
id: 5,
878-
avatar_url: "https://via.placeholder.com/100/2563eb/ffffff?text=D",
879-
html_url: "https://github.com/diana",
880-
contributions: 52,
881-
type: "User",
882-
},
883-
{
884-
login: "emma",
885-
id: 6,
886-
avatar_url: "https://via.placeholder.com/100/1dc5c8/ffffff?text=E",
887-
html_url: "https://github.com/emma",
888-
contributions: 41,
889-
type: "User",
890-
},
891-
{
892-
login: "frank",
893-
id: 7,
894-
avatar_url: "https://via.placeholder.com/100/4f8cff/ffffff?text=F",
895-
html_url: "https://github.com/frank",
896-
contributions: 35,
897-
type: "User",
898-
},
899-
{
900-
login: "grace",
901-
id: 8,
902-
avatar_url: "https://via.placeholder.com/100/2563eb/ffffff?text=G",
903-
html_url: "https://github.com/grace",
904-
contributions: 28,
905-
type: "User",
906-
},
907-
];
908-
}
909-
910-
// Fetch additional user details
911-
async function fetchUserDetails(login) {
871+
// Fetch contributors from GitHub API with caching
872+
async function fetchContributors() {
873+
const cacheKey = `contributors_${owner}_${repo}`;
874+
const cacheDuration = 30 * 60 * 1000; // 30 minutes
875+
const cachedItem = sessionStorage.getItem(cacheKey);
876+
877+
// Check cache first
878+
if (cachedItem) {
879+
const { timestamp, data } = JSON.parse(cachedItem);
880+
if (new Date().getTime() - timestamp < cacheDuration) {
881+
console.log("📦 Loading contributors from cache");
882+
return data;
883+
}
884+
}
885+
912886
try {
913-
const url = `https://api.github.com/users/${login}`;
914-
const response = await fetch(url);
887+
console.log("🔄 Fetching contributors from GitHub API...");
888+
const contributors = await fetchAllContributors();
915889

916-
if (!response.ok) {
917-
return null;
890+
if (!Array.isArray(contributors) || contributors.length === 0) {
891+
throw new Error("No contributors found in repository");
918892
}
919893

920-
return await response.json();
894+
// Cache the data
895+
sessionStorage.setItem(cacheKey, JSON.stringify({
896+
timestamp: new Date().getTime(),
897+
data: contributors
898+
}));
899+
900+
console.log(`✅ Fetched ${contributors.length} contributors`);
901+
return contributors;
921902
} catch (error) {
922-
console.error(`Error fetching user details for ${login}:`, error);
923-
return null;
903+
console.error("Error fetching contributors:", error);
904+
905+
// Try to use cached data even if expired
906+
if (cachedItem) {
907+
const { data } = JSON.parse(cachedItem);
908+
console.warn("⚠️ Using expired cache due to API error");
909+
return data;
910+
}
911+
912+
throw error;
924913
}
925914
}
926915

@@ -960,13 +949,13 @@ <h3 class="contributor-name">${
960949
</div>
961950
<div class="contributor-stat">
962951
<div class="contributor-stat-value">${
963-
contributor.public_repos || "N/A"
952+
contributor.public_repos || "-"
964953
}</div>
965954
<div class="contributor-stat-label">Repos</div>
966955
</div>
967956
<div class="contributor-stat">
968957
<div class="contributor-stat-value">${
969-
contributor.followers || "N/A"
958+
contributor.followers || "-"
970959
}</div>
971960
<div class="contributor-stat-label">Followers</div>
972961
</div>
@@ -1017,9 +1006,7 @@ <h3 class="contributor-name">${
10171006
} else {
10181007
filteredContributors = contributorsData.filter(
10191008
(contributor) =>
1020-
contributor.login.toLowerCase().includes(searchTerm) ||
1021-
(contributor.name &&
1022-
contributor.name.toLowerCase().includes(searchTerm))
1009+
contributor.login.toLowerCase().includes(searchTerm)
10231010
);
10241011
}
10251012

@@ -1028,23 +1015,38 @@ <h3 class="contributor-name">${
10281015

10291016
// Initialize contributors page
10301017
async function init() {
1031-
const contributors = await fetchContributors();
1032-
1033-
// Fetch additional details for each contributor
1034-
const contributorsWithDetails = await Promise.all(
1035-
contributors.map(async (contributor) => {
1036-
const userDetails = await fetchUserDetails(contributor.login);
1037-
return { ...contributor, ...userDetails };
1038-
})
1039-
);
1018+
try {
1019+
const contributors = await fetchContributors();
10401020

1041-
contributorsData = contributorsWithDetails.sort(
1042-
(a, b) => b.contributions - a.contributions
1043-
);
1044-
filteredContributors = [...contributorsData];
1021+
// Contributors endpoint already includes: login, avatar_url, html_url, contributions, type
1022+
// No need for additional API calls per user
1023+
contributorsData = contributors.sort(
1024+
(a, b) => b.contributions - a.contributions
1025+
);
1026+
filteredContributors = [...contributorsData];
10451027

1046-
updateStats(contributorsData);
1047-
renderContributors(filteredContributors);
1028+
updateStats(contributorsData);
1029+
renderContributors(filteredContributors);
1030+
} catch (error) {
1031+
console.error("Error initializing contributors:", error);
1032+
const grid = document.getElementById("contributors-grid");
1033+
if (grid) {
1034+
grid.innerHTML = `
1035+
<div class="loading-state" style="text-align: center; padding: 40px;">
1036+
<div style="font-size: 3rem; margin-bottom: 20px;">⚠️</div>
1037+
<div style="font-size: 1.2rem; font-weight: 600; color: #dc3545; margin-bottom: 10px;">Error Loading Contributors</div>
1038+
<div style="font-size: 0.9rem; color: var(--text-light); margin-bottom: 20px;">${error.message}</div>
1039+
<button onclick="sessionStorage.clear(); location.reload();" style="padding: 10px 20px; background: #6C63FF; color: white; border: none; border-radius: 5px; cursor: pointer;">Retry</button>
1040+
</div>
1041+
`;
1042+
}
1043+
1044+
// Show error in stats
1045+
document.getElementById("totalContributors").textContent = "0";
1046+
document.getElementById("totalCommits").textContent = "0";
1047+
document.getElementById("totalPRs").textContent = "0";
1048+
return;
1049+
}
10481050

10491051
// Set up search functionality
10501052
document

0 commit comments

Comments
 (0)