mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
When no stats microservice is configured (config.features.stats.isEnabled false), don't fire the stats:lines request that can only fail — the Stats page already renders the live Network Overview + an honest 'being indexed' note. Avoids a wasted erroring query on every Stats page load.
110 lines
3.4 KiB
TypeScript
110 lines
3.4 KiB
TypeScript
import { useRouter } from 'next/router';
|
|
import React, { useCallback, useMemo, useState } from 'react';
|
|
|
|
import type * as stats from '@luxfi/stats-types';
|
|
import type { StatsIntervalIds } from 'types/client/stats';
|
|
import type { ExternalChainExtended } from 'types/externalChains';
|
|
|
|
import config from 'configs/app';
|
|
import useApiQuery from 'lib/api/useApiQuery';
|
|
import getQueryParamString from 'lib/router/getQueryParamString';
|
|
import { STATS_CHARTS } from 'stubs/stats';
|
|
|
|
function isSectionMatches(section: stats.LineChartSection, currentSection: string): boolean {
|
|
return currentSection === 'all' || section.id === currentSection;
|
|
}
|
|
|
|
function isChartNameMatches(q: string, chart: stats.LineChartInfo) {
|
|
return chart.title.toLowerCase().includes(q.toLowerCase());
|
|
}
|
|
|
|
interface Props {
|
|
chain?: ExternalChainExtended;
|
|
}
|
|
|
|
export default function useStats({ chain }: Props = {}) {
|
|
const router = useRouter();
|
|
|
|
const { data, isPlaceholderData, isError } = useApiQuery('stats:lines', {
|
|
queryOptions: {
|
|
placeholderData: STATS_CHARTS,
|
|
// No stats microservice configured → don't fire a request that can only
|
|
// fail; the page renders the live Network Overview + an honest note.
|
|
enabled: config.features.stats.isEnabled,
|
|
},
|
|
chain,
|
|
});
|
|
|
|
const [ currentSection, setCurrentSection ] = useState('all');
|
|
const [ filterQuery, setFilterQuery ] = useState('');
|
|
const [ initialFilterQuery, setInitialFilterQuery ] = React.useState('');
|
|
const [ interval, setInterval ] = useState<StatsIntervalIds>('oneMonth');
|
|
const sectionIds = useMemo(() => data?.sections?.map(({ id }) => id), [ data ]);
|
|
|
|
React.useEffect(() => {
|
|
if (!isPlaceholderData && !isError) {
|
|
const chartId = getQueryParamString(router.query.chartId);
|
|
const chartName = data?.sections.map((section) => section.charts.find((chart) => chart.id === chartId)).filter(Boolean)[0]?.title;
|
|
if (chartName) {
|
|
setInitialFilterQuery(chartName);
|
|
setFilterQuery(chartName);
|
|
router.replace({ pathname: '/stats' }, undefined, { scroll: false });
|
|
}
|
|
}
|
|
// run only when data is loaded
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [ isPlaceholderData ]);
|
|
|
|
const displayedCharts = React.useMemo(() => {
|
|
return data?.sections
|
|
?.map((section) => {
|
|
const charts = section.charts.filter((chart) => isSectionMatches(section, currentSection) && isChartNameMatches(filterQuery, chart));
|
|
|
|
return {
|
|
...section,
|
|
charts,
|
|
};
|
|
}).filter((section) => section.charts.length > 0);
|
|
}, [ currentSection, data?.sections, filterQuery ]);
|
|
|
|
const handleSectionChange = useCallback((newSection: string) => {
|
|
setCurrentSection(newSection);
|
|
}, []);
|
|
|
|
const handleIntervalChange = useCallback((newInterval: StatsIntervalIds) => {
|
|
setInterval(newInterval);
|
|
}, []);
|
|
|
|
const handleFilterChange = useCallback((q: string) => {
|
|
setFilterQuery(q);
|
|
}, []);
|
|
|
|
return React.useMemo(() => ({
|
|
sections: data?.sections,
|
|
sectionIds,
|
|
isPlaceholderData,
|
|
isError,
|
|
initialFilterQuery,
|
|
filterQuery,
|
|
currentSection,
|
|
handleSectionChange,
|
|
interval,
|
|
handleIntervalChange,
|
|
handleFilterChange,
|
|
displayedCharts,
|
|
}), [
|
|
data,
|
|
sectionIds,
|
|
isPlaceholderData,
|
|
isError,
|
|
initialFilterQuery,
|
|
filterQuery,
|
|
currentSection,
|
|
handleSectionChange,
|
|
interval,
|
|
handleIntervalChange,
|
|
handleFilterChange,
|
|
displayedCharts,
|
|
]);
|
|
}
|