Skip to content

Commit 80f9959

Browse files
committed
chore/ui: minimise layout shift for auth check
Signed-off-by: SeeuSim <[email protected]>
1 parent c94dd71 commit 80f9959

File tree

3 files changed

+54
-17
lines changed

3 files changed

+54
-17
lines changed
Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,36 @@
1+
import { useState } from 'react';
12
import { Outlet } from 'react-router-dom';
23

4+
import { AuthStoreProvider } from '@/stores/auth-store';
5+
6+
import NavBar from './nav-bar';
7+
38
export function RootLayout() {
9+
const [userId, setUserId] = useState('');
10+
const [username, setUsername] = useState('');
11+
const [email, setEmail] = useState('');
12+
const [isAdmin, setIsAdmin] = useState(false);
413
return (
514
<div className='text-text bg-background flex min-h-screen flex-col overscroll-contain'>
6-
<Outlet />
15+
<AuthStoreProvider
16+
value={{
17+
...{
18+
userId,
19+
setUserId,
20+
email,
21+
setEmail,
22+
username,
23+
setUsername,
24+
isAdmin,
25+
setIsAdmin,
26+
},
27+
}}
28+
>
29+
<NavBar />
30+
<main className='flex flex-1'>
31+
<Outlet />
32+
</main>
33+
</AuthStoreProvider>
734
</div>
835
);
936
}

frontend/src/components/blocks/route-guard.tsx

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ import {
1111

1212
import { ROUTES, UNAUTHED_ROUTES } from '@/lib/routes';
1313
import { checkIsAuthed } from '@/services/user-service';
14-
import { AuthStoreProvider } from '@/stores/auth-store';
14+
import { useAuthedRoute } from '@/stores/auth-store';
1515

1616
import { Loading } from './loading';
17-
import NavBar from './nav-bar';
1817

1918
export const loader =
2019
(queryClient: QueryClient) =>
@@ -50,26 +49,33 @@ export const RouteGuard = () => {
5049
<Await resolve={data.payload}>
5150
{({ authedPayload, isAuthedRoute, path: _p }) => {
5251
const [isLoading, setIsLoading] = useState(true);
52+
const hooks = useAuthedRoute();
5353
useEffect(() => {
5454
if (authedPayload.isAuthed !== isAuthedRoute) {
5555
navigate(isAuthedRoute ? ROUTES.LOGIN : ROUTES.HOME);
5656
}
5757

58+
const { isAdmin, email, username, userId } = authedPayload;
59+
60+
if (isAdmin && hooks.setIsAdmin) {
61+
hooks.setIsAdmin(true);
62+
}
63+
64+
if (email && hooks.setEmail) {
65+
hooks.setEmail(email);
66+
}
67+
68+
if (username && hooks.setUsername) {
69+
hooks.setUsername(username);
70+
}
71+
72+
if (userId && hooks.setUserId) {
73+
hooks.setUserId(userId);
74+
}
75+
5876
setIsLoading(false);
5977
}, [authedPayload]);
60-
return (
61-
<AuthStoreProvider
62-
value={{
63-
userId: authedPayload.userId ?? '',
64-
username: authedPayload.username ?? '',
65-
email: authedPayload.email ?? '',
66-
isAdmin: authedPayload.isAdmin ?? undefined,
67-
}}
68-
>
69-
<NavBar />
70-
<main className='flex flex-1'>{isLoading ? <Loading /> : <Outlet />}</main>
71-
</AuthStoreProvider>
72-
);
78+
return isLoading ? <Loading /> : <Outlet />;
7379
}}
7480
</Await>
7581
</Suspense>

frontend/src/stores/auth-store.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
import { createContext, useContext } from 'react';
1+
import { createContext, type Dispatch, type SetStateAction, useContext } from 'react';
22

33
type AuthStoreType = {
44
userId: string;
5+
setUserId?: Dispatch<SetStateAction<string>>;
56
username: string;
7+
setUsername?: Dispatch<SetStateAction<string>>;
68
email: string;
9+
setEmail?: Dispatch<SetStateAction<string>>;
710
isAdmin?: boolean;
11+
setIsAdmin?: Dispatch<SetStateAction<boolean>>;
812
};
913

1014
const AuthStore = createContext<AuthStoreType>({

0 commit comments

Comments
 (0)