diff --git a/frontend/admin-web/package-lock.json b/frontend/admin-web/package-lock.json
index 04f75e2b..8493706a 100644
--- a/frontend/admin-web/package-lock.json
+++ b/frontend/admin-web/package-lock.json
@@ -18,6 +18,7 @@
"react-dom": "^18.3.1",
"react-redux": "^9.2.0",
"recharts": "^2.15.0",
+ "redux-persist": "^6.0.0",
"xlsx": "^0.18.5",
"zustand": "^5.0.3"
},
@@ -5346,6 +5347,15 @@
"license": "MIT",
"peer": true
},
+ "node_modules/redux-persist": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz",
+ "integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "redux": ">4.0.0"
+ }
+ },
"node_modules/redux-thunk": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
diff --git a/frontend/admin-web/package.json b/frontend/admin-web/package.json
index 396f7dbc..33a11502 100644
--- a/frontend/admin-web/package.json
+++ b/frontend/admin-web/package.json
@@ -24,6 +24,7 @@
"react-dom": "^18.3.1",
"react-redux": "^9.2.0",
"recharts": "^2.15.0",
+ "redux-persist": "^6.0.0",
"xlsx": "^0.18.5",
"zustand": "^5.0.3"
},
diff --git a/frontend/admin-web/src/app/providers.tsx b/frontend/admin-web/src/app/providers.tsx
index 1e802eca..e47f00d6 100644
--- a/frontend/admin-web/src/app/providers.tsx
+++ b/frontend/admin-web/src/app/providers.tsx
@@ -1,9 +1,10 @@
'use client';
import { Provider } from 'react-redux';
+import { PersistGate } from 'redux-persist/integration/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { useState } from 'react';
-import { store } from '@/store/redux/store';
+import { store, persistor } from '@/store/redux/store';
export function Providers({ children }: { children: React.ReactNode }) {
const [queryClient] = useState(
@@ -20,7 +21,9 @@ export function Providers({ children }: { children: React.ReactNode }) {
return (
- {children}
+
+ {children}
+
);
}
diff --git a/frontend/admin-web/src/store/redux/slices/authSlice.ts b/frontend/admin-web/src/store/redux/slices/authSlice.ts
index 4ab72395..8d4c615f 100644
--- a/frontend/admin-web/src/store/redux/slices/authSlice.ts
+++ b/frontend/admin-web/src/store/redux/slices/authSlice.ts
@@ -1,4 +1,5 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
+import { REHYDRATE } from 'redux-persist';
import type { User } from '@/types/user.types';
interface AuthState {
@@ -51,6 +52,19 @@ const authSlice = createSlice({
}
},
},
+ extraReducers: (builder) => {
+ builder.addCase(REHYDRATE, (state, action: PayloadAction<{ auth?: AuthState } | undefined>) => {
+ if (action.payload?.auth) {
+ const rehydratedAuth = action.payload.auth;
+ state.user = rehydratedAuth.user;
+ state.token = rehydratedAuth.token;
+ state.refreshToken = rehydratedAuth.refreshToken;
+ state.permissions = rehydratedAuth.permissions;
+ state.isAuthenticated = rehydratedAuth.isAuthenticated;
+ }
+ state.loading = false;
+ });
+ },
});
export const { setCredentials, logout, setLoading, updateUser } = authSlice.actions;
diff --git a/frontend/admin-web/src/store/redux/store.ts b/frontend/admin-web/src/store/redux/store.ts
index 9a6350dd..9659a673 100644
--- a/frontend/admin-web/src/store/redux/store.ts
+++ b/frontend/admin-web/src/store/redux/store.ts
@@ -1,16 +1,46 @@
-import { configureStore } from '@reduxjs/toolkit';
+import { configureStore, combineReducers } from '@reduxjs/toolkit';
+import {
+ persistStore,
+ persistReducer,
+ FLUSH,
+ REHYDRATE,
+ PAUSE,
+ PERSIST,
+ PURGE,
+ REGISTER,
+} from 'redux-persist';
+import storage from 'redux-persist/lib/storage';
import authReducer from './slices/authSlice';
import settingsReducer from './slices/settingsSlice';
import notificationReducer from './slices/notificationSlice';
+const rootReducer = combineReducers({
+ auth: authReducer,
+ settings: settingsReducer,
+ notification: notificationReducer,
+});
+
+const persistConfig = {
+ key: 'rwadurian-admin',
+ version: 1,
+ storage,
+ whitelist: ['auth'], // εͺζδΉ
ε auth slice
+};
+
+const persistedReducer = persistReducer(persistConfig, rootReducer);
+
export const store = configureStore({
- reducer: {
- auth: authReducer,
- settings: settingsReducer,
- notification: notificationReducer,
- },
+ reducer: persistedReducer,
+ middleware: (getDefaultMiddleware) =>
+ getDefaultMiddleware({
+ serializableCheck: {
+ ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
+ },
+ }),
devTools: process.env.NODE_ENV !== 'production',
});
+export const persistor = persistStore(store);
+
export type RootState = ReturnType;
export type AppDispatch = typeof store.dispatch;