diff --git a/webapp/package-lock.json b/webapp/package-lock.json
index f8f81ed..7e90efa 100644
--- a/webapp/package-lock.json
+++ b/webapp/package-lock.json
@@ -24,6 +24,7 @@
"@types/bcrypt": "^5.0.0",
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
+ "@types/redux-persist": "^4.0.0",
"apexcharts": "^3.42.0",
"autoprefixer": "10.4.14",
"axios": "^1.4.0",
@@ -1665,6 +1666,27 @@
"@types/react": "*"
}
},
+ "node_modules/@types/redux-persist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/redux-persist/-/redux-persist-4.0.0.tgz",
+ "integrity": "sha512-VyDn75G7+Xkebp5Lxowk2t7HeT4VLSy92nyoQu1dZxk+ySBBdvV0yVR/upE4z24eVFxMp6Fo3CisQpkl4v1k3w==",
+ "license": "MIT",
+ "dependencies": {
+ "redux": "^3.6.0"
+ }
+ },
+ "node_modules/@types/redux-persist/node_modules/redux": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz",
+ "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==",
+ "license": "MIT",
+ "dependencies": {
+ "lodash": "^4.2.1",
+ "lodash-es": "^4.2.1",
+ "loose-envify": "^1.1.0",
+ "symbol-observable": "^1.0.3"
+ }
+ },
"node_modules/@types/scheduler": {
"version": "0.16.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
@@ -5919,6 +5941,7 @@
"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"
}
@@ -6708,6 +6731,15 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/symbol-observable": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/synckit": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz",
diff --git a/webapp/package.json b/webapp/package.json
index 9d18147..49f7c1b 100644
--- a/webapp/package.json
+++ b/webapp/package.json
@@ -25,6 +25,7 @@
"@types/bcrypt": "^5.0.0",
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
+ "@types/redux-persist": "^4.0.0",
"apexcharts": "^3.42.0",
"autoprefixer": "10.4.14",
"axios": "^1.4.0",
diff --git a/webapp/src/redux/provider.tsx b/webapp/src/redux/provider.tsx
index 1474c04..7d2a91f 100644
--- a/webapp/src/redux/provider.tsx
+++ b/webapp/src/redux/provider.tsx
@@ -7,10 +7,17 @@
*/
import React from "react"
-import { store } from './store'
import { Provider } from "react-redux"
+import { PersistGate } from 'redux-persist/integration/react';
+import { store, persistor } from './store';
export function ReduxProvider({children} : {children : React.ReactNode})
{
- return {children}
+ return (
+
+
+ {children}
+
+
+ )
}
\ No newline at end of file
diff --git a/webapp/src/redux/store.ts b/webapp/src/redux/store.ts
index b93fd37..0b463b8 100644
--- a/webapp/src/redux/store.ts
+++ b/webapp/src/redux/store.ts
@@ -3,11 +3,14 @@
* @description Redux store , all the app state goes right here
* * source : https://www.youtube.com/watch?v=Yokjzp91A4o
*/
-import { TypedUseSelectorHook , useSelector } from 'react-redux';
-import { configureStore } from '@reduxjs/toolkit'
-import authReducer from './features/auth-slice'
-import themeTypeReducer from './features/theme-slice'
-import alertReducer from './features/alert-slice'
+import { TypedUseSelectorHook, useSelector } from 'react-redux';
+import { configureStore } from '@reduxjs/toolkit';
+import { persistStore, persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } from 'redux-persist';
+import storage from 'redux-persist/lib/storage';
+import { combineReducers } from 'redux';
+import authReducer from './features/auth-slice';
+import themeTypeReducer from './features/theme-slice';
+import alertReducer from './features/alert-slice';
import settingsReducer from './features/settings-slice';
import sidebarReducer from './features/sidebar-slice';
import servicesReducer from './features/services-slice';
@@ -19,26 +22,49 @@ import equipmentsReducer from './features/equipments-slice';
import expensesReducer from './features/expenses-slice';
import incomesReducer from './features/incomes-slice';
-// init the store
+// Combine all reducers
+const rootReducer = combineReducers({
+ authReducer, // handle auth states
+ themeTypeReducer, // handle app theme
+ alertReducer, // handle app alert
+ settingsReducer, // handle the app settings
+ sidebarReducer, // handle dashboard sidebar state
+ servicesReducer, // handle the services page state
+ membersReducer, // handle the members page state
+ workersReducer, // handle the workers page state
+ productsReducer, // handle the products page state
+ statisticsReducer, // handle the statistics state
+ equipmentsReducer, // handle the equipments state
+ expensesReducer, // handle the expenses state
+ incomesReducer, // handle the incomes state
+});
+
+// Persist config
+const persistConfig = {
+ key: 'root',
+ version: 1,
+ storage,
+ whitelist: ['settingsReducer', 'authReducer', 'themeTypeReducer'], // Only persist these reducers
+};
+
+const persistedReducer = persistReducer(persistConfig, rootReducer);
+
+// Configure the store
export const store = configureStore({
- reducer: { // get state and do some work & update it after that
- authReducer, // handle auth states
- themeTypeReducer, // handle app theme
- alertReducer, // handle app alert
- settingsReducer, // handle the app settings
- sidebarReducer, // handle dashboard sidebar state
- servicesReducer, // handle the services page state
- membersReducer, // handle the members page state
- workersReducer, // handle the workers page state
- productsReducer, // handle the products page state
- statisticsReducer, // handle the statistics state
- equipmentsReducer, // handle the equipments state
- expensesReducer, // handle the expenses state
- incomesReducer, // handle the incomes state
- }
-})
-// export the needed types
-export type RootState = ReturnType
-export type AppDispatch = typeof store.dispatch
-// export the store selector
-export const useAppSelector : TypedUseSelectorHook = useSelector
\ No newline at end of file
+ reducer: persistedReducer,
+ middleware: (getDefaultMiddleware) =>
+ getDefaultMiddleware({
+ serializableCheck: {
+ ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
+ },
+ }),
+});
+
+export const persistor = persistStore(store);
+
+// Export types
+export type RootState = ReturnType;
+export type AppDispatch = typeof store.dispatch;
+
+// Export the store selector
+export const useAppSelector: TypedUseSelectorHook = useSelector;
\ No newline at end of file
diff --git a/webapp/src/redux/types.d.ts b/webapp/src/redux/types.d.ts
new file mode 100644
index 0000000..6228f5b
--- /dev/null
+++ b/webapp/src/redux/types.d.ts
@@ -0,0 +1,19 @@
+import { RootState, AppDispatch } from './store';
+
+declare module 'react-redux' {
+ interface DefaultRootState extends RootState {}
+ function useDispatch(): AppDispatch;
+}
+
+declare module 'redux-persist' {
+ interface PersistState {
+ version: number;
+ rehydrated: boolean;
+ }
+}
+
+declare module 'redux-persist/integration/react' {
+ import { PersistGateProps } from 'redux-persist/es/integration/react';
+ export { PersistGate };
+ export const PersistGate: React.ComponentType;
+}