Add house leaderboard feature: Integrate house leaderboard functionality in LeaderboardPage and LeaderboardSection components. Update userStatsService to fetch house leaderboard data, and enhance UI to display house rankings, scores, and member details. Update Prisma schema to include house-related models and relationships, and seed database with initial house data.
Some checks failed
Deploy with Docker Compose / deploy (push) Has been cancelled

This commit is contained in:
Julien Froidefond
2025-12-17 13:35:18 +01:00
parent cb02b494f4
commit 85ee812ab1
36 changed files with 5422 additions and 13 deletions

View File

@@ -27,6 +27,26 @@ export interface LeaderboardEntry {
characterClass: CharacterClass | null;
}
export interface HouseMember {
id: string;
username: string;
avatar: string | null;
score: number;
level: number;
role: string;
}
export interface HouseLeaderboardEntry {
rank: number;
houseId: string;
houseName: string;
totalScore: number;
memberCount: number;
averageScore: number;
description: string | null;
members: HouseMember[];
}
/**
* Service de gestion des statistiques utilisateur
*/
@@ -64,6 +84,72 @@ export class UserStatsService {
}));
}
/**
* Récupère le leaderboard par maison
*/
async getHouseLeaderboard(limit: number = 10): Promise<HouseLeaderboardEntry[]> {
// Récupérer toutes les maisons avec leurs membres et leurs scores
const houses = await prisma.house.findMany({
include: {
memberships: {
include: {
user: {
select: {
id: true,
username: true,
avatar: true,
score: true,
level: true,
},
},
},
orderBy: [
{ role: "asc" }, // OWNER, ADMIN, MEMBER
{ user: { score: "desc" } }, // Puis par score décroissant
],
},
},
});
// Calculer le score total et la moyenne pour chaque maison
const houseStats = houses
.map((house) => {
const memberScores = house.memberships.map((m) => m.user.score);
const totalScore = memberScores.reduce((sum, score) => sum + score, 0);
const memberCount = house.memberships.length;
const averageScore = memberCount > 0 ? Math.floor(totalScore / memberCount) : 0;
// Mapper les membres avec leurs détails
const members: HouseMember[] = house.memberships.map((membership) => ({
id: membership.user.id,
username: membership.user.username,
avatar: membership.user.avatar,
score: membership.user.score,
level: membership.user.level,
role: membership.role,
}));
return {
houseId: house.id,
houseName: house.name,
totalScore,
memberCount,
averageScore,
description: house.description,
members,
};
})
.filter((house) => house.memberCount > 0) // Exclure les maisons sans membres
.sort((a, b) => b.totalScore - a.totalScore) // Trier par score total décroissant
.slice(0, limit) // Limiter le nombre de résultats
.map((house, index) => ({
rank: index + 1,
...house,
}));
return houseStats;
}
/**
* Met à jour les statistiques d'un utilisateur
*/