Spaces:
Running
Running
import React, { useState, useEffect } from "react"; | |
import { | |
Box, | |
CircularProgress, | |
Stack, | |
Button, | |
FormControlLabel, | |
Switch, | |
TextField, | |
InputAdornment, | |
Typography, | |
} from "@mui/material"; | |
import SearchIcon from "@mui/icons-material/Search"; | |
import SearchOffIcon from "@mui/icons-material/SearchOff"; | |
import Logo from "../../components/Logo/Logo"; | |
import PageTitle from "../../components/PageTitle/PageTitle"; | |
import PageHeader from "../../components/PageHeader/PageHeader"; | |
import LeaderboardSection from "../../components/LeaderboardSection"; | |
import LeaderboardFilters from "../../components/LeaderboardFilters/LeaderboardFilters"; | |
import { alpha } from "@mui/material/styles"; | |
import API_URLS from "../../config/api"; | |
import { | |
LeaderboardProvider, | |
useLeaderboard, | |
} from "../../context/LeaderboardContext"; | |
const LeaderboardPageContent = () => { | |
const [loading, setLoading] = useState(true); | |
const { | |
setLeaderboards, | |
filterLeaderboards, | |
sections, | |
allSections, | |
searchQuery, | |
arenaOnly, | |
} = useLeaderboard(); | |
useEffect(() => { | |
fetch(API_URLS.leaderboards) | |
.then((res) => res.json()) | |
.then((data) => { | |
const leaderboardsArray = Array.isArray(data) | |
? data | |
: Object.values(data).filter((item) => Array.isArray(item))[0]; | |
setLeaderboards(leaderboardsArray); | |
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} /> | |
{!hasLeaderboards && isFiltering && ( | |
<Box | |
sx={{ | |
display: "flex", | |
flexDirection: "column", | |
alignItems: "center", | |
gap: 2, | |
mt: 8, | |
py: 7, | |
}} | |
> | |
<SearchOffIcon | |
sx={{ | |
fontSize: 64, | |
color: "text.secondary", | |
opacity: 0.5, | |
}} | |
/> | |
<Typography variant="h5" color="text.secondary" align="center"> | |
{searchQuery ? ( | |
<> | |
Oops! No leaderboard matches{" "} | |
<Box | |
component="span" | |
sx={{ | |
bgcolor: "primary.main", | |
color: "primary.contrastText", | |
px: 1, | |
borderRadius: 1, | |
}} | |
> | |
{searchQuery} | |
</Box> | |
</> | |
) : ( | |
"Oops! No leaderboard matches your criteria" | |
)} | |
</Typography> | |
<Typography variant="body1" color="text.secondary" align="center"> | |
Try adjusting your search filters | |
</Typography> | |
</Box> | |
)} | |
{(hasLeaderboards || !isFiltering) && | |
sections.map(({ id, title, data }) => { | |
const filteredLeaderboards = filterLeaderboards(data); | |
if (filteredLeaderboards.length === 0) return null; | |
return ( | |
<Box key={id} id={id}> | |
<LeaderboardSection | |
title={title} | |
leaderboards={filteredLeaderboards} | |
/> | |
</Box> | |
); | |
})} | |
</Box> | |
)} | |
</Box> | |
); | |
}; | |
const LeaderboardPage = () => { | |
return ( | |
<LeaderboardProvider> | |
<LeaderboardPageContent /> | |
</LeaderboardProvider> | |
); | |
}; | |
export default LeaderboardPage; | |