diff --git a/actions/admin/challenges.ts b/actions/admin/challenges.ts index 268b4d0..6fbafc5 100644 --- a/actions/admin/challenges.ts +++ b/actions/admin/challenges.ts @@ -1,20 +1,17 @@ -'use server' +"use server"; -import { revalidatePath } from 'next/cache' -import { auth } from '@/lib/auth' -import { challengeService } from '@/services/challenges/challenge.service' -import { Role } from '@/prisma/generated/prisma/client' -import { - ValidationError, - NotFoundError, -} from '@/services/errors' +import { revalidatePath } from "next/cache"; +import { auth } from "@/lib/auth"; +import { challengeService } from "@/services/challenges/challenge.service"; +import { Role } from "@/prisma/generated/prisma/client"; +import { ValidationError, NotFoundError } from "@/services/errors"; async function checkAdminAccess() { - const session = await auth() + const session = await auth(); if (!session?.user || session.user.role !== Role.ADMIN) { - throw new Error('Accès refusé - Admin uniquement') + throw new Error("Accès refusé - Admin uniquement"); } - return session + return session; } export async function validateChallenge( @@ -23,34 +20,41 @@ export async function validateChallenge( adminComment?: string ) { try { - const session = await checkAdminAccess() + const session = await checkAdminAccess(); const challenge = await challengeService.validateChallenge( challengeId, session.user.id, winnerId, adminComment - ) + ); - revalidatePath('/admin') - revalidatePath('/challenges') - revalidatePath('/leaderboard') + revalidatePath("/admin"); + revalidatePath("/challenges"); + revalidatePath("/leaderboard"); - return { success: true, message: 'Défi validé avec succès', data: challenge } + return { + success: true, + message: "Défi validé avec succès", + data: challenge, + }; } catch (error) { - console.error('Validate challenge error:', error) + console.error("Validate challenge error:", error); if (error instanceof ValidationError) { - return { success: false, error: error.message } + return { success: false, error: error.message }; } if (error instanceof NotFoundError) { - return { success: false, error: error.message } + return { success: false, error: error.message }; } - if (error instanceof Error && error.message.includes('Accès refusé')) { - 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 la validation du défi' } + return { + success: false, + error: "Une erreur est survenue lors de la validation du défi", + }; } } @@ -59,94 +63,106 @@ export async function rejectChallenge( adminComment?: string ) { try { - const session = await checkAdminAccess() + const session = await checkAdminAccess(); const challenge = await challengeService.rejectChallenge( challengeId, session.user.id, adminComment - ) + ); - revalidatePath('/admin') - revalidatePath('/challenges') + revalidatePath("/admin"); + revalidatePath("/challenges"); - return { success: true, message: 'Défi rejeté', data: challenge } + return { success: true, message: "Défi rejeté", data: challenge }; } catch (error) { - console.error('Reject challenge error:', error) + console.error("Reject challenge error:", error); if (error instanceof ValidationError) { - return { success: false, error: error.message } + return { success: false, error: error.message }; } if (error instanceof NotFoundError) { - return { success: false, error: error.message } + return { success: false, error: error.message }; } - if (error instanceof Error && error.message.includes('Accès refusé')) { - 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 du rejet du défi' } + return { + success: false, + error: "Une erreur est survenue lors du rejet du défi", + }; } } export async function updateChallenge( challengeId: string, data: { - title?: string - description?: string - pointsReward?: number + title?: string; + description?: string; + pointsReward?: number; } ) { try { - await checkAdminAccess() + await checkAdminAccess(); const challenge = await challengeService.updateChallenge(challengeId, { title: data.title, description: data.description, pointsReward: data.pointsReward, - }) + }); - revalidatePath('/admin') - revalidatePath('/challenges') + revalidatePath("/admin"); + revalidatePath("/challenges"); - return { success: true, message: 'Défi mis à jour avec succès', data: challenge } + return { + success: true, + message: "Défi mis à jour avec succès", + data: challenge, + }; } catch (error) { - console.error('Update challenge error:', error) + console.error("Update challenge error:", error); if (error instanceof ValidationError) { - return { success: false, error: error.message } + return { success: false, error: error.message }; } if (error instanceof NotFoundError) { - return { success: false, error: error.message } + return { success: false, error: error.message }; } - if (error instanceof Error && error.message.includes('Accès refusé')) { - 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 la mise à jour du défi' } + return { + success: false, + error: "Une erreur est survenue lors de la mise à jour du défi", + }; } } export async function deleteChallenge(challengeId: string) { try { - await checkAdminAccess() + await checkAdminAccess(); - await challengeService.deleteChallenge(challengeId) + await challengeService.deleteChallenge(challengeId); - revalidatePath('/admin') - revalidatePath('/challenges') + revalidatePath("/admin"); + revalidatePath("/challenges"); - return { success: true, message: 'Défi supprimé avec succès' } + return { success: true, message: "Défi supprimé avec succès" }; } catch (error) { - console.error('Delete challenge error:', error) + console.error("Delete challenge error:", error); if (error instanceof NotFoundError) { - return { success: false, error: error.message } + return { success: false, error: error.message }; } - if (error instanceof Error && error.message.includes('Accès refusé')) { - 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 la suppression du défi' } + return { + success: false, + error: "Une erreur est survenue lors de la suppression du défi", + }; } } - diff --git a/components/admin/ChallengeManagement.tsx b/components/admin/ChallengeManagement.tsx index 3ec11d2..234f623 100644 --- a/components/admin/ChallengeManagement.tsx +++ b/components/admin/ChallengeManagement.tsx @@ -1,7 +1,12 @@ "use client"; import { useEffect, useState, useTransition } from "react"; -import { validateChallenge, rejectChallenge, updateChallenge, deleteChallenge } from "@/actions/admin/challenges"; +import { + validateChallenge, + rejectChallenge, + updateChallenge, + deleteChallenge, +} from "@/actions/admin/challenges"; import { Button, Card, Input, Textarea, Alert } from "@/components/ui"; import { Avatar } from "@/components/ui"; @@ -29,8 +34,12 @@ interface Challenge { export default function ChallengeManagement() { const [challenges, setChallenges] = useState([]); const [loading, setLoading] = useState(true); - const [selectedChallenge, setSelectedChallenge] = useState(null); - const [editingChallenge, setEditingChallenge] = useState(null); + const [selectedChallenge, setSelectedChallenge] = useState( + null + ); + const [editingChallenge, setEditingChallenge] = useState( + null + ); const [winnerId, setWinnerId] = useState(""); const [adminComment, setAdminComment] = useState(""); const [editTitle, setEditTitle] = useState(""); @@ -73,7 +82,9 @@ export default function ChallengeManagement() { ); if (result.success) { - setSuccessMessage("Défi validé avec succès ! Les points ont été attribués."); + setSuccessMessage( + "Défi validé avec succès ! Les points ont été attribués." + ); setSelectedChallenge(null); setWinnerId(""); setAdminComment(""); @@ -145,7 +156,11 @@ export default function ChallengeManagement() { }; const handleDelete = async (challengeId: string) => { - if (!confirm("Êtes-vous sûr de vouloir supprimer ce défi ? Cette action est irréversible.")) { + if ( + !confirm( + "Êtes-vous sûr de vouloir supprimer ce défi ? Cette action est irréversible." + ) + ) { return; } @@ -193,10 +208,12 @@ export default function ChallengeManagement() { )}
- {acceptedChallenges.length} défi{acceptedChallenges.length > 1 ? "s" : ""} en attente de validation + {acceptedChallenges.length} défi + {acceptedChallenges.length > 1 ? "s" : ""} en attente de validation {pendingChallenges.length > 0 && ( - • {pendingChallenges.length} défi{pendingChallenges.length > 1 ? "s" : ""} en attente d'acceptation + • {pendingChallenges.length} défi + {pendingChallenges.length > 1 ? "s" : ""} en attente d'acceptation )}
@@ -233,20 +250,28 @@ export default function ChallengeManagement() {
- Récompense: {challenge.pointsReward} points + Récompense:{" "} + + {challenge.pointsReward} points +
- - {challenge.status === "ACCEPTED" ? "Accepté" : "En attente d'acceptation"} + + {challenge.status === "ACCEPTED" + ? "Accepté" + : "En attente d'acceptation"}
{challenge.acceptedAt && (
- Accepté le: {new Date(challenge.acceptedAt).toLocaleDateString("fr-FR")} + Accepté le:{" "} + {new Date(challenge.acceptedAt).toLocaleDateString("fr-FR")}
)} @@ -466,7 +491,9 @@ export default function ChallengeManagement() { type="number" min="1" value={editPointsReward} - onChange={(e) => setEditPointsReward(parseInt(e.target.value) || 0)} + onChange={(e) => + setEditPointsReward(parseInt(e.target.value) || 0) + } required placeholder="100" /> @@ -475,7 +502,12 @@ export default function ChallengeManagement() {