import { useReducer, createContext, useContext, useEffect } from 'react'; import storage from '../utils/localStorage'; const StateContext = createContext({ editValues: null, notification: null, darkMode: false, setEditValues: (values) => {}, clearEdit: () => {}, notify: (message, severity, duration) => {}, clearNotif: () => {}, toggleDarkMode: () => {}, }); const stateReducer = (state, action) => { switch (action.type) { case 'SET_EDIT': return { ...state, editValues: action.payload, }; case 'CLEAR_EDIT': return { ...state, editValues: null, }; case 'SET_NOTIFICATION': return { ...state, notification: action.payload, }; case 'CLEAR_NOTIFICATION': return { ...state, notification: null, }; case 'TOGGLE_DARK_MODE': return { ...state, darkMode: !state.darkMode, }; default: return state; } }; export const StateProvider = ({ children }) => { const [state, dispatch] = useReducer(stateReducer, { editValues: null, notification: null, darkMode: false, }); useEffect(() => { const loadedDarkMode = storage.loadDarkMode(); if (loadedDarkMode === true) { dispatch({ type: 'TOGGLE_DARK_MODE', }); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const setEditValues = (valuesObj) => { dispatch({ type: 'SET_EDIT', payload: valuesObj, }); }; const clearEdit = () => { dispatch({ type: 'CLEAR_EDIT', }); }; let timeoutID = null; const notify = (message, severity = 'success', duration = 5) => { clearTimeout(timeoutID); dispatch({ type: 'SET_NOTIFICATION', payload: { message, severity, duration }, }); timeoutID = setTimeout(() => { dispatch({ type: 'CLEAR_NOTIFICATION', }); }, duration * 1000); }; const clearNotif = () => { dispatch({ type: 'CLEAR_NOTIFICATION', }); }; const toggleDarkMode = () => { dispatch({ type: 'TOGGLE_DARK_MODE', }); storage.saveDarkMode(!state.darkMode); }; return ( <StateContext.Provider value={{ editValues: state.editValues, notification: state.notification, darkMode: state.darkMode, setEditValues, clearEdit, notify, clearNotif, toggleDarkMode, }} > {children} </StateContext.Provider> ); }; export const useStateContext = () => useContext(StateContext);