mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-07-29 01:52:51 +00:00
react-router optimizations
This commit is contained in:
@@ -1,17 +1,14 @@
|
||||
import { memo, useContext } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import { Navigate } from 'react-router';
|
||||
import { Navigate, Outlet } from 'react-router';
|
||||
|
||||
import { AuthenticatedContext } from 'contexts/authentication';
|
||||
import type { RequiredChildrenProps } from 'utils';
|
||||
|
||||
const RequireAdmin: FC<RequiredChildrenProps> = ({ children }) => {
|
||||
const authenticatedContext = useContext(AuthenticatedContext);
|
||||
return authenticatedContext.me.admin ? (
|
||||
<>{children}</>
|
||||
) : (
|
||||
<Navigate replace to="/" />
|
||||
);
|
||||
// Layout-route guard: renders nested admin routes only for admins, otherwise
|
||||
// redirects home. Must be used inside the authenticated route subtree so that
|
||||
// AuthenticatedContext (and `me`) is available.
|
||||
const RequireAdmin = () => {
|
||||
const { me } = useContext(AuthenticatedContext);
|
||||
return me.admin ? <Outlet /> : <Navigate replace to="/" />;
|
||||
};
|
||||
|
||||
export default memo(RequireAdmin);
|
||||
|
||||
35
interface/src/components/routing/RootRedirect.tsx
Normal file
35
interface/src/components/routing/RootRedirect.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import { memo, useContext, useEffect, useRef } from 'react';
|
||||
import { Navigate } from 'react-router';
|
||||
|
||||
import { toast } from 'components/toast';
|
||||
import { AuthenticationContext } from 'contexts/authentication';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
type RootRedirectKind = 'unauthorized' | 'fileUpdated';
|
||||
|
||||
// Shows a one-shot toast and bounces back to "/". Used by the /unauthorized and
|
||||
// /fileUpdated routes. Resolves its own i18n message so it can be used directly
|
||||
// as a static route element.
|
||||
const RootRedirect = ({ kind }: { kind: RootRedirectKind }) => {
|
||||
const { LL } = useI18nContext();
|
||||
const { signOut } = useContext(AuthenticationContext);
|
||||
const hasShownToast = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
// Guard against StrictMode double-invoke / re-renders.
|
||||
if (hasShownToast.current) return;
|
||||
hasShownToast.current = true;
|
||||
|
||||
if (kind === 'unauthorized') {
|
||||
signOut(false);
|
||||
toast.success(LL.PLEASE_SIGNIN());
|
||||
} else {
|
||||
toast.success(LL.UPLOAD_SUCCESSFUL());
|
||||
}
|
||||
// Run once on mount.
|
||||
}, []);
|
||||
|
||||
return <Navigate to="/" replace />;
|
||||
};
|
||||
|
||||
export default memo(RootRedirect);
|
||||
@@ -2,3 +2,4 @@ export { default as RouterTabs } from './RouterTabs';
|
||||
export { default as RequireAdmin } from './RequireAdmin';
|
||||
export { default as RequireAuthenticated } from './RequireAuthenticated';
|
||||
export { default as RequireUnauthenticated } from './RequireUnauthenticated';
|
||||
export { default as RootRedirect } from './RootRedirect';
|
||||
|
||||
Reference in New Issue
Block a user