project-standalo-todo-super/app/api/leaderboard/route.ts

72 lines
1.9 KiB
TypeScript

/**
* GET /api/leaderboard - Get top users by points
*/
import { NextRequest, NextResponse } from 'next/server';
import { getCurrentUser } from '@/app/lib/auth';
import { getAllUsers, getUserBalance, getUserCompletedTasks, getUserBadges } from '@/app/lib/db/store';
import { LeaderboardResponse, LeaderboardEntry, ApiResponse } from '@/app/lib/types';
export async function GET(request: NextRequest) {
try {
// Get current user (optional - for user rank)
const currentUser = getCurrentUser(request);
// Get all users
const users = getAllUsers();
// Build leaderboard entries
const entries: LeaderboardEntry[] = users
.map(user => ({
userId: user.id,
userName: user.name,
points: getUserBalance(user.id),
tasksCompleted: getUserCompletedTasks(user.id).length,
badgesEarned: getUserBadges(user.id).length,
rank: 0 // Will be set after sorting
}))
.sort((a, b) => {
// Sort by points descending, then by tasks completed
if (b.points !== a.points) {
return b.points - a.points;
}
return b.tasksCompleted - a.tasksCompleted;
})
.map((entry, index) => ({
...entry,
rank: index + 1
}));
// Get top 100 entries
const topEntries = entries.slice(0, 100);
// Find current user's rank
let userRank: LeaderboardEntry | undefined;
if (currentUser) {
userRank = entries.find(entry => entry.userId === currentUser.id);
}
const response: LeaderboardResponse = {
entries: topEntries,
userRank
};
return NextResponse.json<ApiResponse<LeaderboardResponse>>(
{
success: true,
data: response
},
{ status: 200 }
);
} catch (error) {
console.error('Get leaderboard error:', error);
return NextResponse.json<ApiResponse>(
{
success: false,
error: 'Internal server error'
},
{ status: 500 }
);
}
}