Alina Lozowski
Migrating to the React project
e7abd9e
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,
};
};