diff --git a/src/app/airdrops/error.tsx b/src/app/airdrops/error.tsx new file mode 100644 index 0000000..c72dcf3 --- /dev/null +++ b/src/app/airdrops/error.tsx @@ -0,0 +1,10 @@ +"use client"; + +import RouteError from "@/components/RouteError/RouteError"; + +export default function AirdropsError(props: { + error: Error & { digest?: string }; + reset: () => void; +}) { + return ; +} diff --git a/src/app/alerts/error.tsx b/src/app/alerts/error.tsx new file mode 100644 index 0000000..de4f6ae --- /dev/null +++ b/src/app/alerts/error.tsx @@ -0,0 +1,10 @@ +"use client"; + +import RouteError from "@/components/RouteError/RouteError"; + +export default function AlertsError(props: { + error: Error & { digest?: string }; + reset: () => void; +}) { + return ; +} diff --git a/src/app/contributors/error.tsx b/src/app/contributors/error.tsx new file mode 100644 index 0000000..6a6dea0 --- /dev/null +++ b/src/app/contributors/error.tsx @@ -0,0 +1,10 @@ +"use client"; + +import RouteError from "@/components/RouteError/RouteError"; + +export default function ContributorsError(props: { + error: Error & { digest?: string }; + reset: () => void; +}) { + return ; +} diff --git a/src/app/farm/error.tsx b/src/app/farm/error.tsx new file mode 100644 index 0000000..440cf6d --- /dev/null +++ b/src/app/farm/error.tsx @@ -0,0 +1,10 @@ +"use client"; + +import RouteError from "@/components/RouteError/RouteError"; + +export default function FarmError(props: { + error: Error & { digest?: string }; + reset: () => void; +}) { + return ; +} diff --git a/src/app/history/error.tsx b/src/app/history/error.tsx new file mode 100644 index 0000000..d0db251 --- /dev/null +++ b/src/app/history/error.tsx @@ -0,0 +1,10 @@ +"use client"; + +import RouteError from "@/components/RouteError/RouteError"; + +export default function HistoryError(props: { + error: Error & { digest?: string }; + reset: () => void; +}) { + return ; +} diff --git a/src/app/leaderboard/error.tsx b/src/app/leaderboard/error.tsx new file mode 100644 index 0000000..09815c1 --- /dev/null +++ b/src/app/leaderboard/error.tsx @@ -0,0 +1,10 @@ +"use client"; + +import RouteError from "@/components/RouteError/RouteError"; + +export default function LeaderboardError(props: { + error: Error & { digest?: string }; + reset: () => void; +}) { + return ; +} diff --git a/src/app/prices/error.tsx b/src/app/prices/error.tsx new file mode 100644 index 0000000..eb0e3c1 --- /dev/null +++ b/src/app/prices/error.tsx @@ -0,0 +1,10 @@ +"use client"; + +import RouteError from "@/components/RouteError/RouteError"; + +export default function PricesError(props: { + error: Error & { digest?: string }; + reset: () => void; +}) { + return ; +} diff --git a/src/app/webhooks/error.tsx b/src/app/webhooks/error.tsx new file mode 100644 index 0000000..1b1077d --- /dev/null +++ b/src/app/webhooks/error.tsx @@ -0,0 +1,10 @@ +"use client"; + +import RouteError from "@/components/RouteError/RouteError"; + +export default function WebhooksError(props: { + error: Error & { digest?: string }; + reset: () => void; +}) { + return ; +} diff --git a/src/components/AppShell/AppShell.tsx b/src/components/AppShell/AppShell.tsx index d7bdbdc..9d6ba1a 100644 --- a/src/components/AppShell/AppShell.tsx +++ b/src/components/AppShell/AppShell.tsx @@ -4,6 +4,7 @@ import ConnectWalletButton from "@/components/ConnectWalletButton/ConnectWalletB import Footer from "@/components/Footer/Footer"; import Navbar from "@/components/Navbar/Navbar"; import NetworkMismatchBanner from "@/components/NetworkMismatchBanner/NetworkMismatchBanner"; +import RefetchIndicator from "@/components/RefetchIndicator/RefetchIndicator"; import RpcUnreachableBanner from "@/components/RpcUnreachableBanner/RpcUnreachableBanner"; import ContextProvider from "@/context"; import { @@ -46,6 +47,7 @@ function LayoutWrapper({ children }: { children: React.ReactNode }) { md: 0, }} > + diff --git a/src/components/RefetchIndicator/RefetchIndicator.tsx b/src/components/RefetchIndicator/RefetchIndicator.tsx new file mode 100644 index 0000000..2454fdd --- /dev/null +++ b/src/components/RefetchIndicator/RefetchIndicator.tsx @@ -0,0 +1,46 @@ +"use client"; + +import { keyframes } from "@emotion/react"; +import { Box } from "@chakra-ui/react"; +import { useIsFetching } from "@tanstack/react-query"; + +const slide = keyframes` + 0% { transform: translateX(-100%); } + 100% { transform: translateX(250%); } +`; + +/** + * A thin bar at the top of the viewport while cached data is being refreshed + * (#499). Only queries that already hold data count, so first loads (which + * have their own spinners) don't trigger it; the old data stays on screen and + * this shows it is being updated. The animation is dropped for users who + * prefer reduced motion, leaving a static bar. + */ +export default function RefetchIndicator() { + const refetching = + useIsFetching({ predicate: (query) => query.state.data !== undefined }) > 0; + + return ( +