import React, { useContext, useReducer, useState } from 'react'; import AuthContext from './AuthContext'; import authReducer from './AuthReducer'; import { USER_ACTIONS } from './AuthTypes'; import api from '../../utils/AxiosConfig'; // ### EXPORT useContext TO REDUCE NEEDED CODE IN CLIENT FILES export function useAuth() { return useContext(AuthContext); } function AuthState({ children }) { // ################################# // HOOKS // ################################# // ### CURRENTUSER_ACTIONS // set default user for first page load and hard reloads (<CTRL +> F5) const initial_currenUser = JSON.parse(localStorage.getItem('user')) || null; const [currentUser, dispatchCurrentUser] = useReducer(authReducer, initial_currenUser); // ### ACCESSTOKEN const [accessToken, setAccessToken] = useState(); // ################################# // FUNCTIONS // ################################# // ### LOGIN async function login(credentials) { let result = {}; try { result = await api.post( '/users/login', credentials, { withCredentials: true } ); } catch (error) { result = await api.post( '/users/adminlogin', credentials, { withCredentials: true } ); // try to match output with normal user result.data.record = { ...result.data.admin, isAdmin: true }; } // set current user to login and merge accessToken into currentUser dispatchCurrentUser({ type: USER_ACTIONS.SET, payload: { ...result.data.record } }); setAccessToken(result.data.token); // TODO: don't store accessToken in localStorage, keep in memory only localStorage.setItem("accessToken", JSON.stringify(result.data.token)); return result; } // ### HANDLE LOGOUT async function logout() { dispatchCurrentUser({ type: USER_ACTIONS.DROP }); const result = await api.get( '/users/logout', ); return result; } // ### REQUEST PASSWORD RESET function requestPasswordReset(email) { return api.post('/users/requestpasswordreset', { email }); } // ### REQUEST PASSWORD RESET function requestEmailReset(email) { return api.post('/users/requestemailchange', { email }); } // ### RETURN return ( <AuthContext.Provider value={{ login, currentUser, logout, requestPasswordReset, requestEmailReset, USER_ACTIONS, dispatchCurrentUser }}> {children} </AuthContext.Provider> ); }; export default React.memo(AuthState);