File size: 5,793 Bytes
2f38845
606f214
 
 
5621ad9
606f214
 
 
 
 
 
 
 
 
 
 
6ba1570
606f214
 
 
 
 
 
 
5621ad9
606f214
 
 
 
 
 
 
2f38845
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
606f214
48cea17
 
 
 
 
 
 
 
 
 
 
 
 
606f214
 
 
 
5621ad9
 
 
 
f145689
 
606f214
5621ad9
 
 
 
606f214
5621ad9
 
 
 
 
 
 
 
 
f145689
 
 
606f214
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5621ad9
 
 
 
 
 
 
606f214
 
 
2f38845
606f214
 
 
 
 
 
 
5621ad9
 
606f214
 
 
 
 
 
 
 
 
 
2405b72
 
606f214
 
 
 
 
 
5621ad9
606f214
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
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 (
    <Box sx={{ mb: 6 }}>
      <SectionHeader
        title={enrichedTitle}
        count={approvedLeaderboards.length}
        isExpanded={isExpanded}
        onToggleExpand={toggleExpanded}
        showExpandButton={showExpandButton}
        isExpandButtonEnabled={isExpandButtonEnabled}
      />

      {showLanguageList && (
        <LanguageList
          languages={languages}
          languageStats={languageStats}
          selectedLanguage={selectedLanguage}
          onLanguageSelect={setSelectedLanguage}
          LANGUAGE_FAMILIES={LANGUAGE_FAMILIES}
          findLanguageFamily={findLanguageFamily}
        />
      )}

      {approvedLeaderboards.length === 0 ? (
        // Toujours afficher EmptyState, que showEmptyState soit true ou non
        <EmptyState title={enrichedTitle} searchQuery={searchQuery} />
      ) : (
        <LeaderboardGrid
          displayedLeaderboards={displayedLeaderboards}
          remainingLeaderboards={remainingLeaderboards}
          isExpanded={isExpanded}
          skeletonsNeeded={skeletonsNeeded}
          id={id}
        />
      )}
    </Box>
  );
};

export default LeaderboardSection;