From f4b9820b5b439e4501b44b63fb60a0fc91eaa000 Mon Sep 17 00:00:00 2001 From: Owen Date: Thu, 11 Jun 2026 15:06:13 +0200 Subject: [PATCH] add loading page --- TODO | 4 ++- .../{Error => }/GenericErrorView.tsx | 0 src/components/LoadingView.tsx | 34 +++++++++++++++++++ src/pages/Callback.tsx | 10 +++--- src/routes/__root.tsx | 4 ++- src/routes/callback.tsx | 2 +- 6 files changed, 47 insertions(+), 7 deletions(-) rename src/components/{Error => }/GenericErrorView.tsx (100%) create mode 100644 src/components/LoadingView.tsx diff --git a/TODO b/TODO index 6c4ee6b..2587734 100644 --- a/TODO +++ b/TODO @@ -11,4 +11,6 @@ - try/catch where needed in client code - generate state and check it against the state returned from lichess https://lichess.org/api#tag/oauth/GET/oauth - checkbox and toggle disabled states -- 404 \ No newline at end of file +- 404 page +- lichess data with zod validation +- react query on for study and chapter load, to allow caching \ No newline at end of file diff --git a/src/components/Error/GenericErrorView.tsx b/src/components/GenericErrorView.tsx similarity index 100% rename from src/components/Error/GenericErrorView.tsx rename to src/components/GenericErrorView.tsx diff --git a/src/components/LoadingView.tsx b/src/components/LoadingView.tsx new file mode 100644 index 0000000..c857f28 --- /dev/null +++ b/src/components/LoadingView.tsx @@ -0,0 +1,34 @@ +interface IProps { + title?: string; + description?: string; +} + +const LoadingView = ({ title, description }: IProps) => { + return ( +
+
+ {/* Animated Custom Loader */} +
+ {/* Outer Pulsing Ring */} +
+ + {/* Inner Spinning Ring */} +
+
+ + {/* Loading Content */} +

+ {title || "Loading Data"} +

+

+ {description || "Please wait a moment while we load the data."} +

+ + {/* Decorative background glow matching your layout */} +
+
+
+ ); +}; + +export default LoadingView; diff --git a/src/pages/Callback.tsx b/src/pages/Callback.tsx index 3ba34be..0aecbdf 100644 --- a/src/pages/Callback.tsx +++ b/src/pages/Callback.tsx @@ -1,4 +1,6 @@ import { getRouteApi, useNavigate } from "@tanstack/react-router"; +import GenericErrorView from "#/components/GenericErrorView.tsx"; +import LoadingView from "#/components/LoadingView.tsx"; import { useLichess } from "#/hooks/useLichess.ts"; const routeApi = getRouteApi("/callback"); @@ -11,11 +13,11 @@ const Callback = () => { if (status === "success") navigate({ to: "/chessboard" }); - if (status === "error") { - console.error(error); - } + if (status === "error") return ; - return
Loading...
; + return ( + + ); }; export default Callback; diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index f0baf99..66dc5d2 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -3,7 +3,8 @@ import { createRootRoute, HeadContent, Scripts } from "@tanstack/react-router"; import { TanStackRouterDevtoolsPanel } from "@tanstack/react-router-devtools"; import { type ReactNode, Suspense } from "react"; import { ToastContainer } from "react-toastify"; -import GenericErrorView from "#/components/Error/GenericErrorView.tsx"; +import GenericErrorView from "#/components/GenericErrorView.tsx"; +import LoadingView from "#/components/LoadingView.tsx"; import { MatomoAnalytics } from "#/components/MatomoAnalytics.tsx"; import { LichessUserProvider } from "#/context/LichessUserContext.tsx"; import Footer from "../components/Footer"; @@ -45,6 +46,7 @@ export const Route = createRootRoute({ }), shellComponent: RootDocument, errorComponent: ({ error }) => , + pendingComponent: () => , }); function RootDocument({ children }: { children: ReactNode }) { diff --git a/src/routes/callback.tsx b/src/routes/callback.tsx index 2af503a..a8b026e 100644 --- a/src/routes/callback.tsx +++ b/src/routes/callback.tsx @@ -1,6 +1,6 @@ import { createFileRoute, notFound } from "@tanstack/react-router"; import { z } from "zod"; -import GenericErrorView from "#/components/Error/GenericErrorView.tsx"; +import GenericErrorView from "#/components/GenericErrorView.tsx"; import Callback from "#/pages/Callback.tsx"; const callbackSchema = z.object({