| import React, { useState, useEffect, useMemo } from "react"; | |
| import { | |
| Box, | |
| CircularProgress, | |
| Typography, | |
| Chip, | |
| Tooltip, | |
| } from "@mui/material"; | |
| import SearchOffIcon from "@mui/icons-material/SearchOff"; | |
| import WarningAmberIcon from "@mui/icons-material/WarningAmber"; | |
| import Logo from "../../components/Logo/Logo"; | |
| import PageTitle from "../../components/PageTitle/PageTitle"; | |
| import LeaderboardSection from "../../components/LeaderboardSection"; | |
| import LeaderboardFilters from "../../components/LeaderboardFilters/LeaderboardFilters"; | |
| import API_URLS from "../../config/api"; | |
| import { | |
| LeaderboardProvider, | |
| useLeaderboard, | |
| } from "../../context/LeaderboardContext"; | |
| import EmptyState from "../../components/LeaderboardSection/components/EmptyState"; | |
| const LeaderboardPageContent = () => { | |
| const [loading, setLoading] = useState(true); | |
| const [showUncategorized, setShowUncategorized] = useState(false); | |
| const { | |
| setLeaderboards, | |
| filterLeaderboards, | |
| sections, | |
| allSections, | |
| sectionsSortedByCount, | |
| searchQuery, | |
| arenaOnly, | |
| selectedCategories, | |
| leaderboards, | |
| } = useLeaderboard(); | |
| // Vérifier si on a uniquement une recherche textuelle active ou arena only | |
| const isOnlyTextSearch = | |
| (searchQuery || arenaOnly) && selectedCategories.size === 0; | |
| // Obtenir tous les leaderboards uniques de toutes les sections | |
| const allUniqueLeaderboards = useMemo(() => { | |
| if (!allSections) return []; | |
| return Array.from( | |
| new Set( | |
| allSections.reduce((acc, section) => { | |
| return [...acc, ...(section.data || [])]; | |
| }, []) | |
| ) | |
| ); | |
| }, [allSections]); | |
| const uncategorizedLeaderboards = useMemo(() => { | |
| if (!leaderboards || leaderboards.length === 0) return []; | |
| return leaderboards.filter( | |
| (board) => | |
| board.approval_status === "approved" && | |
| !board.tags?.some( | |
| (tag) => | |
| tag.startsWith("modality:") || | |
| tag.startsWith("eval:") || | |
| tag.startsWith("domain:") || | |
| tag.startsWith("language:") | |
| ) | |
| ); | |
| }, [leaderboards]); | |
| // Filtrer tous les leaderboards pour la recherche textuelle ou arena only | |
| const searchResults = useMemo(() => { | |
| if (!isOnlyTextSearch) return []; | |
| return filterLeaderboards(allUniqueLeaderboards); | |
| }, [isOnlyTextSearch, filterLeaderboards, allUniqueLeaderboards]); | |
| useEffect(() => { | |
| fetch(API_URLS.leaderboards) | |
| .then((res) => { | |
| if (!res.ok) { | |
| throw new Error(`Failed to fetch leaderboards: ${res.status}`); | |
| } | |
| return res.json(); | |
| }) | |
| .then((data) => { | |
| // Les données sont directement dans le format attendu depuis le dataset HF | |
| setLeaderboards(data); | |
| setLoading(false); | |
| }) | |
| .catch((error) => { | |
| console.error("Error fetching leaderboards:", error); | |
| setLoading(false); | |
| }); | |
| }, [setLeaderboards]); | |
| // Check if any leaderboards are found after filtering | |
| const totalFilteredLeaderboards = sections.reduce( | |
| (total, { data }) => total + filterLeaderboards(data).length, | |
| 0 | |
| ); | |
| const hasLeaderboards = totalFilteredLeaderboards > 0; | |
| const isFiltering = searchQuery || arenaOnly; | |
| return ( | |
| <Box | |
| sx={{ | |
| width: "100%", | |
| ph: 2, | |
| display: "flex", | |
| flexDirection: "column", | |
| }} | |
| > | |
| <Box | |
| sx={{ display: "flex", justifyContent: "center", pt: 6, mb: -4, pb: 0 }} | |
| > | |
| <Logo /> | |
| </Box> | |
| <Box | |
| sx={{ | |
| display: "flex", | |
| flexDirection: "column", | |
| alignItems: "center", | |
| textAlign: "center", | |
| mb: 0, | |
| mt: 6, | |
| gap: 2, | |
| }} | |
| > | |
| <PageTitle /> | |
| <Typography variant="h6" color="text.secondary"> | |
| <span style={{ fontWeight: 600 }}>Discover</span> and{" "} | |
| <span style={{ fontWeight: 600 }}>explore</span> all leaderboards from | |
| the <span style={{ fontWeight: 600 }}>Hugging Face community</span> | |
| </Typography> | |
| </Box> | |
| {loading ? ( | |
| <Box sx={{ display: "flex", justifyContent: "center", mt: 4 }}> | |
| <CircularProgress /> | |
| </Box> | |
| ) : ( | |
| <Box | |
| sx={{ | |
| width: "100%", | |
| maxWidth: "1200px", | |
| mx: "auto", | |
| mt: 4, | |
| }} | |
| > | |
| <LeaderboardFilters allSections={allSections} /> | |
| {isOnlyTextSearch ? ( | |
| // Vue spéciale pour la recherche textuelle | |
| searchResults.length > 0 ? ( | |
| <Box key="search-results"> | |
| <LeaderboardSection | |
| id="search-results" | |
| title={ | |
| searchQuery | |
| ? `All leaderboards matching "${searchQuery}"${ | |
| arenaOnly ? " (Arena only)" : "" | |
| }` | |
| : "All Arena leaderboards" | |
| } | |
| leaderboards={allUniqueLeaderboards} | |
| filteredLeaderboards={searchResults} | |
| /> | |
| </Box> | |
| ) : ( | |
| // Message d'erreur pour la recherche textuelle sans résultats | |
| <Box key="search-results"> | |
| <LeaderboardSection | |
| id="search-results" | |
| title={ | |
| searchQuery | |
| ? `All leaderboards matching "${searchQuery}"${ | |
| arenaOnly ? " (Arena only)" : "" | |
| }` | |
| : "All Arena leaderboards" | |
| } | |
| leaderboards={allUniqueLeaderboards} | |
| filteredLeaderboards={[]} | |
| showEmptyState={true} | |
| /> | |
| </Box> | |
| ) | |
| ) : selectedCategories.size > 0 ? ( | |
| // Si des catégories sont sélectionnées | |
| selectedCategories.size === 1 ? ( | |
| // Si une seule catégorie est sélectionnée, on affiche sa section | |
| sections | |
| .filter(({ id }) => selectedCategories.has(id)) | |
| .map(({ id, title, data }) => { | |
| const filteredLeaderboards = filterLeaderboards(data); | |
| // Ajouter le terme de recherche au titre si présent | |
| const sectionTitle = searchQuery | |
| ? `${title} matching "${searchQuery}"` | |
| : title; | |
| // Toujours afficher la section, même si elle est vide | |
| return ( | |
| <Box key={id} id={id}> | |
| <LeaderboardSection | |
| id={id} | |
| title={sectionTitle} | |
| leaderboards={data} | |
| filteredLeaderboards={filteredLeaderboards} | |
| showEmptyState={true} // Toujours afficher l'état vide sous le header | |
| /> | |
| </Box> | |
| ); | |
| }) | |
| ) : ( | |
| // Si plusieurs catégories sont sélectionnées, on les agrège | |
| (() => { | |
| // Agréger les données de toutes les sections sélectionnées | |
| const selectedSections = sections.filter(({ id }) => | |
| selectedCategories.has(id) | |
| ); | |
| // Créer un titre combiné avec le terme de recherche si présent | |
| const combinedTitle = selectedSections | |
| .map(({ title }) => title) | |
| .join(" + "); | |
| const finalTitle = searchQuery | |
| ? `${combinedTitle} matching "${searchQuery}"` | |
| : combinedTitle; | |
| // Agréger les leaderboards | |
| const combinedData = selectedSections.reduce( | |
| (acc, { data }) => [...acc, ...data], | |
| [] | |
| ); | |
| // Filtrer les doublons par ID | |
| const uniqueData = Array.from( | |
| new Map(combinedData.map((item) => [item.id, item])).values() | |
| ); | |
| const filteredLeaderboards = filterLeaderboards(uniqueData); | |
| return ( | |
| <Box key="combined"> | |
| <LeaderboardSection | |
| id="combined" | |
| title={finalTitle} | |
| leaderboards={uniqueData} | |
| filteredLeaderboards={filteredLeaderboards} | |
| showEmptyState={true} // Toujours afficher l'état vide sous le header | |
| /> | |
| </Box> | |
| ); | |
| })() | |
| ) | |
| ) : ( | |
| // Si aucune catégorie n'est sélectionnée, on affiche toutes les sections avec des résultats | |
| // triées par nombre de leaderboards | |
| (hasLeaderboards || !isFiltering) && | |
| sectionsSortedByCount.map(({ id, title, data }) => { | |
| const filteredLeaderboards = filterLeaderboards(data); | |
| if (filteredLeaderboards.length === 0) return null; | |
| return ( | |
| <Box key={id} id={id}> | |
| <LeaderboardSection | |
| id={id} | |
| title={title} | |
| leaderboards={data} | |
| filteredLeaderboards={filteredLeaderboards} | |
| /> | |
| </Box> | |
| ); | |
| }) | |
| )} | |
| </Box> | |
| )} | |
| </Box> | |
| ); | |
| }; | |
| const LeaderboardPage = () => { | |
| return ( | |
| <LeaderboardProvider> | |
| <LeaderboardPageContent /> | |
| </LeaderboardProvider> | |
| ); | |
| }; | |
| export default LeaderboardPage; | |
| Pq234 |
Xet Storage Details
- Size:
- 9.66 kB
- Xet hash:
- 869bf7a48f6fc1e2a58918770663d56734e7146a5b8d5d775f160af12416d3cd
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.