133 lines
3.9 KiB
JavaScript
133 lines
3.9 KiB
JavaScript
"use client";
|
|
import { GET_USER_ROUTE } from "@/core/utils/routes";
|
|
import axios from "axios";
|
|
import { createContext, useCallback, useContext, useEffect, useReducer, useState } from "react";
|
|
|
|
const initAuth = {
|
|
initAuthState: false,
|
|
isAuth: false,
|
|
token: null,
|
|
user: {},
|
|
};
|
|
|
|
const authReducer = (state, action) => {
|
|
switch (action.type) {
|
|
case "CLEAR_USER":
|
|
return { ...state, user: {} };
|
|
case "CHANGE_USER":
|
|
return { ...state, user: action.user };
|
|
case "CHANGE_AUTH_STATE":
|
|
return { ...state, isAuth: action.isAuth };
|
|
case "CHANGE_INIT_AUTH":
|
|
return { ...state, initAuthState: action.initAuthState };
|
|
case "CLEAR_TOKEN":
|
|
localStorage.removeItem("_token");
|
|
return { ...state, token: null };
|
|
case "SET_TOKEN":
|
|
localStorage.setItem("_token", action.token);
|
|
return { ...state, token: action.token };
|
|
default:
|
|
return state;
|
|
}
|
|
};
|
|
|
|
const AuthContext = createContext();
|
|
|
|
export const AuthProvider = ({ children }) => {
|
|
const [errorState, setErrorState] = useState({ status: null, message: "" });
|
|
const [state, dispatch] = useReducer(authReducer, initAuth);
|
|
const [tokenChecked, setTokenChecked] = useState(false);
|
|
|
|
const clearUser = useCallback(() => {
|
|
dispatch({ type: "CLEAR_USER" });
|
|
}, []);
|
|
|
|
const changeUser = useCallback((user) => {
|
|
dispatch({ type: "CHANGE_USER", user });
|
|
}, []);
|
|
|
|
const changeAuthState = useCallback((isAuth) => {
|
|
dispatch({ type: "CHANGE_AUTH_STATE", isAuth });
|
|
}, []);
|
|
|
|
const changeInitAuth = useCallback((initAuthState) => {
|
|
dispatch({ type: "CHANGE_INIT_AUTH", initAuthState });
|
|
}, []);
|
|
|
|
const clearToken = useCallback(() => {
|
|
dispatch({ type: "CLEAR_TOKEN" });
|
|
}, []);
|
|
|
|
const setToken = useCallback((token) => {
|
|
dispatch({ type: "SET_TOKEN", token });
|
|
}, []);
|
|
|
|
const logout = () => {
|
|
clearToken();
|
|
clearUser();
|
|
changeAuthState(false);
|
|
changeInitAuth(true);
|
|
};
|
|
|
|
const getUser = useCallback(async () => {
|
|
try {
|
|
const { data } = await axios.get(GET_USER_ROUTE, {
|
|
headers: { authorization: `Bearer ${state.token}` },
|
|
});
|
|
changeUser(data.data);
|
|
changeAuthState(true);
|
|
changeInitAuth(true);
|
|
setErrorState(false);
|
|
} catch (error) {
|
|
if (error.response && error.response.status === 401) {
|
|
clearUser();
|
|
changeAuthState(false);
|
|
changeInitAuth(true);
|
|
return;
|
|
}
|
|
let status = error.response && error.response.status ? error.response.status : "نامشخص";
|
|
setErrorState({
|
|
status,
|
|
message: " مشکلی در احراز هویت رخ داده است . دقایقی بعد امتحان کنید!!!",
|
|
});
|
|
}
|
|
}, [state.token, clearUser, changeUser, changeAuthState, changeInitAuth]);
|
|
|
|
useEffect(() => {
|
|
const localToken = localStorage.getItem("_token");
|
|
if (localToken) dispatch({ type: "SET_TOKEN", token: localToken });
|
|
setTokenChecked(true);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (!tokenChecked) return;
|
|
|
|
if (!state.token) {
|
|
clearUser();
|
|
changeAuthState(false);
|
|
changeInitAuth(true);
|
|
return;
|
|
}
|
|
getUser();
|
|
}, [tokenChecked, state.token]);
|
|
|
|
return (
|
|
<AuthContext.Provider
|
|
value={{
|
|
token: state.token,
|
|
user: state.user,
|
|
isAuth: state.isAuth,
|
|
initAuthState: state.initAuthState,
|
|
getUser,
|
|
logout,
|
|
setToken,
|
|
errorState,
|
|
}}
|
|
>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useAuth = () => useContext(AuthContext);
|