Add admin challenge acceptance functionality: Implement adminAcceptChallenge method in ChallengeService, allowing admins to accept pending challenges. Update ChallengeManagement component to include a button for accepting challenges, enhancing admin capabilities and user feedback handling.
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 4m48s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 4m48s
This commit is contained in:
@@ -234,3 +234,37 @@ export async function reactivateChallenge(challengeId: string) {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function adminAcceptChallenge(challengeId: string) {
|
||||
try {
|
||||
await checkAdminAccess();
|
||||
|
||||
const challenge = await challengeService.adminAcceptChallenge(challengeId);
|
||||
|
||||
revalidatePath("/admin");
|
||||
revalidatePath("/challenges");
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: "Défi accepté avec succès",
|
||||
data: challenge,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Admin accept challenge error:", error);
|
||||
|
||||
if (error instanceof ValidationError) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
if (error instanceof NotFoundError) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
if (error instanceof Error && error.message.includes("Accès refusé")) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: "Une erreur est survenue lors de l'acceptation du défi",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
deleteChallenge,
|
||||
adminCancelChallenge,
|
||||
reactivateChallenge,
|
||||
adminAcceptChallenge,
|
||||
} from "@/actions/admin/challenges";
|
||||
import {
|
||||
Button,
|
||||
@@ -226,6 +227,29 @@ export default function ChallengeManagement() {
|
||||
});
|
||||
};
|
||||
|
||||
const handleAdminAccept = async (challengeId: string) => {
|
||||
if (
|
||||
!confirm(
|
||||
"Êtes-vous sûr de vouloir accepter ce défi à la place de l'utilisateur ?"
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
startTransition(async () => {
|
||||
const result = await adminAcceptChallenge(challengeId);
|
||||
|
||||
if (result.success) {
|
||||
setSuccessMessage("Défi accepté avec succès");
|
||||
fetchChallenges();
|
||||
setTimeout(() => setSuccessMessage(null), 5000);
|
||||
} else {
|
||||
setErrorMessage(result.error || "Erreur lors de l'acceptation");
|
||||
setTimeout(() => setErrorMessage(null), 5000);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="text-center text-pixel-gold py-8">Chargement...</div>
|
||||
@@ -376,6 +400,16 @@ export default function ChallengeManagement() {
|
||||
>
|
||||
Modifier
|
||||
</Button>
|
||||
{challenge.status === "PENDING" && (
|
||||
<Button
|
||||
onClick={() => handleAdminAccept(challenge.id)}
|
||||
variant="primary"
|
||||
size="sm"
|
||||
disabled={isPending}
|
||||
>
|
||||
Accepter le défi
|
||||
</Button>
|
||||
)}
|
||||
{challenge.status === "ACCEPTED" && (
|
||||
<Button
|
||||
onClick={() => setSelectedChallenge(challenge)}
|
||||
|
||||
@@ -120,6 +120,34 @@ export class ChallengeService {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepte un défi en tant qu'admin (bypass les vérifications utilisateur)
|
||||
*/
|
||||
async adminAcceptChallenge(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 en attente
|
||||
if (challenge.status !== "PENDING") {
|
||||
throw new ValidationError(
|
||||
"Ce défi ne peut plus être accepté (statut: " + challenge.status + ")"
|
||||
);
|
||||
}
|
||||
|
||||
return prisma.challenge.update({
|
||||
where: { id: challengeId },
|
||||
data: {
|
||||
status: "ACCEPTED",
|
||||
acceptedAt: new Date(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Annule un défi (par le challenger ou le challenged)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user