import React, { useMemo } from "react"; import { Box } from "@mui/material"; import { useLeaderboard } from "../../context/LeaderboardContext"; import SectionHeader from "./components/SectionHeader"; import LanguageList from "./components/LanguageList"; import LeaderboardGrid from "./components/LeaderboardGrid"; import EmptyState from "./components/EmptyState"; import { useLanguageStats } from "./hooks/useLanguageStats"; const ITEMS_PER_PAGE = 4; const LeaderboardSection = ({ title, leaderboards, filteredLeaderboards, id, showEmptyState = false, }) => { const { expandedSections, setExpandedSections, selectedLanguage, setSelectedLanguage, searchQuery, selectedCategories, } = useLeaderboard(); const isExpanded = expandedSections.has(id); const { languages, languageStats, LANGUAGE_FAMILIES, findLanguageFamily } = useLanguageStats(leaderboards, filteredLeaderboards); // Créer un titre enrichi qui inclut les filtres de langue const enrichedTitle = useMemo(() => { let newTitle = title; // Ajouter les langues sélectionnées au titre si elles ne sont pas déjà incluses if (selectedLanguage && selectedLanguage.size > 0) { const languageNames = Array.from(selectedLanguage) .map((lang) => lang.charAt(0).toUpperCase() + lang.slice(1)) .join(", "); // Vérifier si le titre contient déjà "language" if (!newTitle.toLowerCase().includes("language")) { newTitle = `${newTitle} + Language: ${languageNames}`; } else if ( !newTitle.toLowerCase().includes(languageNames.toLowerCase()) ) { // Si le titre contient "language" mais pas les noms spécifiques newTitle = newTitle.replace( /language(\s+specific)?/i, `Language: ${languageNames}` ); } } // Ajouter le terme de recherche s'il existe if ( searchQuery && !newTitle .toLowerCase() .includes(`matching "${searchQuery.toLowerCase()}"`) ) { newTitle = `${newTitle} matching "${searchQuery}"`; } return newTitle; }, [title, selectedLanguage, searchQuery]); // Filtrer pour n'avoir que les leaderboards approuvés const approvedLeaderboards = useMemo(() => { // Filtrer d'abord pour n'avoir que les leaderboards approuvés const approved = filteredLeaderboards.filter( (leaderboard) => leaderboard.approval_status === "approved" ); // Trier par trending_score (ordre décroissant) return [...approved].sort((a, b) => { const scoreA = a.trending_score || 0; const scoreB = b.trending_score || 0; return scoreB - scoreA; // Tri décroissant }); }, [filteredLeaderboards]); // On ne retourne null que si on n'a pas de leaderboards bruts if (!leaderboards) return null; // Déterminer si on doit paginer ou montrer tous les leaderboards const shouldShowAll = (selectedCategories.size === 1 && selectedCategories.has(id)) || // Une seule catégorie sélectionnée ET c'est celle-ci (selectedCategories.size > 1 && id === "combined") || // Plusieurs catégories ET c'est la section combinée isExpanded || // Section dépliée (quelle que soit la sélection) id === "search-results"; // Toujours afficher tous les résultats pour la recherche textuelle // Si on doit tout montrer, on ne divise pas la liste const displayedLeaderboards = shouldShowAll ? approvedLeaderboards : approvedLeaderboards.slice(0, ITEMS_PER_PAGE); const remainingLeaderboards = shouldShowAll ? [] : approvedLeaderboards.slice(ITEMS_PER_PAGE); // Calculate how many skeletons we need (seulement si on ne montre pas tout) const skeletonsNeeded = shouldShowAll ? 0 : Math.max(0, 4 - approvedLeaderboards.length); // On affiche le bouton expand seulement quand on n'a pas de sélection et que ce n'est pas une recherche textuelle const showExpandButton = selectedCategories.size === 0 && id !== "search-results"; // Le bouton est actif seulement s'il y a plus de 4 leaderboards const isExpandButtonEnabled = approvedLeaderboards.length > ITEMS_PER_PAGE; const toggleExpanded = () => { setExpandedSections((prev) => { const newSet = new Set(prev); if (isExpanded) { newSet.delete(id); } else { newSet.add(id); } return newSet; }); }; // Déterminer si on doit afficher la liste des langues const showLanguageList = languages && selectedCategories.size > 0 && (id === "language" || (selectedCategories.size > 1 && selectedCategories.has("language"))); return ( {showLanguageList && ( )} {approvedLeaderboards.length === 0 ? ( // Toujours afficher EmptyState, que showEmptyState soit true ou non ) : ( )} ); }; export default LeaderboardSection;