Open-Greek-Financial-LLM-Leaderboard
/
frontend
/src
/pages
/LeaderboardPage
/components
/Leaderboard
/hooks
/useLeaderboardData.js
import { useMemo, useRef, useState } from "react"; | |
import { useQuery, useQueryClient } from "@tanstack/react-query"; | |
import { useSearchParams } from "react-router-dom"; | |
import { useLeaderboard } from "../context/LeaderboardContext"; | |
import { useDataProcessing } from "../components/Table/hooks/useDataProcessing"; | |
const CACHE_KEY = "leaderboardData"; | |
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes | |
export const useLeaderboardData = () => { | |
const queryClient = useQueryClient(); | |
const [searchParams] = useSearchParams(); | |
const isInitialLoadRef = useRef(true); | |
const { data, isLoading, error } = useQuery({ | |
queryKey: ["leaderboard"], | |
queryFn: async () => { | |
try { | |
const cachedData = localStorage.getItem(CACHE_KEY); | |
if (cachedData) { | |
const { data: cached, timestamp } = JSON.parse(cachedData); | |
const age = Date.now() - timestamp; | |
if (age < CACHE_DURATION) { | |
return cached; | |
} | |
} | |
const response = await fetch("/api/leaderboard/formatted"); | |
if (!response.ok) { | |
throw new Error(`HTTP error! status: ${response.status}`); | |
} | |
const newData = await response.json(); | |
localStorage.setItem( | |
CACHE_KEY, | |
JSON.stringify({ | |
data: newData, | |
timestamp: Date.now(), | |
}) | |
); | |
return newData; | |
} catch (error) { | |
console.error("Detailed error:", error); | |
throw error; | |
} | |
}, | |
staleTime: CACHE_DURATION, | |
cacheTime: CACHE_DURATION * 2, | |
refetchOnWindowFocus: false, | |
enabled: isInitialLoadRef.current || !!searchParams.toString(), | |
}); | |
useMemo(() => { | |
if (data && isInitialLoadRef.current) { | |
isInitialLoadRef.current = false; | |
} | |
}, [data]); | |
return { | |
data, | |
isLoading, | |
error, | |
refetch: () => queryClient.invalidateQueries(["leaderboard"]), | |
}; | |
}; | |
export const useLeaderboardProcessing = () => { | |
const { state, actions } = useLeaderboard(); | |
const [sorting, setSorting] = useState([ | |
{ id: "model.average_score", desc: true }, | |
]); | |
const memoizedData = useMemo(() => state.models, [state.models]); | |
const memoizedFilters = useMemo( | |
() => ({ | |
search: state.filters.search, | |
precisions: state.filters.precisions, | |
types: state.filters.types, | |
paramsRange: state.filters.paramsRange, | |
booleanFilters: state.filters.booleanFilters, | |
isOfficialProviderActive: state.filters.isOfficialProviderActive, | |
}), | |
[ | |
state.filters.search, | |
state.filters.precisions, | |
state.filters.types, | |
state.filters.paramsRange, | |
state.filters.booleanFilters, | |
state.filters.isOfficialProviderActive, | |
] | |
); | |
const { | |
table, | |
minAverage, | |
maxAverage, | |
getColorForValue, | |
processedData, | |
filteredData, | |
columns, | |
columnVisibility, | |
} = useDataProcessing( | |
memoizedData, | |
memoizedFilters.search, | |
memoizedFilters.precisions, | |
memoizedFilters.types, | |
memoizedFilters.paramsRange, | |
memoizedFilters.booleanFilters, | |
sorting, | |
state.display.rankingMode, | |
state.display.averageMode, | |
state.display.visibleColumns, | |
state.display.scoreDisplay, | |
state.pinnedModels, | |
actions.togglePinnedModel, | |
setSorting, | |
memoizedFilters.isOfficialProviderActive | |
); | |
return { | |
table, | |
minAverage, | |
maxAverage, | |
getColorForValue, | |
processedData, | |
filteredData, | |
columns, | |
columnVisibility, | |
loading: state.loading, | |
error: state.error, | |
}; | |
}; | |