'use client'; import { useState, useEffect, useMemo, useRef } from 'react'; import { parseCSVFromText, Person } from '@/lib/csv-parser-client'; const STORAGE_KEY = 'people-randomizr-data'; export default function Home() { const [people, setPeople] = useState([]); const [loading, setLoading] = useState(true); const [selectedCount, setSelectedCount] = useState(5); const [selectedPostes, setSelectedPostes] = useState>(new Set()); const [randomPeople, setRandomPeople] = useState([]); const [showResults, setShowResults] = useState(false); const [searchPoste, setSearchPoste] = useState(''); const [hasData, setHasData] = useState(false); const fileInputRef = useRef(null); // Charger les données depuis localStorage au démarrage useEffect(() => { try { const stored = localStorage.getItem(STORAGE_KEY); if (stored) { const data = JSON.parse(stored); setPeople(data); setHasData(true); } } catch (error) { console.error('Error loading from localStorage:', error); } finally { setLoading(false); } }, []); // Sauvegarder dans localStorage quand les données changent useEffect(() => { if (people.length > 0) { localStorage.setItem(STORAGE_KEY, JSON.stringify(people)); setHasData(true); } }, [people]); const handleFileUpload = (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (!file) return; if (!file.name.endsWith('.csv')) { alert('Veuillez sélectionner un fichier CSV'); return; } const reader = new FileReader(); reader.onload = (e) => { try { const content = e.target?.result as string; const parsed = parseCSVFromText(content); setPeople(parsed); setSelectedPostes(new Set()); setShowResults(false); alert(`✅ ${parsed.length} personnes chargées avec succès !`); } catch (error) { console.error('Error parsing CSV:', error); alert('Erreur lors du parsing du CSV. Vérifiez le format du fichier.'); } }; reader.readAsText(file, 'UTF-8'); }; const handleClearData = () => { if (confirm('Êtes-vous sûr de vouloir supprimer toutes les données ?')) { localStorage.removeItem(STORAGE_KEY); setPeople([]); setHasData(false); setSelectedPostes(new Set()); setShowResults(false); if (fileInputRef.current) { fileInputRef.current.value = ''; } } }; // Compter le nombre de personnes par poste const posteCounts = useMemo(() => { const counts: Record = {}; people.forEach(person => { if (person.description) { counts[person.description] = (counts[person.description] || 0) + 1; } }); return counts; }, [people]); // Extraire tous les postes uniques triés par nombre décroissant const allPostes = useMemo(() => { const postes = new Set(); people.forEach(person => { if (person.description) { postes.add(person.description); } }); return Array.from(postes).sort((a, b) => { const countA = posteCounts[a] || 0; const countB = posteCounts[b] || 0; // Tri décroissant par nombre, puis alphabétique si égal if (countA !== countB) { return countB - countA; } return a.localeCompare(b); }); }, [people, posteCounts]); // Filtrer les postes selon la recherche const filteredPostes = useMemo(() => { if (!searchPoste.trim()) { return allPostes; } const searchLower = searchPoste.toLowerCase(); return allPostes.filter(poste => poste.toLowerCase().includes(searchLower) ); }, [allPostes, searchPoste]); // Filtrer les personnes selon les postes sélectionnés const filteredPeople = useMemo(() => { if (selectedPostes.size === 0) { return people; } return people.filter(person => person.description && selectedPostes.has(person.description) ); }, [people, selectedPostes]); const handlePosteToggle = (poste: string) => { const newSelected = new Set(selectedPostes); if (newSelected.has(poste)) { newSelected.delete(poste); } else { newSelected.add(poste); } setSelectedPostes(newSelected); setShowResults(false); }; const handleSelectAll = () => { if (selectedPostes.size === allPostes.length) { setSelectedPostes(new Set()); } else { setSelectedPostes(new Set(allPostes)); } setShowResults(false); }; const handleRandomize = () => { if (selectedCount <= 0 || selectedCount > filteredPeople.length) { alert(`Veuillez entrer un nombre entre 1 et ${filteredPeople.length}`); return; } const shuffled = [...filteredPeople].sort(() => Math.random() - 0.5); const selected = shuffled.slice(0, selectedCount); setRandomPeople(selected); setShowResults(true); }; if (loading) { return (
); } if (!hasData) { return (
{/* Effets de fond animés */}
📊

People Randomizr

Importez votre fichier CSV pour commencer

Le fichier CSV doit contenir les colonnes : Nom, Description, Type

); } return (
{/* Effets de fond animés */}

People Randomizr

Sélection intelligente • Extraction aléatoire

{/* Boutons de gestion de données */}

Filtres par poste

{selectedPostes.size} / {allPostes.length} sélectionné{selectedPostes.size > 1 ? 's' : ''}
{/* Barre de recherche */}
setSearchPoste(e.target.value)} className="w-full px-5 py-3 glass rounded-xl focus:ring-2 focus:ring-cyan-500 focus:border-cyan-400/50 text-white placeholder-gray-400 border border-cyan-500/20 transition-all duration-300" /> {searchPoste && ( )}
{/* Badges de filtres */}
{filteredPostes.length === 0 ? (

Aucun poste trouvé

) : ( filteredPostes.map((poste) => { const isSelected = selectedPostes.has(poste); const count = posteCounts[poste] || 0; return ( ); }) )}
setSelectedCount(parseInt(e.target.value) || 1)} className="w-full px-5 py-3 glass rounded-xl focus:ring-2 focus:ring-cyan-500 focus:border-cyan-400/50 text-white bg-white/5 border border-cyan-500/20 transition-all duration-300" />

{selectedPostes.size === 0 ? ( <>📊 Total disponible: {people.length} personnes ) : ( <>🎯 Total filtré: {filteredPeople.length} personne{filteredPeople.length > 1 ? 's' : ''} (sur {people.length}) )}

{showResults && randomPeople.length > 0 && (

Résultats sélectionnés

{randomPeople.length} personne{randomPeople.length > 1 ? 's' : ''}
{randomPeople.map((person, index) => (

{person.nom}

{person.description && (

{person.description}

)} {person.type}
))}
)}

{selectedPostes.size === 0 ? `Toutes les personnes` : `Personnes filtrées` }

{filteredPeople.length} / {people.length}
{filteredPeople.map((person, index) => (
0 && selectedPostes.has(person.description) ? 'border-cyan-400/50 bg-cyan-500/10 hover:border-cyan-400 hover:shadow-cyan-500/20' : 'border-purple-500/20 hover:border-purple-400/50' }`} >

{person.nom}

{person.description && (

{person.description}

)}
))}
); }