Remove Suspense from root-providers and refine route checks

The Suspense wrapper was removed from root-providers.tsx to simplify code. For the Privacy Path Checking, a property was added to 'AuthRedirectListener' to allow customization of 'privatePathPrefixes', and the prefixes list was moved to the top. Also, explicit constant assertions were added in 'create-i18n-settings.ts' to ensure the types correctness.
This commit is contained in:
giancarlo
2024-04-21 19:53:16 +08:00
parent ae10f7b142
commit 7cbbae9fef
3 changed files with 27 additions and 30 deletions

View File

@@ -1,7 +1,5 @@
'use client'; 'use client';
import { Suspense } from 'react';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
@@ -46,25 +44,23 @@ export function RootProviders({
return ( return (
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<ReactQueryStreamedHydration> <ReactQueryStreamedHydration>
<Suspense fallback={null}> <I18nProvider settings={i18nSettings} resolver={i18nResolver}>
<I18nProvider settings={i18nSettings} resolver={i18nResolver}> <CaptchaProvider>
<CaptchaProvider> <CaptchaTokenSetter siteKey={captchaSiteKey} />
<CaptchaTokenSetter siteKey={captchaSiteKey} />
<AuthChangeListener appHomePath={pathsConfig.app.home}> <AuthChangeListener appHomePath={pathsConfig.app.home}>
<ThemeProvider <ThemeProvider
attribute="class" attribute="class"
enableSystem enableSystem
disableTransitionOnChange disableTransitionOnChange
defaultTheme={theme} defaultTheme={theme}
enableColorScheme={false} enableColorScheme={false}
> >
{children} {children}
</ThemeProvider> </ThemeProvider>
</AuthChangeListener> </AuthChangeListener>
</CaptchaProvider> </CaptchaProvider>
</I18nProvider> </I18nProvider>
</Suspense>
</ReactQueryStreamedHydration> </ReactQueryStreamedHydration>
</QueryClientProvider> </QueryClientProvider>
); );

View File

@@ -21,9 +21,9 @@ export function createI18nSettings({
fallbackLng: languages[0], fallbackLng: languages[0],
detection: undefined, detection: undefined,
lng, lng,
load: 'languageOnly', load: 'languageOnly' as const,
preload: false, preload: false as const,
lowerCaseLng: true, lowerCaseLng: true as const,
fallbackNS: ns, fallbackNS: ns,
ns, ns,
react: { react: {

View File

@@ -12,11 +12,15 @@ import {
useUserSession, useUserSession,
} from '../hooks/use-user-session'; } from '../hooks/use-user-session';
const PRIVATE_PATH_PREFIXES = ['/home', '/admin', '/join', '/update-password'];
function AuthRedirectListener({ function AuthRedirectListener({
children, children,
privatePathPrefixes = PRIVATE_PATH_PREFIXES,
appHomePath, appHomePath,
}: React.PropsWithChildren<{ }: React.PropsWithChildren<{
appHomePath: string; appHomePath: string;
privatePathPrefixes?: string[];
}>) { }>) {
const client = useSupabase(); const client = useSupabase();
const pathName = usePathname(); const pathName = usePathname();
@@ -30,7 +34,8 @@ function AuthRedirectListener({
const listener = client.auth.onAuthStateChange((_, user) => { const listener = client.auth.onAuthStateChange((_, user) => {
// log user out if user is falsy // log user out if user is falsy
// and if the current path is a private route // and if the current path is a private route
const shouldRedirectUser = !user && isPrivateRoute(pathName); const shouldRedirectUser =
!user && isPrivateRoute(pathName, privatePathPrefixes);
if (shouldRedirectUser) { if (shouldRedirectUser) {
// send user away when signed out // send user away when signed out
@@ -86,11 +91,7 @@ export function AuthChangeListener({
/** /**
* Determines if a given path is a private route. * Determines if a given path is a private route.
*
* @param {string} path - The path to check.
*/ */
function isPrivateRoute(path: string) { function isPrivateRoute(path: string, privatePathPrefixes: string[]) {
const prefixes = ['/home', '/admin', '/join', '/update-password']; return privatePathPrefixes.some((prefix) => path.startsWith(prefix));
return prefixes.some((prefix) => path.startsWith(prefix));
} }