diff --git a/explorer-v2/src/app/page.tsx b/explorer-v2/src/app/page.tsx index 56a83475f3..0cc48d3243 100644 --- a/explorer-v2/src/app/page.tsx +++ b/explorer-v2/src/app/page.tsx @@ -4,11 +4,11 @@ import Grid from "@mui/material/Grid2"; import BlogArticlesCards from "../components/blogs/BlogArticleCards"; import { ContentLayout } from "../components/contentLayout/ContentLayout"; import SectionHeading from "../components/headings/SectionHeading"; -import { CurrentEpochCard } from "../components/landingPageComponents/CurrentEpochCard"; -import { NetworkStakeCard } from "../components/landingPageComponents/NetworkStakeCard"; -import { NoiseCard } from "../components/landingPageComponents/NoiseCard"; -import { StakersNumberCard } from "../components/landingPageComponents/StakersNumberCard"; -import { TokenomicsCard } from "../components/landingPageComponents/TokenomicsCard"; +import { CurrentEpochCardWrapper } from "../components/landingPageComponents/CurrentEpochCardWrapper"; +import { NetworkStakeCardWrapper } from "../components/landingPageComponents/NetworkStakeCardWrapper"; +import { NoiseCardWrapper } from "../components/landingPageComponents/NoiseCardWrapper"; +import { StakersNumberCardWrapper } from "../components/landingPageComponents/StakersNumberCardWrapper"; +import { TokenomicsCardWrapper } from "../components/landingPageComponents/TokenomicsCardWrapper"; import NodeTable from "../components/nodeTable/NodeTableWithAction"; import NodeAndAddressSearch from "../components/search/NodeAndAddressSearch"; @@ -23,29 +23,19 @@ export default async function Home() { - - - + - - - - - - + + - - - - - - + + diff --git a/explorer-v2/src/components/landingPageComponents/ConditionalCardWrapper.tsx b/explorer-v2/src/components/landingPageComponents/ConditionalCardWrapper.tsx new file mode 100644 index 0000000000..1ba3ff5e1f --- /dev/null +++ b/explorer-v2/src/components/landingPageComponents/ConditionalCardWrapper.tsx @@ -0,0 +1,21 @@ +"use client"; +import Grid from "@mui/material/Grid2"; +import { ReactNode } from "react"; + +interface ConditionalCardWrapperProps { + children: ReactNode; + size?: any; + visible?: boolean; +} + +export const ConditionalCardWrapper = ({ + children, + size, + visible = true, +}: ConditionalCardWrapperProps) => { + if (!visible) { + return null; + } + + return {children}; +}; diff --git a/explorer-v2/src/components/landingPageComponents/CurrentEpochCardWrapper.tsx b/explorer-v2/src/components/landingPageComponents/CurrentEpochCardWrapper.tsx new file mode 100644 index 0000000000..73bb53d45c --- /dev/null +++ b/explorer-v2/src/components/landingPageComponents/CurrentEpochCardWrapper.tsx @@ -0,0 +1,19 @@ +"use client"; +import { useEpochContext } from "@/providers/EpochProvider"; +import { CurrentEpochCard } from "./CurrentEpochCard"; +import { ConditionalCardWrapper } from "./ConditionalCardWrapper"; + +export const CurrentEpochCardWrapper = () => { + const { data, isError, isLoading, epochStatus } = useEpochContext(); + + // Determine if the card should be visible + // Show the card if we have data and it's not in a pending state, or if we're still loading + const isVisible = + !isError && (data || isLoading) && epochStatus !== "pending"; + + return ( + + + + ); +}; diff --git a/explorer-v2/src/components/landingPageComponents/NetworkStakeCard.tsx b/explorer-v2/src/components/landingPageComponents/NetworkStakeCard.tsx index 770cc4ae52..751774fde2 100644 --- a/explorer-v2/src/components/landingPageComponents/NetworkStakeCard.tsx +++ b/explorer-v2/src/components/landingPageComponents/NetworkStakeCard.tsx @@ -33,21 +33,14 @@ export const NetworkStakeCard = () => { ); } - if (isStakingError || !packetsAndStaking) { - return ( - - - Failed to load data - - - - ); + // Don't display the card if there's an error or insufficient data + if ( + isStakingError || + !packetsAndStaking || + !Array.isArray(packetsAndStaking) || + packetsAndStaking.length < 10 + ) { + return null; } const packetsAndStakingData: ExplorerData["packetsAndStakingData"] = diff --git a/explorer-v2/src/components/landingPageComponents/NetworkStakeCardWrapper.tsx b/explorer-v2/src/components/landingPageComponents/NetworkStakeCardWrapper.tsx new file mode 100644 index 0000000000..3a46184ed4 --- /dev/null +++ b/explorer-v2/src/components/landingPageComponents/NetworkStakeCardWrapper.tsx @@ -0,0 +1,25 @@ +"use client"; +import { fetchNoise } from "@/app/api"; +import { useQuery } from "@tanstack/react-query"; +import { NetworkStakeCard } from "./NetworkStakeCard"; +import { ConditionalCardWrapper } from "./ConditionalCardWrapper"; + +export const NetworkStakeCardWrapper = () => { + const { data, isLoading, isError } = useQuery({ + queryKey: ["noise"], + queryFn: fetchNoise, + staleTime: 10 * 60 * 1000, // 10 minutes + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }); + + // Determine if the card should be visible + const isVisible = + !isLoading && !isError && data && Array.isArray(data) && data.length >= 10; + + return ( + + + + ); +}; diff --git a/explorer-v2/src/components/landingPageComponents/NoiseCard.tsx b/explorer-v2/src/components/landingPageComponents/NoiseCard.tsx index 102436e5e9..28153d2c6a 100644 --- a/explorer-v2/src/components/landingPageComponents/NoiseCard.tsx +++ b/explorer-v2/src/components/landingPageComponents/NoiseCard.tsx @@ -41,33 +41,9 @@ export const NoiseCard = () => { ); } - if (isError || !data || !Array.isArray(data)) { - return ( - - - Failed to load data - - - - ); - } - - // If we don't have enough data, show loading - if (data.length < 3) { - return ( - - - - - - - ); + // Don't display the card if there's an error or insufficient data + if (isError || !data || !Array.isArray(data) || data.length < 10) { + return null; } const todaysData = data[data.length - 2]; diff --git a/explorer-v2/src/components/landingPageComponents/NoiseCardWrapper.tsx b/explorer-v2/src/components/landingPageComponents/NoiseCardWrapper.tsx new file mode 100644 index 0000000000..b9a7c9b2cc --- /dev/null +++ b/explorer-v2/src/components/landingPageComponents/NoiseCardWrapper.tsx @@ -0,0 +1,25 @@ +"use client"; +import { fetchNoise } from "@/app/api"; +import { useQuery } from "@tanstack/react-query"; +import { NoiseCard } from "./NoiseCard"; +import { ConditionalCardWrapper } from "./ConditionalCardWrapper"; + +export const NoiseCardWrapper = () => { + const { data, isLoading, isError } = useQuery({ + queryKey: ["noise"], + queryFn: fetchNoise, + staleTime: 10 * 60 * 1000, // 10 minutes + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }); + + // Determine if the card should be visible + const isVisible = + !isLoading && !isError && data && Array.isArray(data) && data.length >= 10; + + return ( + + + + ); +}; diff --git a/explorer-v2/src/components/landingPageComponents/StakersNumberCardWrapper.tsx b/explorer-v2/src/components/landingPageComponents/StakersNumberCardWrapper.tsx new file mode 100644 index 0000000000..f43fcb0881 --- /dev/null +++ b/explorer-v2/src/components/landingPageComponents/StakersNumberCardWrapper.tsx @@ -0,0 +1,26 @@ +"use client"; +import { fetchNSApiNodes } from "@/app/api"; +import { useQuery } from "@tanstack/react-query"; +import { StakersNumberCard } from "./StakersNumberCard"; +import { ConditionalCardWrapper } from "./ConditionalCardWrapper"; + +export const StakersNumberCardWrapper = () => { + const { data, isLoading, isError } = useQuery({ + queryKey: ["nsApiNodes"], + queryFn: fetchNSApiNodes, + staleTime: 10 * 60 * 1000, // 10 minutes + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchOnMount: false, + }); + + // Determine if the card should be visible + const isVisible = + !isLoading && !isError && data && Array.isArray(data) && data.length > 0; + + return ( + + + + ); +}; diff --git a/explorer-v2/src/components/landingPageComponents/TokenomicsCardWrapper.tsx b/explorer-v2/src/components/landingPageComponents/TokenomicsCardWrapper.tsx new file mode 100644 index 0000000000..93051d4b51 --- /dev/null +++ b/explorer-v2/src/components/landingPageComponents/TokenomicsCardWrapper.tsx @@ -0,0 +1,64 @@ +"use client"; +import { fetchEpochRewards, fetchNoise, fetchNymPrice } from "@/app/api"; +import { useQuery } from "@tanstack/react-query"; +import { TokenomicsCard } from "./TokenomicsCard"; +import { ConditionalCardWrapper } from "./ConditionalCardWrapper"; + +export const TokenomicsCardWrapper = () => { + const { + data: nymPrice, + isLoading: isPriceLoading, + isError: isPriceError, + } = useQuery({ + queryKey: ["nymPrice"], + queryFn: fetchNymPrice, + staleTime: 10 * 60 * 1000, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchOnMount: false, + }); + + const { + data: epochRewards, + isLoading: isEpochLoading, + isError: isEpochError, + } = useQuery({ + queryKey: ["epochRewards"], + queryFn: fetchEpochRewards, + staleTime: 10 * 60 * 1000, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchOnMount: false, + }); + + const { + data: packetsAndStaking, + isLoading: isStakingLoading, + isError: isStakingError, + } = useQuery({ + queryKey: ["noise"], + queryFn: fetchNoise, + staleTime: 10 * 60 * 1000, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchOnMount: false, + }); + + // Determine if the card should be visible + const isLoading = isPriceLoading || isEpochLoading || isStakingLoading; + const hasError = isPriceError || isEpochError || isStakingError; + const hasData = + nymPrice && + epochRewards && + packetsAndStaking && + Array.isArray(packetsAndStaking) && + packetsAndStaking.length >= 2; + + const isVisible = !hasError && (hasData || isLoading); + + return ( + + + + ); +};