Skip to content

feat: add a GET /api/stats endpoint to server.js that returns aggregate leaderboard statistics β€” the dashboard currently shows no summary metrics (total users, total problems solved, most active week, etc.)Β #296

Description

@divyanshim27

πŸš€ Problem Statement

The leaderboard frontend shows a table of individual student rankings but has no aggregate statistics panel. A student or club admin visiting the site cannot immediately see:

  • Total number of registered students
  • Total problems solved across all students
  • Average problems solved per student
  • How many students solved at least one problem this week
  • The most popular difficulty level (Easy/Medium/Hard ratio)

These summary stats would make the leaderboard feel alive and motivating β€” rather than just a static sorted table. They also give the CodePVG club admins a quick pulse check on overall club activity.

Proposed Fix

Backend β€” add GET /api/stats to server.js

// server.js

app.get('/api/stats', async (req, res) => {
  try {
    const users = await loadLeaderboardData(); // existing function

    const stats = users.reduce((acc, user) => {
      acc.totalUsers++;
      acc.totalSolved += (user.easySolved || 0) + (user.mediumSolved || 0) + (user.hardSolved || 0);
      acc.totalEasy += user.easySolved || 0;
      acc.totalMedium += user.mediumSolved || 0;
      acc.totalHard += user.hardSolved || 0;
      if ((user.easySolved + user.mediumSolved + user.hardSolved) > 0) acc.activeUsers++;
      return acc;
    }, { totalUsers: 0, totalSolved: 0, totalEasy: 0, totalMedium: 0, totalHard: 0, activeUsers: 0 });

    res.json({
      ...stats,
      avgSolvedPerUser: stats.totalUsers > 0
        ? (stats.totalSolved / stats.totalUsers).toFixed(1)
        : 0,
      difficultyRatio: {
        easy: ((stats.totalEasy / stats.totalSolved) * 100).toFixed(1) + '%',
        medium: ((stats.totalMedium / stats.totalSolved) * 100).toFixed(1) + '%',
        hard: ((stats.totalHard / stats.totalSolved) * 100).toFixed(1) + '%',
      },
      lastUpdated: new Date().toISOString(),
    });
  } catch (err) {
    res.status(500).json({ error: 'Failed to compute stats' });
  }
});

Frontend β€” add a stats banner above the leaderboard table

<!-- frontend/ β€” add above the leaderboard table -->
<div id="stats-banner" class="stats-grid">
  <div class="stat-card">
    <span class="stat-value" id="stat-total-users">β€”</span>
    <span class="stat-label">Registered Students</span>
  </div>
  <div class="stat-card">
    <span class="stat-value" id="stat-total-solved">β€”</span>
    <span class="stat-label">Problems Solved</span>
  </div>
  <div class="stat-card">
    <span class="stat-value" id="stat-avg-solved">β€”</span>
    <span class="stat-label">Avg per Student</span>
  </div>
  <div class="stat-card">
    <span class="stat-value" id="stat-active-users">β€”</span>
    <span class="stat-label">Active Students</span>
  </div>
</div>
// Fetch and display stats
fetch('/api/stats')
  .then(r => r.json())
  .then(stats => {
    document.getElementById('stat-total-users').textContent = stats.totalUsers;
    document.getElementById('stat-total-solved').textContent = stats.totalSolved.toLocaleString();
    document.getElementById('stat-avg-solved').textContent = stats.avgSolvedPerUser;
    document.getElementById('stat-active-users').textContent = stats.activeUsers;
  });

Files to Modify

File Change
server.js Add GET /api/stats endpoint
frontend/ (leaderboard HTML) Add stats banner with 4 stat cards
frontend/ (leaderboard JS) Fetch stats and populate cards
frontend/ (leaderboard CSS) Style .stats-grid and .stat-card

Suggested labels: enhancement, frontend, backend, level: beginner

I would like to work on this. Could you please assign it to me?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions