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
Some checks failed
Deploy with Docker Compose / deploy (push) Has been cancelled
This commit is contained in:
@@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user