diff --git a/CHANGELOG.md b/CHANGELOG.md index 454569217a..6efc1e228e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to ### Changed +- ♻️(frontend) Refactor Auth component for improved redirection logic #1461 - ♻️(frontend) replace Arial font-family with token font #1411 - ♿(frontend) improve accessibility: - ♿(frontend) enable enter key to open documentss #1354 diff --git a/src/frontend/apps/impress/src/features/auth/components/Auth.tsx b/src/frontend/apps/impress/src/features/auth/components/Auth.tsx index addb481b38..414ac51b61 100644 --- a/src/frontend/apps/impress/src/features/auth/components/Auth.tsx +++ b/src/frontend/apps/impress/src/features/auth/components/Auth.tsx @@ -1,8 +1,7 @@ -import { Loader } from '@openfun/cunningham-react'; import { useRouter } from 'next/router'; -import { PropsWithChildren } from 'react'; +import { PropsWithChildren, useEffect, useState } from 'react'; -import { Box } from '@/components'; +import { Loading } from '@/components'; import { useConfig } from '@/core'; import { HOME_URL } from '../conf'; @@ -14,57 +13,65 @@ export const Auth = ({ children }: PropsWithChildren) => { useAuth(); const { replace, pathname } = useRouter(); const { data: config } = useConfig(); - - if (isLoading && !isFetchedAfterMount) { - return ( - - - - ); - } + const [isRedirecting, setIsRedirecting] = useState(false); /** - * If the user is authenticated and wanted initially to access a document, - * we redirect to the document page. + * If the user is authenticated and initially wanted to access a specific page, redirect him to that page now. */ - if (authenticated) { + useEffect(() => { + if (!authenticated || isRedirecting) { + return; + } + const authUrl = getAuthUrl(); if (authUrl) { - void replace(authUrl); - return ( - - - - ); + setIsRedirecting(true); + void replace(authUrl).then(() => setIsRedirecting(false)); } - } + }, [authenticated, isRedirecting, pathname, replace]); /** - * If the user is not authenticated and the path is not allowed, we redirect to the login page. + * If the user is not authenticated and not on a allowed pages */ - if (!authenticated && !pathAllowed) { + useEffect(() => { + if (isLoading || authenticated || pathAllowed || isRedirecting) { + return; + } + + /** + * The homepage feature is enabled, redirect them to the homepage + */ if (config?.FRONTEND_HOMEPAGE_FEATURE_ENABLED) { - void replace(HOME_URL); - } else { - gotoLogin(); + if (pathname !== HOME_URL) { + setIsRedirecting(true); + void replace(HOME_URL).then(() => setIsRedirecting(false)); + } + + return; } - return ( - - - - ); - } - /** - * If the user is authenticated and the path is the home page, we redirect to the index. - */ - if (pathname === HOME_URL && authenticated) { - void replace('/'); - return ( - - - - ); + /** + * Redirect them to login page + */ + setIsRedirecting(true); + gotoLogin(); + }, [ + authenticated, + pathAllowed, + config?.FRONTEND_HOMEPAGE_FEATURE_ENABLED, + replace, + isLoading, + isRedirecting, + pathname, + ]); + + const shouldShowLoader = + (isLoading && !isFetchedAfterMount) || + isRedirecting || + (!authenticated && !pathAllowed); + + if (shouldShowLoader) { + return ; } return children; diff --git a/src/frontend/apps/impress/src/features/auth/conf.ts b/src/frontend/apps/impress/src/features/auth/conf.ts index c44fe01884..14bb1d225f 100644 --- a/src/frontend/apps/impress/src/features/auth/conf.ts +++ b/src/frontend/apps/impress/src/features/auth/conf.ts @@ -1,6 +1,6 @@ import { baseApiUrl } from '@/api'; -export const HOME_URL = '/home'; +export const HOME_URL: string = '/home'; export const LOGIN_URL = `${baseApiUrl()}authenticate/`; export const LOGOUT_URL = `${baseApiUrl()}logout/`; export const PATH_AUTH_LOCAL_STORAGE = 'docs-path-auth'; diff --git a/src/frontend/apps/impress/src/features/auth/utils.ts b/src/frontend/apps/impress/src/features/auth/utils.ts index 41d50cf01b..81058e9751 100644 --- a/src/frontend/apps/impress/src/features/auth/utils.ts +++ b/src/frontend/apps/impress/src/features/auth/utils.ts @@ -1,7 +1,15 @@ import { terminateCrispSession } from '@/services/Crisp'; -import { LOGIN_URL, LOGOUT_URL, PATH_AUTH_LOCAL_STORAGE } from './conf'; +import { + HOME_URL, + LOGIN_URL, + LOGOUT_URL, + PATH_AUTH_LOCAL_STORAGE, +} from './conf'; +/** + * Get the stored auth URL from local storage + */ export const getAuthUrl = () => { const path_auth = localStorage.getItem(PATH_AUTH_LOCAL_STORAGE); if (path_auth) { @@ -10,8 +18,15 @@ export const getAuthUrl = () => { } }; +/** + * Store the current path in local storage if it's not the homepage or root + * so we can redirect the user to this path after login + */ export const setAuthUrl = () => { - if (window.location.pathname !== '/') { + if ( + window.location.pathname !== '/' && + window.location.pathname !== `${HOME_URL}/` + ) { localStorage.setItem(PATH_AUTH_LOCAL_STORAGE, window.location.pathname); } }; diff --git a/src/frontend/apps/impress/src/pages/home/index.tsx b/src/frontend/apps/impress/src/pages/home/index.tsx index dca212335f..9497d08805 100644 --- a/src/frontend/apps/impress/src/pages/home/index.tsx +++ b/src/frontend/apps/impress/src/pages/home/index.tsx @@ -1,7 +1,30 @@ +import { useRouter } from 'next/router'; +import { useEffect } from 'react'; + +import { Loading } from '@/components'; +import { useAuth } from '@/features/auth'; import { HomeContent } from '@/features/home'; import { NextPageWithLayout } from '@/types/next'; const Page: NextPageWithLayout = () => { + const { authenticated } = useAuth(); + const { replace } = useRouter(); + + /** + * If the user is authenticated we redirect him to the index page (grid). + */ + useEffect(() => { + if (!authenticated) { + return; + } + + void replace('/'); + }, [authenticated, replace]); + + if (authenticated) { + return ; + } + return ; };