import { createStore, applyMiddleware, combineReducers } from "redux"; import { createWrapper, HYDRATE, REHYDRATE } from "next-redux-wrapper"; import thunkMiddleware from "redux-thunk"; import { reducer as formReducer } from "redux-form"; import autoMergeLevel2 from "redux-persist/lib/stateReconciler/autoMergeLevel2"; import autoMergeLevel1 from "redux-persist/lib/stateReconciler/autoMergeLevel1"; //import storage from "redux-persist/lib/storage"; import storage from "./storage"; import currentView from "./currentView/reducer"; import search from "./search/reducer"; import searchResultsObj from "./searchOutput/reducer"; import formData from "./formData/reducer"; import appealType from "./appealType/reducer"; import LPAData from "./lpa/reducer"; import accountDetails from "./accountDetails/reducer"; import awaitingSubmission from "./awaitingSubmission/reducer"; import myCases from "./myCases/reducer"; import myRepresentations from "./myRepresentations/reducer"; import watchedCases from "./watchedCases/reducer"; import govGateway from "./govgateway/reducer"; //COMBINING ALL REDUCERS const appReducer = combineReducers({ currentView, search, searchResultsObj, formData, appealType, LPAData, accountDetails, awaitingSubmission, myCases, myRepresentations, watchedCases, govGateway, form: formReducer, }); const combinedReducer = (state, action) => { if (action.type === "USER_LOGOUT") { // for all keys defined in your persistConfig(s) storage.removeItem("persist:acp"); // storage.removeItem('persist:otherKey') return appReducer(undefined, action); } return appReducer(state, action); }; const reducer = (state = {}, action) => { switch (action.type) { case HYDRATE: return { ...state, ...action.payload }; case "SERVER_ACTION": return { ...state, server: { ...state.server, progress: action.payload, }, }; case "CLIENT_ACTION": return { ...state, client: { ...state.client, progress: action.payload, }, }; case "GET_ITEMS": return { ...state, items: action.payload, loading: false, }; case "SET_ITEMS": return { ...state, items: action.payload, loading: false, }; default: return combinedReducer(state, action); } }; // BINDING MIDDLEWARE const bindMiddleware = (middleware) => { if (process.env.NODE_ENV !== "production") { const { composeWithDevTools } = require("redux-devtools-extension"); return composeWithDevTools(applyMiddleware(...middleware)); } return applyMiddleware(...middleware); }; const makeStore = ({ isServer }) => { if (isServer) { //If it's on server side, create a store return createStore(reducer, bindMiddleware([thunkMiddleware])); } else { //If it's on client side, create a store which will persist const { persistStore, persistReducer, createMigrate, } = require("redux-persist"); const storage = require("redux-persist/lib/storage").default; const persistConfig = { key: "acp", whitelist: [ // "currentView", // "search", // "searchResultsObj", "formData", "appealType", "LPAData", "accountDetails", "awaitingSubmission", "myCases", "myRepresentations", "watchedCases", "govGateway", "form", ], version: 1.1, storage: storage, stateReconciler: autoMergeLevel2, // if needed, use a safer storage migrate: (state) => { console.log("Migration Running!"); // console.log(state); return Promise.resolve(state); }, }; const persistedReducer = persistReducer(persistConfig, reducer); // Create a new reducer with our existing reducer const store = createStore( persistedReducer, bindMiddleware([thunkMiddleware]) ); // Creating the store again store.__persistor = persistStore(store); // This creates a persistor object & push that persisted object to .__persistor, so that we can avail the persistability feature return store; } }; export const setClientState = (clientState) => ({ type: SET_CLIENT_STATE, payload: clientState, }); // Export the wrapper & wrap the pages/_app.js with this wrapper only export const wrapper = createWrapper(makeStore);