Add admin challenge management features: Implement functions for canceling and reactivating challenges, enhance error handling, and update the ChallengeManagement component to support these actions. Update API to retrieve all challenge statuses for admin and improve UI to display active challenges count.
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 6m16s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 6m16s
This commit is contained in:
@@ -306,6 +306,63 @@ export class ChallengeService {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Annule un défi (admin seulement)
|
||||
*/
|
||||
async adminCancelChallenge(challengeId: string): Promise<Challenge> {
|
||||
const challenge = await prisma.challenge.findUnique({
|
||||
where: { id: challengeId },
|
||||
});
|
||||
|
||||
if (!challenge) {
|
||||
throw new NotFoundError("Défi");
|
||||
}
|
||||
|
||||
// Vérifier que le défi peut être annulé
|
||||
if (challenge.status === "COMPLETED") {
|
||||
throw new ValidationError("Un défi complété ne peut pas être annulé");
|
||||
}
|
||||
|
||||
return prisma.challenge.update({
|
||||
where: { id: challengeId },
|
||||
data: {
|
||||
status: "CANCELLED",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Réactive un défi annulé (admin seulement)
|
||||
* Remet le défi en PENDING s'il n'avait jamais été accepté, sinon en ACCEPTED
|
||||
*/
|
||||
async reactivateChallenge(challengeId: string): Promise<Challenge> {
|
||||
const challenge = await prisma.challenge.findUnique({
|
||||
where: { id: challengeId },
|
||||
});
|
||||
|
||||
if (!challenge) {
|
||||
throw new NotFoundError("Défi");
|
||||
}
|
||||
|
||||
// Vérifier que le défi est annulé
|
||||
if (challenge.status !== "CANCELLED") {
|
||||
throw new ValidationError(
|
||||
"Seuls les défis annulés peuvent être réactivés"
|
||||
);
|
||||
}
|
||||
|
||||
// Si le défi avait été accepté avant, le remettre en ACCEPTED
|
||||
// Sinon, le remettre en PENDING
|
||||
const newStatus = challenge.acceptedAt ? "ACCEPTED" : "PENDING";
|
||||
|
||||
return prisma.challenge.update({
|
||||
where: { id: challengeId },
|
||||
data: {
|
||||
status: newStatus,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime un défi (admin seulement)
|
||||
*/
|
||||
@@ -405,7 +462,7 @@ export class ChallengeService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère les défis en attente de validation admin
|
||||
* Récupère les défis acceptés en attente de désignation du gagnant
|
||||
*/
|
||||
async getPendingValidationChallenges(): Promise<ChallengeWithUsers[]> {
|
||||
return prisma.challenge.findMany({
|
||||
@@ -489,6 +546,30 @@ export class ChallengeService {
|
||||
take: options?.take,
|
||||
}) as Promise<ChallengeWithUsers[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compte les défis actifs pour un utilisateur
|
||||
* - PENDING où l'utilisateur est challenged (en attente de sa réponse)
|
||||
* - ACCEPTED où l'utilisateur est challenger ou challenged (en cours, en attente de validation)
|
||||
*/
|
||||
async getActiveChallengesCount(userId: string): Promise<number> {
|
||||
return prisma.challenge.count({
|
||||
where: {
|
||||
OR: [
|
||||
// Défis en attente de réponse de l'utilisateur
|
||||
{
|
||||
status: "PENDING",
|
||||
challengedId: userId,
|
||||
},
|
||||
// Défis acceptés en cours (en attente de désignation du gagnant)
|
||||
{
|
||||
status: "ACCEPTED",
|
||||
OR: [{ challengerId: userId }, { challengedId: userId }],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const challengeService = new ChallengeService();
|
||||
|
||||
Reference in New Issue
Block a user