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 (
+
+
+
+ );
+};