feat: add conditional card wrappers to prevent empty grid spaces
This commit is contained in:
@@ -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() {
|
||||
<Grid size={12}>
|
||||
<SectionHeading title="Network Overview" />
|
||||
</Grid>
|
||||
<Grid size={{ xs: 12, sm: 6, lg: 3 }}>
|
||||
<NoiseCard />
|
||||
</Grid>
|
||||
<NoiseCardWrapper />
|
||||
<Grid
|
||||
container
|
||||
columnSpacing={5}
|
||||
rowSpacing={5}
|
||||
size={{ xs: 12, sm: 6, lg: 3 }}
|
||||
>
|
||||
<Grid size={12}>
|
||||
<StakersNumberCard />
|
||||
</Grid>
|
||||
<Grid size={12}>
|
||||
<CurrentEpochCard />
|
||||
</Grid>
|
||||
<StakersNumberCardWrapper />
|
||||
<CurrentEpochCardWrapper />
|
||||
</Grid>
|
||||
|
||||
<Grid size={{ xs: 12, sm: 6, lg: 3 }}>
|
||||
<NetworkStakeCard />
|
||||
</Grid>
|
||||
<Grid size={{ xs: 12, sm: 6, lg: 3 }}>
|
||||
<TokenomicsCard />
|
||||
</Grid>
|
||||
<NetworkStakeCardWrapper />
|
||||
<TokenomicsCardWrapper />
|
||||
</Grid>
|
||||
<Grid container rowSpacing={5}>
|
||||
<Grid size={12}>
|
||||
|
||||
@@ -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 <Grid size={size}>{children}</Grid>;
|
||||
};
|
||||
@@ -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 (
|
||||
<ConditionalCardWrapper size={12} visible={isVisible}>
|
||||
<CurrentEpochCard />
|
||||
</ConditionalCardWrapper>
|
||||
);
|
||||
};
|
||||
@@ -33,21 +33,14 @@ export const NetworkStakeCard = () => {
|
||||
);
|
||||
}
|
||||
|
||||
if (isStakingError || !packetsAndStaking) {
|
||||
return (
|
||||
<ExplorerCard label="Current network stake">
|
||||
<Typography
|
||||
variant="h5"
|
||||
sx={{
|
||||
color: isDarkMode ? "base.white" : "pine.950",
|
||||
letterSpacing: 0.7,
|
||||
}}
|
||||
>
|
||||
Failed to load data
|
||||
</Typography>
|
||||
<Skeleton variant="text" height={238} />
|
||||
</ExplorerCard>
|
||||
);
|
||||
// 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"] =
|
||||
|
||||
@@ -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 (
|
||||
<ConditionalCardWrapper size={{ xs: 12, sm: 6, lg: 3 }} visible={isVisible}>
|
||||
<NetworkStakeCard />
|
||||
</ConditionalCardWrapper>
|
||||
);
|
||||
};
|
||||
@@ -41,33 +41,9 @@ export const NoiseCard = () => {
|
||||
);
|
||||
}
|
||||
|
||||
if (isError || !data || !Array.isArray(data)) {
|
||||
return (
|
||||
<ExplorerCard label="Mixnet traffic">
|
||||
<Typography
|
||||
variant="h5"
|
||||
sx={{
|
||||
color: isDarkMode ? "base.white" : "pine.950",
|
||||
letterSpacing: 0.7,
|
||||
}}
|
||||
>
|
||||
Failed to load data
|
||||
</Typography>
|
||||
<Skeleton variant="text" height={238} />
|
||||
</ExplorerCard>
|
||||
);
|
||||
}
|
||||
|
||||
// If we don't have enough data, show loading
|
||||
if (data.length < 3) {
|
||||
return (
|
||||
<ExplorerCard label="Mixnet traffic">
|
||||
<Stack gap={1}>
|
||||
<Skeleton variant="text" />
|
||||
<Skeleton variant="text" height={238} />
|
||||
</Stack>
|
||||
</ExplorerCard>
|
||||
);
|
||||
// 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];
|
||||
|
||||
@@ -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 (
|
||||
<ConditionalCardWrapper size={{ xs: 12, sm: 6, lg: 3 }} visible={isVisible}>
|
||||
<NoiseCard />
|
||||
</ConditionalCardWrapper>
|
||||
);
|
||||
};
|
||||
@@ -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 (
|
||||
<ConditionalCardWrapper size={12} visible={isVisible}>
|
||||
<StakersNumberCard />
|
||||
</ConditionalCardWrapper>
|
||||
);
|
||||
};
|
||||
@@ -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 (
|
||||
<ConditionalCardWrapper size={{ xs: 12, sm: 6, lg: 3 }} visible={isVisible}>
|
||||
<TokenomicsCard />
|
||||
</ConditionalCardWrapper>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user