fashionAvenue / client / src / context / AuthContext.js
AuthContext.js
Raw
import axios from 'axios';
import { createContext, useEffect, useState } from 'react';
import jwt_decode from 'jwt-decode';
import { useNavigate } from 'react-router-dom';
import jwtInterceptor from './jwtInterceptor';
import refreshToken from './refreshToken';

const AuthContext = createContext();

export const AuthContextProvider = ({ children }) => {
  const navigate = useNavigate();
  const [cartItems, setCartItems] = useState([]);
  const [user, setUser] = useState(() => {
    if (localStorage.getItem('tokens')) {
      let tokens = JSON.parse(localStorage.getItem('tokens'));
      return jwt_decode(tokens.access_token);
    }
    return null;
  });

  useEffect(() => {
    if (user) {
      jwtInterceptor
        .get('http://localhost:4000/cart/all')
        .then((res) => {
          console.log(res);
          setCartItems(res.data);
        })
        .catch((err) => {
          console.log(err);
          if (err.response.status === 401) {
            refreshToken().catch((err) => {
              console.log(err);
              logout();
              navigate('/login');
              alert('please log in again');
            });
          }
        });
    }
  }, [user]);

  const addToCart = async (productId) => {
    if (!user) {
      alert('please log in to add item in the cart');
    } else {
      await jwtInterceptor
        .put(`http://localhost:4000/cart/add/${productId}`)
        .then((res) => {
          window.location.reload();
        })
        .catch((err) => {
          if (err.response.status === 401) {
            refreshToken().catch((err) => {
              console.log(err);
              logout();
              navigate('/login');
              alert('please log in again');
            });
          }
        });
    }
  };

  const removeFromCart = async (productId) => {
    if (!user) {
      alert('please log in to add item in the cart');
    } else {
      await jwtInterceptor
        .put(`http://localhost:4000/cart/remove/${productId}`)
        .then((res) => {
          window.location.reload();
        })
        .catch((err) => {
          console.log(err);
          if (err.response.status === 401) {
            refreshToken().catch((err) => {
              console.log(err);
              logout();
              navigate('/login');
              alert('please log in again');
            });
          }
        });
    }
  };

  const deleteItem = async (productId) => {
    if (!user) {
      alert('please log in to add item in the cart');
    } else {
      await jwtInterceptor
        .delete(`http://localhost:4000/cart/${productId}`)
        .then((res) => {
          window.location.reload();
        })
        .catch((err) => {
          console.log(err);
          if (err.response.status === 401) {
            refreshToken().catch((err) => {
              console.log(err);
              logout();
              navigate('/login');
              alert('please log in again');
            });
          }
        });
    }
  };

  const login = async (payload) => {
    const apiResponse = await axios.post(
      'http://localhost:4000/auth/login',
      payload,
    );
    localStorage.setItem('tokens', JSON.stringify(apiResponse.data));
    setUser(jwt_decode(apiResponse.data.access_token));
    navigate('/');
    window.location.reload();
  };

  const logout = async () => {
    await jwtInterceptor.post('http://localhost:4000/auth/logout', {
      userId: user.sub,
    });
    localStorage.removeItem('tokens');
    setUser(null);
    setCartItems([]);
    navigate('/');
    window.location.reload();
  };

  return (
    <AuthContext.Provider
      value={{
        user,
        cartItems,
        login,
        logout,
        addToCart,
        removeFromCart,
        deleteItem,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
};

export default AuthContext;