'use client'; import { useState, useEffect } from 'react'; import Link from 'next/link'; import { useParams } from 'next/navigation'; import { Campaign, Participant, ParticipantWithVoteStatus } from '@/types'; import { campaignService, participantService, voteService } from '@/lib/services'; import AddParticipantModal from '@/components/AddParticipantModal'; import EditParticipantModal from '@/components/EditParticipantModal'; import DeleteParticipantModal from '@/components/DeleteParticipantModal'; import ImportFileModal from '@/components/ImportFileModal'; import SendParticipantEmailModal from '@/components/SendParticipantEmailModal'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Avatar, AvatarFallback } from '@/components/ui/avatar'; import { Input } from '@/components/ui/input'; import Navigation from '@/components/Navigation'; import AuthGuard from '@/components/AuthGuard'; import { User, Calendar, Mail, Vote, Copy, Check, Upload } from 'lucide-react'; export const dynamic = 'force-dynamic'; function CampaignParticipantsPageContent() { const params = useParams(); const campaignId = params.id as string; const [campaign, setCampaign] = useState(null); const [participants, setParticipants] = useState([]); const [loading, setLoading] = useState(true); const [showAddModal, setShowAddModal] = useState(false); const [showEditModal, setShowEditModal] = useState(false); const [showDeleteModal, setShowDeleteModal] = useState(false); const [showImportModal, setShowImportModal] = useState(false); const [showSendEmailModal, setShowSendEmailModal] = useState(false); const [selectedParticipant, setSelectedParticipant] = useState(null); const [copiedParticipantId, setCopiedParticipantId] = useState(null); useEffect(() => { // Vérifier la configuration Supabase const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; // Si pas de configuration ou valeurs par défaut, rediriger vers setup if (!supabaseUrl || !supabaseAnonKey || supabaseUrl === 'https://placeholder.supabase.co' || supabaseAnonKey === 'your-anon-key') { console.log('🔧 Configuration Supabase manquante, redirection vers /setup'); window.location.href = '/setup'; return; } loadData(); }, [campaignId]); const loadData = async () => { try { setLoading(true); const [campaignData, participantsWithVoteStatus] = await Promise.all([ campaignService.getById(campaignId), voteService.getParticipantVoteStatus(campaignId) ]); setCampaign(campaignData); setParticipants(participantsWithVoteStatus); } catch (error) { console.error('Erreur lors du chargement des données:', error); } finally { setLoading(false); } }; const handleParticipantAdded = () => { setShowAddModal(false); loadData(); }; const handleParticipantEdited = () => { setShowEditModal(false); loadData(); }; const handleParticipantDeleted = () => { setShowDeleteModal(false); loadData(); }; const handleImportParticipants = async (data: any[]) => { try { const participantsToCreate = data.map(row => ({ campaign_id: campaignId, first_name: row.first_name || '', last_name: row.last_name || '', email: row.email || '' })); // Créer les participants un par un for (const participant of participantsToCreate) { await participantService.create(participant); } loadData(); } catch (error) { console.error('Erreur lors de l\'import des participants:', error); } }; const getInitials = (firstName: string, lastName: string) => { return `${firstName.charAt(0)}${lastName.charAt(0)}`.toUpperCase(); }; const copyVoteLink = (participantId: string, shortId?: string) => { // Utiliser le lien court si disponible, sinon le lien long const voteUrl = shortId ? `${window.location.origin}/v/${shortId}` : `${window.location.origin}/campaigns/${campaignId}/vote/${participantId}`; navigator.clipboard.writeText(voteUrl); setCopiedParticipantId(participantId); setTimeout(() => setCopiedParticipantId(null), 2000); }; if (loading) { return (

Chargement des participants...

); } if (!campaign) { return (

Campagne introuvable

La campagne que vous recherchez n'existe pas ou a été supprimée.

); } return (
{/* Header */}

Participants

{campaign.title}

{/* Participants List */} {participants.length === 0 ? (

Aucun participant

Aucun participant n'a encore été ajouté à cette campagne.

) : (
{participants.map((participant) => (
{participant.first_name} {participant.last_name} {participant.has_voted ? 'A voté' : 'N\'a pas voté'}
{getInitials(participant.first_name, participant.last_name)}
{participant.email}
{new Date(participant.created_at).toLocaleDateString('fr-FR')}
{participant.has_voted && participant.total_voted_amount !== undefined && (
{participant.total_voted_amount}€ votés
)}
{/* Vote Link for voting campaigns */} {campaign.status === 'voting' && (
Lien de vote :
)}
))}
)} {/* Modals */} setShowAddModal(false)} onSuccess={handleParticipantAdded} campaignId={campaignId} /> {selectedParticipant && ( setShowEditModal(false)} onSuccess={handleParticipantEdited} participant={selectedParticipant} /> )} {selectedParticipant && ( setShowDeleteModal(false)} onSuccess={handleParticipantDeleted} participant={selectedParticipant} /> )} setShowImportModal(false)} onImport={handleImportParticipants} type="participants" campaignTitle={campaign?.title} /> {selectedParticipant && campaign && ( setShowSendEmailModal(false)} participant={selectedParticipant} campaign={campaign} /> )}
); } export default function CampaignParticipantsPage() { return ( ); }