'use client'; import { useState, useEffect, useMemo } from 'react'; import { adminService } from '@/services/admin.service'; import { Prize, CreatePrizeData, UpdatePrizeData } from '@/types'; import { Gift, Package, Trophy, Percent, Archive, RefreshCw, X } from 'lucide-react'; export default function PrizeManagement() { const [prizes, setPrizes] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const [editingPrize, setEditingPrize] = useState(null); // Form state const [formData, setFormData] = useState({ name: '', type: 'PHYSICAL', description: '', value: '', probability: 0, stock: 0, }); useEffect(() => { loadPrizes(); }, []); const loadPrizes = async () => { try { setLoading(true); setError(null); const data = await adminService.getAllPrizes(); setPrizes(data || []); } catch (err: any) { setError(err.message || 'Erreur lors du chargement des prix'); setPrizes([]); } finally { setLoading(false); } }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); try { if (editingPrize) { await adminService.updatePrize(editingPrize.id, formData as UpdatePrizeData); } else { await adminService.createPrize(formData); } resetForm(); loadPrizes(); } catch (err: any) { alert(err.message || 'Erreur lors de la sauvegarde'); } }; const handleEdit = (prize: Prize) => { setEditingPrize(prize); setFormData({ name: prize.name, type: prize.type, description: prize.description, value: prize.value, probability: prize.probability, stock: prize.stock, }); setIsModalOpen(true); }; const handleDelete = async (prizeId: string) => { if (!confirm('Êtes-vous sûr de vouloir supprimer ce prix ?')) return; try { await adminService.deletePrize(prizeId); loadPrizes(); } catch (err: any) { alert(err.message || 'Erreur lors de la suppression'); } }; const resetForm = () => { setFormData({ name: '', type: 'PHYSICAL', description: '', value: '', probability: 0, stock: 0, }); setEditingPrize(null); setIsModalOpen(false); }; // Calculer les stats const prizeStats = useMemo(() => { const totalStock = prizes.reduce((acc, p) => acc + Number(p.initialStock || p.stock || 0), 0); const totalUsed = prizes.reduce((acc, p) => acc + Number(p.ticketsUsed || 0), 0); const activeCount = prizes.filter(p => p.isActive).length; return { totalStock, totalUsed, activeCount, totalPrizes: prizes.length }; }, [prizes]); // Fonction pour obtenir l'icône et la couleur selon le type const getPrizeStyle = (type: string) => { switch (type) { case 'GRAND_PRIZE': return { bg: 'from-purple-500 to-purple-600', icon: Trophy, color: 'purple' }; case 'PHYSICAL': return { bg: 'from-blue-500 to-blue-600', icon: Package, color: 'blue' }; default: return { bg: 'from-emerald-500 to-emerald-600', icon: Gift, color: 'emerald' }; } }; if (loading) { return (

Chargement des lots...

); } return (
{/* Stats rapides */}

{prizeStats.totalPrizes.toLocaleString('fr-FR')}

Total Lots

{prizeStats.totalStock.toLocaleString('fr-FR')}

Stock Total

{prizeStats.totalUsed.toLocaleString('fr-FR')}

Distribués

{prizeStats.totalStock > 0 ? ((prizeStats.totalUsed / prizeStats.totalStock) * 100).toFixed(1) : '0.0'}%

Taux distrib.

{error && (
{error}
)} {/* Liste des prix */} {prizes.length === 0 ? (

Aucun lot trouvé

) : (
{prizes.map((prize) => { const style = getPrizeStyle(prize.type); const IconComponent = style.icon; const stockRemaining = Number(prize.initialStock || 0) - Number(prize.ticketsUsed || 0); return (
{/* Header avec gradient */}

{prize.name}

{prize.isActive ? 'Actif' : 'Inactif'}
{/* Contenu */}

{prize.description}

{/* Affichage spécial pour le Grand Prix */} {prize.type === 'GRAND_PRIZE' ? (
TIRAGE AU SORT

Attribué lors du tirage final parmi les participants éligibles

) : (
{/* Probabilité */}
Probabilité {(prize.probability * 100).toFixed(1)}%
{/* Stock */}
Stock {stockRemaining.toLocaleString('fr-FR')} / {(prize.initialStock || prize.stock || 0).toLocaleString('fr-FR')}
0 ? (stockRemaining / (prize.initialStock || prize.stock)) * 100 : 0)}%` }} >
{/* Tickets utilisés */} {prize.ticketsUsed !== undefined && prize.ticketsUsed > 0 && (
Distribués {prize.ticketsUsed.toLocaleString('fr-FR')}
)}
)}
); })}
)}
); }