Files
library/apps/frontend/src/app/services/leaderboard.service.ts
T
hikari f839059dd2 feat: implement comprehensive leaderboard feature
Implements issue #55 with multiple leaderboard categories:
- Top Suggestions (by count and acceptance rate)
- Top Likes (by total likes given)
- Top Comments (by total comments posted)
- Overall Leaders (weighted by achievement points and engagement diversity)

Features:
- Tabbed UI with reactive state management
- Medal indicators for top 3 positions
- User avatars and badges display
- Current user highlighting
- Privacy controls via profilePublic setting
- Configurable result limits (max 100)
- Detailed statistics per category

Backend:
- Created LeaderboardService with aggregation logic
- Filters for public profiles and non-banned users
- Efficient sorting algorithms for each category
- Parallel data fetching for all leaderboards

Frontend:
- Standalone Angular component with signals
- Responsive card-based layout
- Integration with existing user profile system
- Navigation link in header dropdown

Technical notes:
- Uses Fastify AutoLoad with FastifyPluginAsync pattern
- Shared types across monorepo for type safety
- Leverages existing achievement system data
2026-02-19 23:31:41 -08:00

59 lines
1.5 KiB
TypeScript

/**
* @copyright 2026 NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Injectable, inject } from '@angular/core';
import { Observable } from 'rxjs';
import type {
LeaderboardResponse,
SuggestionsLeaderboard,
LikesLeaderboard,
CommentsLeaderboard,
OverallLeaderboard,
} from '@library/shared-types';
import { ApiService } from './api.service';
@Injectable({
providedIn: 'root'
})
export class LeaderboardService {
private apiService = inject(ApiService);
/**
* Get all leaderboards at once.
*/
getAllLeaderboards(limit = 25): Observable<LeaderboardResponse> {
return this.apiService.get<LeaderboardResponse>(`/leaderboard?limit=${limit}`);
}
/**
* Get top users by suggestions.
*/
getTopSuggestions(limit = 25): Observable<SuggestionsLeaderboard[]> {
return this.apiService.get<SuggestionsLeaderboard[]>(`/leaderboard/suggestions?limit=${limit}`);
}
/**
* Get top users by likes.
*/
getTopLikes(limit = 25): Observable<LikesLeaderboard[]> {
return this.apiService.get<LikesLeaderboard[]>(`/leaderboard/likes?limit=${limit}`);
}
/**
* Get top users by comments.
*/
getTopComments(limit = 25): Observable<CommentsLeaderboard[]> {
return this.apiService.get<CommentsLeaderboard[]>(`/leaderboard/comments?limit=${limit}`);
}
/**
* Get overall leaderboard.
*/
getOverallLeaderboard(limit = 25): Observable<OverallLeaderboard[]> {
return this.apiService.get<OverallLeaderboard[]>(`/leaderboard/overall?limit=${limit}`);
}
}