diff --git a/web/app/(commonLayout)/layout.tsx b/web/app/(commonLayout)/layout.tsx index 5ac39f1e39..db8644667c 100644 --- a/web/app/(commonLayout)/layout.tsx +++ b/web/app/(commonLayout)/layout.tsx @@ -1,5 +1,4 @@ import type { ReactNode } from 'react' -import * as React from 'react' import { AppInitializer } from '@/app/components/app-initializer' import InSiteMessageNotification from '@/app/components/app/in-site-message/notification' import AmplitudeProvider from '@/app/components/base/amplitude' @@ -14,7 +13,6 @@ import { EventEmitterContextProvider } from '@/context/event-emitter-provider' import { ModalContextProvider } from '@/context/modal-context-provider' import { ProviderContextProvider } from '@/context/provider-context-provider' import PartnerStack from '../components/billing/partner-stack' -import Splash from '../components/splash' import RoleRouteGuard from './role-route-guard' const Layout = ({ children }: { children: ReactNode }) => { @@ -37,7 +35,6 @@ const Layout = ({ children }: { children: ReactNode }) => { - diff --git a/web/app/(commonLayout)/role-route-guard.tsx b/web/app/(commonLayout)/role-route-guard.tsx index 483dfef095..37957994d1 100644 --- a/web/app/(commonLayout)/role-route-guard.tsx +++ b/web/app/(commonLayout)/role-route-guard.tsx @@ -1,10 +1,8 @@ 'use client' import type { ReactNode } from 'react' -import { useEffect } from 'react' -import Loading from '@/app/components/base/loading' import { useAppContext } from '@/context/app-context' -import { usePathname, useRouter } from '@/next/navigation' +import { redirect, usePathname } from '@/next/navigation' const datasetOperatorRedirectRoutes = ['/apps', '/app', '/explore', '/tools'] as const @@ -13,21 +11,11 @@ const isPathUnderRoute = (pathname: string, route: string) => pathname === route export default function RoleRouteGuard({ children }: { children: ReactNode }) { const { isCurrentWorkspaceDatasetOperator, isLoadingCurrentWorkspace } = useAppContext() const pathname = usePathname() - const router = useRouter() const shouldGuardRoute = datasetOperatorRedirectRoutes.some(route => isPathUnderRoute(pathname, route)) const shouldRedirect = shouldGuardRoute && !isLoadingCurrentWorkspace && isCurrentWorkspaceDatasetOperator - useEffect(() => { - if (shouldRedirect) - router.replace('/datasets') - }, [shouldRedirect, router]) - - // Block rendering only for guarded routes to avoid permission flicker. - if (shouldGuardRoute && isLoadingCurrentWorkspace) - return - if (shouldRedirect) - return null + return redirect('/datasets') return <>{children} } diff --git a/web/app/components/app-initializer.tsx b/web/app/components/app-initializer.tsx index e08ece6666..22e04520e7 100644 --- a/web/app/components/app-initializer.tsx +++ b/web/app/components/app-initializer.tsx @@ -3,7 +3,7 @@ import type { ReactNode } from 'react' import Cookies from 'js-cookie' import { parseAsBoolean, useQueryState } from 'nuqs' -import { useCallback, useEffect, useState } from 'react' +import { useCallback, useEffect } from 'react' import { EDUCATION_VERIFY_URL_SEARCHPARAMS_ACTION, EDUCATION_VERIFYING_LOCALSTORAGE_ITEM, @@ -25,7 +25,6 @@ export const AppInitializer = ({ const searchParams = useSearchParams() // Tokens are now stored in cookies, no need to check localStorage const pathname = usePathname() - const [init, setInit] = useState(false) const [oauthNewUser] = useQueryState( 'oauth_new_user', parseAsBoolean.withOptions({ history: 'replace' }), @@ -87,10 +86,7 @@ export const AppInitializer = ({ const redirectUrl = resolvePostLoginRedirect() if (redirectUrl) { location.replace(redirectUrl) - return } - - setInit(true) } catch { router.replace('/signin') @@ -98,5 +94,5 @@ export const AppInitializer = ({ })() }, [isSetupFinished, router, pathname, searchParams, oauthNewUser]) - return init ? children : null + return children } diff --git a/web/app/components/header/header-wrapper.tsx b/web/app/components/header/header-wrapper.tsx index c90f01a6b6..09adb2f6bf 100644 --- a/web/app/components/header/header-wrapper.tsx +++ b/web/app/components/header/header-wrapper.tsx @@ -18,7 +18,7 @@ const HeaderWrapper = ({ // Check if the current path is a workflow canvas & fullscreen const inWorkflowCanvas = pathname.endsWith('/workflow') const isPipelineCanvas = pathname.endsWith('/pipeline') - const workflowCanvasMaximize = localStorage.getItem('workflow-canvas-maximize') === 'true' + const workflowCanvasMaximize = typeof localStorage !== 'undefined' && localStorage.getItem('workflow-canvas-maximize') === 'true' const [hideHeader, setHideHeader] = useState(workflowCanvasMaximize) const { eventEmitter } = useEventEmitterContextContext() @@ -28,7 +28,7 @@ const HeaderWrapper = ({ }) return ( -
+
{children}
) diff --git a/web/app/components/splash.tsx b/web/app/components/splash.tsx deleted file mode 100644 index 4f5f484582..0000000000 --- a/web/app/components/splash.tsx +++ /dev/null @@ -1,21 +0,0 @@ -'use client' -import type { FC, PropsWithChildren } from 'react' -import * as React from 'react' -import { useIsLogin } from '@/service/use-common' -import Loading from './base/loading' - -const Splash: FC = () => { - // would auto redirect to signin page if not logged in - const { isLoading, data: loginData } = useIsLogin() - const isLoggedIn = loginData?.logged_in - - if (isLoading || !isLoggedIn) { - return ( -
- -
- ) - } - return null -} -export default React.memo(Splash) diff --git a/web/app/education-apply/hooks.ts b/web/app/education-apply/hooks.ts index 79faa8b3b2..6068545751 100644 --- a/web/app/education-apply/hooks.ts +++ b/web/app/education-apply/hooks.ts @@ -133,7 +133,7 @@ const useEducationReverifyNotice = ({ export const useEducationInit = () => { const setShowAccountSettingModal = useModalContextSelector(s => s.setShowAccountSettingModal) const setShowEducationExpireNoticeModal = useModalContextSelector(s => s.setShowEducationExpireNoticeModal) - const educationVerifying = localStorage.getItem(EDUCATION_VERIFYING_LOCALSTORAGE_ITEM) + const educationVerifying = typeof localStorage !== 'undefined' && localStorage.getItem(EDUCATION_VERIFYING_LOCALSTORAGE_ITEM) const searchParams = useSearchParams() const educationVerifyAction = searchParams.get('action') diff --git a/web/app/page.tsx b/web/app/page.tsx index 65f8827e01..1daf6fc49b 100644 --- a/web/app/page.tsx +++ b/web/app/page.tsx @@ -1,18 +1,5 @@ -import Loading from '@/app/components/base/loading' -import Link from '@/next/link' +import { redirect } from '@/next/navigation' -const Home = async () => { - return ( -
- -
- -
- 🚀 -
-
-
- ) +export default function Home() { + return redirect('/apps') } - -export default Home diff --git a/web/context/global-public-context.tsx b/web/context/global-public-context.tsx index 3a570fc7ef..e0ff645475 100644 --- a/web/context/global-public-context.tsx +++ b/web/context/global-public-context.tsx @@ -3,7 +3,6 @@ import type { FC, PropsWithChildren } from 'react' import type { SystemFeatures } from '@/types/feature' import { useQuery } from '@tanstack/react-query' import { create } from 'zustand' -import Loading from '@/app/components/base/loading' import { consoleClient } from '@/service/client' import { defaultSystemFeatures } from '@/types/feature' import { fetchSetupStatusWithCache } from '@/utils/setup-status' @@ -53,13 +52,11 @@ const GlobalPublicStoreProvider: FC = ({ }) => { // Fetch systemFeatures and setupStatus in parallel to reduce waterfall. // setupStatus is prefetched here and cached in localStorage for AppInitializer. - const { isPending } = useSystemFeaturesQuery() + useSystemFeaturesQuery() // Prefetch setupStatus for AppInitializer (result not needed here) useSetupStatusQuery() - if (isPending) - return
return <>{children} } export default GlobalPublicStoreProvider diff --git a/web/next.config.ts b/web/next.config.ts index aa4d9318f4..a635d1f538 100644 --- a/web/next.config.ts +++ b/web/next.config.ts @@ -21,15 +21,6 @@ const nextConfig: NextConfig = { // https://nextjs.org/docs/api-reference/next.config.js/ignoring-typescript-errors ignoreBuildErrors: true, }, - async redirects() { - return [ - { - source: '/', - destination: '/apps', - permanent: false, - }, - ] - }, output: 'standalone', compiler: { removeConsole: isDev ? false : { exclude: ['warn', 'error'] }, diff --git a/web/next/navigation.ts b/web/next/navigation.ts index ec7c112645..7147fb2f5d 100644 --- a/web/next/navigation.ts +++ b/web/next/navigation.ts @@ -1,4 +1,5 @@ export { + redirect, useParams, usePathname, useRouter,