Download src/components/shared/RootLoadingGuard.tsx from asnannp/DocDoeAI: direct link, hf CLI and curl.
- Browser
- Download file 3.01 kB
-
https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/shared/RootLoadingGuard.tsx
- Command line
-
hf download hf://spaces/asnannp/DocDoeAI/src/components/shared/RootLoadingGuard.tsx
-
curl -L -o RootLoadingGuard.tsx https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/shared/RootLoadingGuard.tsx
3.01 kB
| "use client"; | |
| import { useContext, useEffect, useState } from "react"; | |
| import { AuthContext } from "@/lib/auth/AuthProvider"; | |
| import { AppLoadingScreen } from "@/components/shared/AppLoadingScreen"; | |
| import { PageTransitionLoader } from "@/components/shared/PageTransitionLoader"; | |
| import { useRouter, usePathname } from "next/navigation"; | |
| import { isOnboardingCompleteEffective } from "@/lib/student-context"; | |
| import { | |
| isProtectedAppPath, | |
| resolveProtectedRouteRedirect, | |
| resolveOnboardingRedirect, | |
| shouldRenderAppChildren, | |
| shouldShowAppLoadingScreen, | |
| } from "@/lib/ui/loading-visibility"; | |
| export function RootLoadingGuard({ children }: { children: React.ReactNode }) { | |
| const auth = useContext(AuthContext); | |
| const router = useRouter(); | |
| const pathname = usePathname(); | |
| const [isRedirecting, setIsRedirecting] = useState(false); | |
| useEffect(() => { | |
| if (!isProtectedAppPath(pathname)) { | |
| const t = window.setTimeout(() => setIsRedirecting(false), 0); | |
| return () => window.clearTimeout(t); | |
| } | |
| if (!auth || auth.isLoading) { | |
| // Avoid sync setState in effect; clear any stale redirect lock. | |
| const t = window.setTimeout(() => setIsRedirecting(false), 0); | |
| return () => window.clearTimeout(t); | |
| } | |
| const authTarget = resolveProtectedRouteRedirect({ | |
| hasUser: Boolean(auth.user), | |
| isAuthLoading: auth.isLoading, | |
| pathname, | |
| }); | |
| if (authTarget) { | |
| router.replace(authTarget); | |
| return; | |
| } | |
| if (!auth.user) { | |
| const t = window.setTimeout(() => setIsRedirecting(false), 0); | |
| return () => window.clearTimeout(t); | |
| } | |
| let cancelled = false; | |
| void isOnboardingCompleteEffective().then((done) => { | |
| if (cancelled) return; | |
| const target = resolveOnboardingRedirect({ | |
| hasUser: Boolean(auth.user), | |
| isAuthLoading: auth.isLoading, | |
| pathname, | |
| onboardingComplete: done, | |
| }); | |
| if (target) { | |
| setIsRedirecting(true); | |
| router.push(target); | |
| } else { | |
| setIsRedirecting(false); | |
| } | |
| }); | |
| return () => { | |
| cancelled = true; | |
| }; | |
| }, [auth, pathname, router]); | |
| const protectedGuestRedirectPending = Boolean( | |
| auth && | |
| !auth.isLoading && | |
| !auth.user && | |
| isProtectedAppPath(pathname), | |
| ); | |
| const loadingInput = { | |
| hasAuthContext: Boolean(auth), | |
| isAuthLoading: auth?.isLoading ?? true, | |
| isRedirecting: isRedirecting || protectedGuestRedirectPending, | |
| pathname, | |
| }; | |
| const showLoader = shouldShowAppLoadingScreen(loadingInput); | |
| const renderChildren = shouldRenderAppChildren(loadingInput); | |
| const isOnboardingPage = pathname === "/onboarding"; | |
| return ( | |
| <> | |
| <AppLoadingScreen isVisible={showLoader} /> | |
| {/* Top-bar transitions only once children can paint — avoids stacking | |
| the progress bar under the full-screen boot loader. */} | |
| {renderChildren && !isOnboardingPage ? <PageTransitionLoader /> : null} | |
| {renderChildren ? children : null} | |
| </> | |
| ); | |
| } | |