diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index d3ce6769..f323c495 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -9,6 +9,7 @@ jobs: DATABASE_URL: postgresql://postgres:@localhost:5432/calendso BASE_URL: http://localhost:3000 JWT_SECRET: secret + GOOGLE_API_CREDENTIALS: "{}" # GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }} # CRON_API_KEY: xxx # CALENDSO_ENCRYPTION_KEY: xxx diff --git a/components/Shell.tsx b/components/Shell.tsx index c0f48da7..2194679e 100644 --- a/components/Shell.tsx +++ b/components/Shell.tsx @@ -11,7 +11,7 @@ import { import { signOut, useSession } from "next-auth/client"; import Link from "next/link"; import { useRouter } from "next/router"; -import React, { ReactNode, useEffect } from "react"; +import React, { ReactNode, useEffect, useState } from "react"; import { Toaster } from "react-hot-toast"; import LicenseBanner from "@ee/components/LicenseBanner"; @@ -37,7 +37,11 @@ import { useViewerI18n } from "./I18nLanguageHandler"; import Logo from "./Logo"; function useMeQuery() { - const meQuery = trpc.useQuery(["viewer.me"]); + const meQuery = trpc.useQuery(["viewer.me"], { + retry(failureCount) { + return failureCount > 3; + }, + }); return meQuery; } @@ -45,7 +49,6 @@ function useMeQuery() { function useRedirectToLoginIfUnauthenticated() { const [session, loading] = useSession(); const router = useRouter(); - const query = useMeQuery(); useEffect(() => { if (!loading && !session) { @@ -56,28 +59,36 @@ function useRedirectToLoginIfUnauthenticated() { }, }); } - }, [loading, session, router]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [loading, session]); - if (query.status !== "loading" && !query.data) { - router.replace("/auth/login"); - } + return { + loading: loading && !session, + }; } function useRedirectToOnboardingIfNeeded() { - const [session, loading] = useSession(); const router = useRouter(); const query = useMeQuery(); const user = query.data; + const [isRedirectingToOnboarding, setRedirecting] = useState(false); useEffect(() => { - if (!loading && user) { - if (shouldShowOnboarding(user)) { - router.replace({ - pathname: "/getting-started", - }); - } + if (user && shouldShowOnboarding(user)) { + setRedirecting(true); } - }, [loading, session, router, user]); + }, [router, user]); + useEffect(() => { + if (isRedirectingToOnboarding) { + router.replace({ + pathname: "/getting-started", + }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isRedirectingToOnboarding]); + return { + isRedirectingToOnboarding, + }; } export function ShellSubHeading(props: { @@ -109,8 +120,8 @@ export default function Shell(props: { }) { const { t } = useLocale(); const router = useRouter(); - useRedirectToLoginIfUnauthenticated(); - useRedirectToOnboardingIfNeeded(); + const { loading } = useRedirectToLoginIfUnauthenticated(); + const { isRedirectingToOnboarding } = useRedirectToOnboardingIfNeeded(); const telemetry = useTelemetry(); @@ -157,7 +168,7 @@ export default function Shell(props: { const i18n = useViewerI18n(); - if (i18n.status === "loading") { + if (i18n.status === "loading" || isRedirectingToOnboarding || loading) { // show spinner whilst i18n is loading to avoid language flicker return (