generated from nhcarrigan/template
f839059dd2
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
59 lines
1.5 KiB
TypeScript
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}`);
|
|
}
|
|
}
|