DEV Community

Abhijit Meshram
Abhijit Meshram

Posted on

Redux-toolkit

`rootReducer.js

import { combineReducers } from "redux";
import storage from "redux-persist/lib/storage";
import products from "./slices/product/products";
//--------auth------------------------
import signin from "./slices/auth/sign-in";
//--------LocalStorage-----------------------
import localStorage from "./slices/localstorage/localStorage";
//---------Dashboard----------------------
import home from "./slices/home";
//---------Access Permission-------------------
import menus from "./slices/access-permission/menus";
import roles from "./slices/access-permission/roles";
import employeeRoleMapping from "./slices/access-permission/employee-role-mapping";
//---------Masters-------------------
import levels from "./slices/masters/levels";
import States from "./slices/masters/State";
//---------Nodal Officer---------------------
import nodalOfficer from "./slices/nodal-officer/nodal-officer";
//---------Common---------------------
import common from "./slices/common";
//---------Customer---------------------
import customer from './slices/customer';
//---------meeting---------------------
import meetings from "./slices/meetings";
//---------meeting---------------------
import employee from "./slices/employee";
import zones from "./slices/masters/zones";
import cities from "./slices/masters/City";
//---------reports---------------------
import reports from "./slices/reports";

const rootPersistConfig = {
key: "root",
storage,
keyPrefix: "redux-",
whitelist: [],
};

const rootReducer = (state, action) => {
if (action.type == 'LOGOUT') {
// Reset the state to its initial values for all slices
state = {};
}
return combineReducers({
product: products,
signinData: signin,
localData: localStorage,
homeData: home,
menusData: menus,
rolesData: roles,
employeeRoleMappingData: employeeRoleMapping,
levelData: levels,
zoneData: zones,
stateData: States,
cityData: cities,
nodalOfficerData: nodalOfficer,
commonData: common,
customerData: customer,
meetingsData: meetings,
employeeData: employee,
reportsData: reports
})(state, action);
};

export { rootPersistConfig, rootReducer };

store.js

import { useMemo } from "react";
import { configureStore } from '@reduxjs/toolkit';
import { rootPersistConfig, rootReducer } from './rootReducer';
import { persistReducer } from 'redux-persist';

let store;

function initStore(initialState) {
return configureStore({
reducer: persistReducer(rootPersistConfig, rootReducer),
initialState,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: false,
immutableCheck: false,
}),
});
}

export const initializeStore = (preloadedState) => {
let initialStore = store ?? initStore(preloadedState);

// After navigating to a page with an initial Redux state, merge that state
// with the current state in the store, and create a new store
if (preloadedState && store) {
    initialStore = initStore({
        ...store.getState(),
        ...preloadedState,
    });
    // Reset the current store
    store = undefined;
}

// For SSG and SSR always create a new store
if (typeof window === "undefined") {
    return initialStore;
}
// Create the store once in the client
if (!store) store = initialStore;

return initialStore;
Enter fullscreen mode Exit fullscreen mode

};

export function useStore(initialState) {
return useMemo(() => initializeStore(initialState), [initialState]);
}

home.js

import { createSlice } from "@reduxjs/toolkit";
// utils
import axios from "../axios/axiosMain";
import api from "../api_urls";

const initialState = {
isLoading: false,
error: null,
meetDayList: [],
dashboardData: [],
reqsCustomersNodalOffsData : [],
graphData : []
};

const slice = createSlice({
name: "homeData",
initialState,
reducers: {
hasgetMeetingDayByMonthSucc(state, action) {
state.meetDayList = action.payload;
},
hasGetListOfMappedNodalOfficerSucc(state, action) {
state.dashboardData = action.payload;
},
hasReqsCustomersNodalOffsSucc(state, action) {
state.reqsCustomersNodalOffsData = action.payload;
},
hasReqGraphDataSucc(state, action) {
state.graphData = action.payload;
},
// HAS ERROR
hasError(state, action) {
state.error = action.payload;
},
},
});

export function getMeetingDayByMonth(month) {
return async (dispatch) => {
try {
const response = await axios.get(${api?.home_meetingday}/${month});
dispatch(slice.actions.hasgetMeetingDayByMonthSucc(response.data));
} catch (error) {
dispatch(slice.actions.hasError(error));
}
};
}

export function getListOfMappedNodalOfficer() {
return async (dispatch) => {
try {
const response = await axios.get(${api?.mapped_nodal_officers});
dispatch(slice.actions.hasGetListOfMappedNodalOfficerSucc(response.data));
} catch (error) {
dispatch(slice.actions.hasError(error));
}
};
}

export function getReqsCustomersNodalOffs() {
return async (dispatch) => {
try {
const response = await axios.get(${api?.reqs_customers_nodaloff});
dispatch(slice.actions.hasReqsCustomersNodalOffsSucc(response.data));
} catch (error) {
dispatch(slice.actions.hasError(error));
}
};
}

export function getDashboardGraphsData(payload) {
return async (dispatch) => {
try {
const response = await axios.post(${api?.get_dashboard_graph_data}, payload);
dispatch(slice.actions.hasReqGraphDataSucc(response.data));
} catch (error) {
dispatch(slice.actions.hasError(error));
}
};
}

// Reducer
export default slice.reducer;

axios.js

import axios from "axios";
import { toast } from "react-toastify";

const crypto = require("crypto");

const keyString = process.env.CRYPTO_SECURITY_KEY; // This must be exactly 16 characters
const key = Buffer.from(keyString, "utf-8");

const axiosInstance = axios.create({ baseURL: process.env.API_URL });

axiosInstance.interceptors.request.use((config) => {
// Encrypt the data before sending it
// if (config.data) {
// const jsonString = JSON.stringify(config.data);
// const iv = crypto.randomBytes(16); // Generate a random IV
// const cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
// let encrypted = cipher.update(jsonString, 'utf-8', 'binary');
// encrypted += cipher.final('binary');
// const encryptedBase64 = Buffer.from(encrypted, 'binary').toString('base64');
// const ivBase64 = iv.toString('base64');
// let encryptedPayload = ${ivBase64}:${encryptedBase64};
// config.data = {payload:encryptedPayload};
// }
return config;
});

axiosInstance.interceptors.response.use(
(response) => {
// Decrypt the response data
if (response && response.data && typeof response?.data?.data == "string") {
const encryptedData = response?.data?.data;
const parts = encryptedData.split(":");
const iv = Buffer.from(parts[0], "base64");
const encryptedText = Buffer.from(parts[1], "base64");
const decipher = crypto.createDecipheriv("aes-128-cbc", key, iv);
let decrypted = decipher.update(encryptedText, "binary", "utf-8");
decrypted += decipher.final("utf-8");
// Parse the decrypted JSON string
response.data.data = JSON.parse(decrypted);
}
if (response.data.statusCode == 200 && response.data.message) {
toast.success(


{response.data.message}

,
{
position: toast.POSITION.TOP_RIGHT,
hideProgressBar: true,
theme: "colored",
}
);
}
return response;
},
(error) => {
if (error?.response?.status === 400) {
error?.response?.data.errors && error?.response?.data.errors.length > 0
? error?.response?.data.errors.map((data) => {
toast.error(


{data}

,
{
position: toast.POSITION.TOP_RIGHT,
hideProgressBar: true,
theme: "colored",
}
);
})
: toast.error(


We're sorry for the inconvenience. Please try again after some
time.

,
{
position: toast.POSITION.TOP_RIGHT,
hideProgressBar: true,
theme: "colored",
}
);
} else if (
error?.response?.status === 404 ||
error?.response?.status === 500
) {
//Requested Resource Not Found OR Server Side Wrror
if (error?.response?.data.error) {
toast.error(


{error?.response?.data.error}.

,
{
position: toast.POSITION.TOP_RIGHT,
theme: "colored",
autoClose: 5000,
closeButton: false,
closeOnClick: false,
draggable: false,
pauseOnHover: false,
style: {
width: "400px",
},
}
);
} else {
toast.error(


{error?.response?.data.message}.

,
{
position: toast.POSITION.TOP_RIGHT,
theme: "colored",
autoClose: 5000,
closeButton: false,
closeOnClick: false,
draggable: false,
pauseOnHover: false,
style: {
width: "400px",
},
}
);
}
} else {
console.warn(
"Status : ",
error?.response?.status,
"Error Log :",
error?.response?.data
);
toast.error(


We're having trouble connecting to the server. Please try again later.

,
{
position: toast.POSITION.TOP_RIGHT,
theme: "colored",
autoClose: 5000,
closeButton: false,
closeOnClick: false,
draggable: false,
pauseOnHover: false,
style: {
width: "400px",
},
}
);
}
return Promise.reject(
(error.response && error.response?.data) || "Something went wrong"
);
}
);

export default axiosInstance;

axiosMain.js

const crypto = require("crypto");
import axios from "axios";
import Router from "next/router";
import { toast } from "react-toastify";
import Swal from "sweetalert2";

let isSwalOpen401 = false;
let isSwalOpen403 = false;

const keyString = process.env.CRYPTO_SECURITY_KEY; // This must be exactly 16 characters
const key = Buffer.from(keyString, "utf-8");

const axiosInstance = axios.create({ baseURL: process.env.API_URL });
axiosInstance.interceptors.request.use((config) => {
// Set Token In Process
const accessToken = JSON.parse(localStorage.getItem("accessToken"));
if (accessToken) {
config.headers["Authorization"] = Bearer ${accessToken};
}
if (config.data?.is_crypto) {
const jsonString = JSON.stringify(config.data);
const iv = crypto.randomBytes(16); // Generate a random IV
const cipher = crypto.createCipheriv("aes-128-cbc", key, iv);
let encrypted = cipher.update(jsonString, "utf-8", "binary");
encrypted += cipher.final("binary");
const encryptedBase64 = Buffer.from(encrypted, "binary").toString("base64");
const ivBase64 = iv.toString("base64");
let encryptedPayload = ${ivBase64}:${encryptedBase64};
config.data = { payload: encryptedPayload };
}
return config;
});
axiosInstance.interceptors.response.use(
(response) => {
// Decrypt the response data
if (response && response.data && typeof response?.data?.data == "string") {
const encryptedData = response?.data?.data;
const parts = encryptedData.split(":");
const iv = Buffer.from(parts[0], "base64");
const encryptedText = Buffer.from(parts[1], "base64");
const decipher = crypto.createDecipheriv("aes-128-cbc", key, iv);
let decrypted = decipher.update(encryptedText, "binary", "utf-8");
decrypted += decipher.final("utf-8");
// Parse the decrypted JSON string
response.data.data = JSON.parse(decrypted);
if (response.data.data?.accessToken) {
localStorage.setItem(
"accessToken",
JSON.stringify(response.data.data.accessToken)
);
isSwalOpen401 = false;
}
}
if (response.data.statusCode == 200 && response.data.message) {
toast.success(


{response.data.message}

,
{
position: toast.POSITION.TOP_RIGHT,
hideProgressBar: true,
theme: "colored",
}
);
}
return response;
},
(error) => {
if (error?.response?.status === 400) {
error?.response?.data.errors && error?.response?.data.errors.length > 0
? error?.response?.data.errors.map((data) => {
toast.error(


{data}

,
{
position: toast.POSITION.TOP_RIGHT,
hideProgressBar: true,
theme: "colored",
}
);
})
: toast.error(


We're sorry for the inconvenience. Please try again after some
time.

,
{
position: toast.POSITION.TOP_RIGHT,
hideProgressBar: true,
theme: "colored",
}
);
} else if (error?.response?.status === 401) {
//Unauthorized Request
if (!isSwalOpen401) {
isSwalOpen401 = true;
Swal.fire({
title: "",
text: "Your session has ended. Would you like to start over?",
icon: "warning",
showCancelButton: true,
confirmButtonText: "Yes",
cancelButtonText: "No",
allowOutsideClick: false,
}).then((result) => {
if (result.isConfirmed) {
axiosInstance.get(/authapi/refresh).finally(() => {});
} else {
axiosInstance.get(/authapi/logout).finally(() => {
isSwalOpen401 = false;
localStorage.clear();
Router.push("/");
});
}
});
}
} else if (error?.response?.status === 403) {
if (!isSwalOpen403) {
isSwalOpen403 = true;
Swal.fire({
title: "",
text: error?.response?.data.message,
icon: "warning",
showCancelButton: false,
showConfirmButton: false,
allowOutsideClick: false,
timer: 5000,
timerProgressBar: true,
didClose: () => {
axiosInstance.get(/authapi/logout).finally(() => {
isSwalOpen403 = false;
Router.push("/");
localStorage.clear();
});
},
});
}
} else if (error?.response?.status === 404) {
//Requested Resource Not Found OR Server Side Wrror
if (Router.pathname !== "/404") {
// Router.push("/404");
}
} else if (error?.response?.status === 500) {
//Requested Resource Not Found OR Server Side Wrror
if (error?.response?.data.error) {
toast.error(


{error?.response?.data.error}

,
{
position: toast.POSITION.TOP_RIGHT,
theme: "colored",
autoClose: 5000,
closeButton: false,
closeOnClick: false,
draggable: false,
pauseOnHover: false,
style: {
width: "400px",
},
}
);
} else {
toast.error(


{error?.response?.data.message}

,
{
position: toast.POSITION.TOP_RIGHT,
theme: "colored",
autoClose: 5000,
closeButton: false,
closeOnClick: false,
draggable: false,
pauseOnHover: false,
style: {
width: "400px",
},
}
);
}
} else {
console.warn(
"Status : ",
error?.response?.status,
"Error Log :",
error?.response?.data
);
toast.error(


We're having trouble connecting to the server. Please try again later.

,
{
position: toast.POSITION.TOP_RIGHT,
theme: "colored",
autoClose: 5000,
closeButton: false,
closeOnClick: false,
draggable: false,
pauseOnHover: false,
style: {
width: "400px",
},
}
);
}
return Promise.reject(
(error.response && error.response?.data) || "Something went wrong"
);
}
);
export default axiosInstance;

_app.js

import '../styles/globals.scss'
import Contentlayout from '../shared/layout-components/layout/content-layout'
import Authenticationlayout from '../shared/layout-components/layout/authentication-layout'
import { Provider } from "react-redux";
import { useStore } from "../shared/redux/store";
import PropTypes from 'prop-types';

const layouts = {
Contentlayout: Contentlayout,
Authenticationlayout: Authenticationlayout,
};
function MyApp({ Component, pageProps }) {
const store = useStore(pageProps?.initialReduxState);
const Layout = layouts[Component.layout] || ((pageProps) => {pageProps});
return (





)
}

MyApp.propTypes = {
Component: PropTypes.elementType,
pageProps: PropTypes.object,
};
export default MyApp;

`

Top comments (0)