feat: auth context
This commit is contained in:
98
src/context/auth.tsx
Normal file
98
src/context/auth.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import { useReducer, createContext, useEffect } from 'react';
|
||||
import axios from 'axios';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
interface ProviderProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
type InitialStateType = {
|
||||
user: any;
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
user: null,
|
||||
};
|
||||
|
||||
const Context = createContext<{
|
||||
state: InitialStateType;
|
||||
dispatch: any;
|
||||
}>({
|
||||
state: initialState,
|
||||
dispatch: () => null,
|
||||
});
|
||||
|
||||
const reducer = (state: InitialStateType, action) => {
|
||||
switch (action.type) {
|
||||
case 'LOGIN':
|
||||
return {
|
||||
...state,
|
||||
user: action.payload,
|
||||
};
|
||||
case 'LOGOUT':
|
||||
return {
|
||||
...state,
|
||||
user: null,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
const Provider = ({ children }: ProviderProps) => {
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
// get user info from local storage
|
||||
useEffect(() => {
|
||||
dispatch({
|
||||
type: 'LOGIN',
|
||||
payload: JSON.parse(window.localStorage.getItem('user')),
|
||||
});
|
||||
}, []);
|
||||
|
||||
axios.interceptors.response.use(
|
||||
function (response) {
|
||||
// any status code that lies within the range of 2XX causes this function to trigger
|
||||
return response;
|
||||
},
|
||||
function (error) {
|
||||
// any status codes that fall outside the range of 2XX cause this function to trigger
|
||||
let res = error.response;
|
||||
if (res.status === 401 && res.config && !res.config.__isRetryRequest) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get('/api/logout')
|
||||
.then((data) => {
|
||||
console.log('/401 error > logout');
|
||||
dispatch({ type: 'LOGOUT' });
|
||||
window.localStorage.removeItem('user');
|
||||
navigate('/login'); // Replace router.push with navigate
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('AXIOS INTERCEPTORS ERROR:', err);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// csrf - include tokens in the axios header every time a request is made
|
||||
useEffect(() => {
|
||||
const getCsrfToken = async () => {
|
||||
const { data } = await axios.get('/api/csrf-token');
|
||||
console.log('CSRFFFFF =>>>>', data);
|
||||
axios.defaults.headers['X-CSRF-TOKEN'] = data.getCsrfToken;
|
||||
};
|
||||
getCsrfToken();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Context.Provider value={{ state, dispatch }}>{children}</Context.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export { Context, Provider };
|
||||
Reference in New Issue
Block a user