"use client"; import { FC, ReactNode } from "react"; import { observer } from "mobx-react"; import { useRouter, useSearchParams, usePathname } from "next/navigation"; import useSWR from "swr"; // components import { LogoSpinner } from "@/components/common"; // helpers import { EPageTypes } from "@/helpers/authentication.helper"; // hooks import { useUser, useUserProfile, useUserSettings, useWorkspace } from "@/hooks/store"; type TPageType = EPageTypes; type TAuthenticationWrapper = { children: ReactNode; pageType?: TPageType; }; const isValidURL = (url: string): boolean => { const disallowedSchemes = /^(https?|ftp):\/\//i; return !disallowedSchemes.test(url); }; export const AuthenticationWrapper: FC = observer((props) => { const pathname = usePathname(); const router = useRouter(); const searchParams = useSearchParams(); const nextPath = searchParams.get("next_path"); // props const { children, pageType = EPageTypes.AUTHENTICATED } = props; // hooks const { isLoading: isUserLoading, data: currentUser, fetchCurrentUser } = useUser(); const { data: currentUserProfile } = useUserProfile(); const { data: currentUserSettings } = useUserSettings(); const { workspaces } = useWorkspace(); const { isLoading: isUserSWRLoading } = useSWR("USER_INFORMATION", async () => await fetchCurrentUser(), { revalidateOnFocus: false, shouldRetryOnError: false, }); const isUserOnboard = currentUserProfile?.is_onboarded || (currentUserProfile?.onboarding_step?.profile_complete && currentUserProfile?.onboarding_step?.workspace_create && currentUserProfile?.onboarding_step?.workspace_invite && currentUserProfile?.onboarding_step?.workspace_join) || false; const getWorkspaceRedirectionUrl = (): string => { let redirectionRoute = "/profile"; // validating the nextPath from the router query if (nextPath && isValidURL(nextPath.toString())) { redirectionRoute = nextPath.toString(); return redirectionRoute; } // validate the last and fallback workspace_slug const currentWorkspaceSlug = currentUserSettings?.workspace?.last_workspace_slug || currentUserSettings?.workspace?.fallback_workspace_slug; // validate the current workspace_slug is available in the user's workspace list const isCurrentWorkspaceValid = Object.values(workspaces || {}).findIndex( (workspace) => workspace.slug === currentWorkspaceSlug ); if (isCurrentWorkspaceValid >= 0) redirectionRoute = `/${currentWorkspaceSlug}`; return redirectionRoute; }; if ((isUserSWRLoading || isUserLoading) && !currentUser?.id) return (
); if (pageType === EPageTypes.PUBLIC) return <>{children}; if (pageType === EPageTypes.NON_AUTHENTICATED) { if (!currentUser?.id) return <>{children}; else { if (currentUserProfile?.id && isUserOnboard) { const currentRedirectRoute = getWorkspaceRedirectionUrl(); router.push(currentRedirectRoute); return <>; } else { router.push("/onboarding"); return <>; } } } if (pageType === EPageTypes.ONBOARDING) { if (!currentUser?.id) { router.push(`/${pathname ? `?next_path=${pathname}` : ``}`); return <>; } else { if (currentUser && currentUserProfile?.id && isUserOnboard) { const currentRedirectRoute = getWorkspaceRedirectionUrl(); router.push(currentRedirectRoute); return <>; } else return <>{children}; } } if (pageType === EPageTypes.SET_PASSWORD) { if (!currentUser?.id) { router.push(`/${pathname ? `?next_path=${pathname}` : ``}`); return <>; } else { if (currentUser && !currentUser?.is_password_autoset && currentUserProfile?.id && isUserOnboard) { const currentRedirectRoute = getWorkspaceRedirectionUrl(); router.push(currentRedirectRoute); return <>; } else return <>{children}; } } if (pageType === EPageTypes.AUTHENTICATED) { if (currentUser?.id) { if (currentUserProfile && currentUserProfile?.id && isUserOnboard) return <>{children}; else { router.push(`/onboarding`); return <>; } } else { router.push(`/${pathname ? `?next_path=${pathname}` : ``}`); return <>; } } return <>{children}; });