Skip to content

[Advanced]: feat(frontend): integrate GitHub Contributors API into Hall of Fame with localStorage caching and rate-limit fallbackΒ #119

@ambicuity

Description

@ambicuity

🧠 Advanced Contributors

This issue requires deep familiarity with:

  • GitHub REST API v3 β€” /repos/{owner}/{repo}/contributors endpoint + Link header pagination
  • Browser fetch with error handling and HTTP 403 (rate-limit) detection
  • localStorage for client-side response caching with TTL
  • Graceful degradation to static JSON fallback
  • The Hall of Fame static page (prerequisite: INT-03 must be merged first)

Important

Prerequisites: The Hall of Fame static page (INT-03) must be merged to main before starting.

You must be assigned before starting β€” comment /assign to claim this issue.

Warning

GitHub unauthenticated API has a 60 requests/hour limit per IP. A naive fetch on every page load will exhaust this for multiple simultaneous users. The localStorage caching strategy is a hard requirement β€” not optional.


🐞 Problem Description

After INT-03 is merged, the Hall of Fame shows hardcoded placeholder cards. Manually maintaining this list defeats the purpose of an automated platform. The integration risk: without caching, the API rate limit breaks the page for anyone who visited in the last hour.


πŸ’‘ Proposed / Expected Solution

Create docs/hall-of-fame.js (new file, loaded only by hall-of-fame.html β€” NOT bundled into app.js).

1. Fetch with localStorage caching (mandatory):

const CACHE_KEY = 'hof_contributors';
const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour

async function fetchContributors() {
  const cached = JSON.parse(localStorage.getItem(CACHE_KEY) || 'null');
  if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {
    return cached.data;
  }
  const res = await fetch(
    'https://api.github.com/repos/ambicuity/New-Grad-Jobs/contributors?per_page=100',
    { headers: { Accept: 'application/vnd.github+json' } }
  );
  if (res.status === 403) { /* rate limited β€” fall back to contributors-fallback.json */ }
  if (!res.ok) throw new Error(`GitHub API ${res.status}`);
  const data = await res.json();
  localStorage.setItem(CACHE_KEY, JSON.stringify({ timestamp: Date.now(), data }));
  return data;
}

2. Pagination: Loop ?page=N until empty response β€” handles >100 contributors.

3. Card rendering: Replace placeholder cards with dynamically generated .hof-card elements (exact HTML from INT-03). Map: login β†’ username link, avatar_url β†’ <img>, contributions β†’ count badge.

4. Sorting + rank badges: Sort by contributions descending. Top 3: πŸ₯‡ Top Contributor, πŸ₯ˆ 2nd, πŸ₯‰ 3rd.

5. Graceful degradation:

  • HTTP 403: fall back to docs/contributors-fallback.json (a committed JSON snapshot β€” you must create this)
  • Other error: "Data temporarily unavailable β€” check back soon", retain localStorage data
  • Loading: show .skeleton-card CSS while fetch is in flight

βœ… Acceptance Criteria

  • docs/hall-of-fame.js created β€” loaded only by hall-of-fame.html
  • fetchContributors() uses localStorage caching with 1-hour TTL
  • HTTP 403 handled gracefully β†’ falls back to docs/contributors-fallback.json
  • All pages fetched if contributor count > 100
  • Top-3 rank badges rendered (πŸ₯‡ πŸ₯ˆ πŸ₯‰)
  • Skeleton loading state shown during fetch
  • Network error state shown if all fallbacks fail
  • docs/contributors-fallback.json committed with current real contributor list
  • jobs.json schema unchanged
  • No new external JS libraries
  • Edge cases: 0 contributors, API timeout, malformed JSON, rate limit on second visit
  • pre-commit run --all-files passes
  • Existing tests pass (make test)
  • PR linked with Fixes #<number>
  • PR title: feat(frontend): integrate GitHub API into Hall of Fame with localStorage caching and rate-limit fallback

Area: 🌐 Frontend / website (docs/)

πŸ”— Additional Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    advancedRequires deep scraper knowledge; high-impact changecommunityCommunity features: sponsors, hall-of-famehall-of-fameContributor Hall of Fame featurehelp wantedExtra attention needed from the communityneeds-triageAwaiting maintainer review and categorizationtype: enhancementNew feature or requestui/uxFrontend UI and UX improvements

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions