Skip to content
Snippets Groups Projects
API.js 12.6 KiB
Newer Older
Ingrid's avatar
Ingrid committed
import axios from "axios";
Sondre Malerud's avatar
Sondre Malerud committed
import { useAuthStore } from "@/stores/authStore.js";
import jwt_decode from "jwt-decode";
import router from "@/router/index";

export const API = {

  /**
   * API method to send a login request.
   * If login succeeds, the logged in User and their token
   * is saved to the Pinia AuthStore
   *
   * @param email email address of the user to log in as
   * @param password password to log in with
   * @returns a Result with whether the login attempt succeeded
   */
  login: async (request) => {
    const authStore = useAuthStore();
    let token;
    authStore.logout(); //in case someone for some reason is logged in

    return axios.post(
      `${import.meta.env.VITE_BACKEND_URL}/login`,
      request,
    )
      .then(async (response) => {
        token = response.data;
        const id = (jwt_decode(token)).id;

        return API.getAccount(id, token)
          .then((user) => {
            authStore.setAccount(user);
            authStore.setToken(token);
            API.getProfiles()
              .then(response => { authStore.setProfiles(response) })
              .catch(() => { throw new Error() })
            return;
Sondre Malerud's avatar
Sondre Malerud committed
          })
          .catch(() => {
Sondre Malerud's avatar
Sondre Malerud committed
          });
      })
      .catch(() => {
        throw new Error();
      });
  },
Sondre Malerud's avatar
Sondre Malerud committed


  /**
   * API method to get a account by their ID
   * @param id ID number of the account to retrieve
   * @returns A promise that resolves to a User if the API call succeeds,
   * or is rejected if the API call fails
   */
  getAccount: async (id, token) => {
    return axios.get(`${import.meta.env.VITE_BACKEND_URL}/account/${id}`, {
      headers: { Authorization: `Bearer ${token}` },
    })
      .then((response) => {
        return response.data;
      })
      .catch(() => {
        throw new Error("Account not found or not accessible");
      });
  },
Sondre Malerud's avatar
Sondre Malerud committed

Sondre Malerud's avatar
Sondre Malerud committed

  /**
     * Sends the user into the home page logged in as the profile specified
     * @param id ID of the profile that the user will log in as 
     */
  selectProfile: async (id) => {
    const authStore = useAuthStore()
    return axios.get(`${import.meta.env.VITE_BACKEND_URL}/profile/${id}`, {
      headers: { Authorization: `Bearer ${authStore.token}` },
    })
      .then((response) => {
Katarzyna Szlejter's avatar
Katarzyna Szlejter committed
          authStore.setProfile(response.data)
          if (!response.data.restricted) {
              router.push('pincode')
          } else {
              router.push("/")
          }
Sondre Malerud's avatar
Sondre Malerud committed

      })
      .catch(() => {
        throw new Error("Profile not found or not accessible")
      })
  },

  /**
   * Upload profile image
Katarzyna Szlejter's avatar
Katarzyna Szlejter committed
   *
   * @param {Blob} image - the image file contents to upload. Must be a JPEG no bigger than 512kB
   * @param {Number} profileId - the ID of the profile to upload this image to
   * @returns {Promise<String>} A Promise that resolves to the URL of the uploaded image
   */
  uploadProfileImage: async (image, profileId) => {
    const authStore = useAuthStore();
    let fd = new FormData();
    fd.append("file", image);
    fd.append("profileId", profileId);

    return axios.post(`${import.meta.env.VITE_BACKEND_URL}/img`, fd, {
      headers: {
        Authorization: `Bearer ${authStore.token}`,
    })
      .then((response) => {
        return response.data;
      .catch(() => {
        throw new Error();
  },

  /**
   * Sends a request to create a new profile on the currently logged in account
Katarzyna Szlejter's avatar
Katarzyna Szlejter committed
   *
   * @typedef {{name: string, id?: number, accountId?: number, profileImageUrl: string, isRestricted: boolean}} ProfileType
   * @param {ProfileType} profile  - the partial data of profile to create
   * @returns {Promise<ProfileType>} the full profile after saving, with id and account ID set
   */
  addProfile: async (profile) => {
    const authStore = useAuthStore();
    if (!authStore.isLoggedIn) {
      throw new Error();
    }

    return axios.post(import.meta.env.VITE_BACKEND_URL + '/profile', profile,  {
      headers: { Authorization: "Bearer " + authStore.token },
    })
      .then((response) => {
        return response.data;
      }).catch(() => {
        throw new Error();
      })
Sondre Malerud's avatar
Sondre Malerud committed

Sondre Malerud's avatar
Sondre Malerud committed
    /**
     * @returns all profiles to the logged in user
     */
    getProfiles: async () => {
        const authStore = useAuthStore();
        if (!authStore.isLoggedIn) {
            throw new Error();
        }

    return axios.get(import.meta.env.VITE_BACKEND_URL + '/profile', {
      headers: { Authorization: "Bearer " + authStore.token },
Sondre Malerud's avatar
Sondre Malerud committed
    },
    )
      .then(response => {
        return response.data
      }).catch(() => {
        throw new Error();
      });
  },
Sondre Malerud's avatar
Sondre Malerud committed
    /**
     * Registers a new account and logs into it
     * @param email the email of the new account
     * @param password the password of the new account
     */
    addAccount: async (request) => {
Sondre Malerud's avatar
Sondre Malerud committed
        axios.post(import.meta.env.VITE_BACKEND_URL + '/account', request)
        .then(() => {
            API.login({email: request.email, password: request.password})
                .catch(err => {console.log(err)})
        })
        .catch(() => {throw new Error()})
Ingrid's avatar
Ingrid committed
    /**
     * fetches all fridge items belonging to the user that is currently logged in
     * @returns {Promise<*>}
Ingrid's avatar
Ingrid committed
     */
    getFridgeItems: async () =>{
        const authStore = useAuthStore();

        return axios.get(`${import.meta.env.VITE_BACKEND_URL}/fridge`, {
            headers: { Authorization: `Bearer ${authStore.token}` },
        })
Ingrid's avatar
Ingrid committed
            .then((response) => {
                authStore.setFridge(response.data)
Ingrid's avatar
Ingrid committed
                return response.data;
            }).catch(() => {
                throw new Error("Could not fetch fridge items");
            });
    },

    /**
     * Adds item(s) to the fridge
     * @param request List<Ingredient> listOfIngredients
     * @returns {Promise<void>}
     */
    addToFridge: async(request) =>{
        const authStore = useAuthStore();
        axios.post(`${import.meta.env.VITE_BACKEND_URL}/fridge/items`, request,{
            headers: { Authorization: `Bearer ${authStore.token}` },
        }).then((response) => {
            authStore.setFridge(response.data)
            return response.data;
        }).catch(()=> {
            throw new Error("Could not add item to fridge: ");
        })
},

    /**
     * Searches for registered items.
     * @param searchPhrase  Name of the item that one is looking for (e.g: "purre")
     * @returns {Promise<*>} list containing items that match the search phrase
    searchItems: async(searchPhrase)=> {
        return axios.get(`${import.meta.env.VITE_BACKEND_URL}/item/search?name=${searchPhrase}`, {
        }).then((response) => {
            console.log(response.data.content);
            return response.data.content;
        }).catch(()=> {
            throw new Error("Error when searching for item ");
        })
    },

    /**
     * Removes an amount of an ingredient from the frodge, and the action is then logged
     * @param request Log.Action action, Map<Integer, Amount>
     * Action available: CONSUMED, DISCARDED,ADDED_TO_FRIDGE
     * @returns {Promise<void>}
     */
        const authStore = useAuthStore();

        axios.put(`${import.meta.env.VITE_BACKEND_URL}/fridge/ingredientsAmount`, request,{
            headers: { Authorization: `Bearer ${authStore.token}` },
        }).then((response) => {
            authStore.setFridge(response.data);
            return response.data;
        }).catch(()=> {
            throw new Error("Could modify ingredient. ");
        })
    },

    /**
     * Changes the expiration date of an ingredient.
     * @param request ingredientId: id of the ingredient, newExpDate: the new expiration date of the ingredient
     * @returns {Promise<void>}
     */
    changeExpirationOfIngredient: async(request) => {
        const authStore = useAuthStore();

        axios.put(`${import.meta.env.VITE_BACKEND_URL}/fridge/ingredient`, request,{
            headers: { Authorization: `Bearer ${authStore.token}` },
        }).then((response) => {
            return response.data;
        }).catch(()=> {
            throw new Error("Could modify ingredient. ");
        })
    },

Sondre Malerud's avatar
Sondre Malerud committed
    /**
     * Getter for the shopping list of a logged in account
     * @returns a promise that resolves to an array of Ingredient objects representing the shopping list, or an error if it fails
     */
    getShoppingList: async () => {
      const authStore = useAuthStore();

      return axios.get(import.meta.env.VITE_BACKEND_URL + '/shoppinglist',
      {
        headers: { Authorization: "Bearer " + authStore.token },
      })
      .then((response) => {
        authStore.setItems(response.data)
        return response.data
      })
      .catch(() => {throw new Error()})
    },


    /**
     * Adds an item to the logged in account's shopping list
     * @param itemId the id of the item that will be added
     * @param amount the amount of the specified item that will be added
     */
    addItemToShoppingList: async (itemId, amount) => {
      const authStore = useAuthStore();
      return axios.put(import.meta.env.VITE_BACKEND_URL + '/shoppinglist/items/' + itemId + '/' + amount, "",
      {
        headers: { Authorization: "Bearer " + authStore.token }
      },
      )
      .then(response => {
        return response.data
      })
      .catch(err => {console.log(err)})
    },

    /**
     * Deletes an ingredient(item with amount) from the logged in account's shopping list
     * @param ingredientId the id of the ingredient that will be removed
     */
    deleteItemFromShoppingList: async (ingredientId) => {
      const authStore = useAuthStore();
      return axios.delete(import.meta.env.VITE_BACKEND_URL + '/shoppinglist/items/' + ingredientId, 
      {
        headers: {Authorization: "Bearer " + authStore.token }
      })
      .then(response => { return response.data; })      
      .catch(err => {console.log(err)})
    },

    /**
     * Adds a suggestion to the logged in account's shopping list
     * @param itemId the id of the item that will be suggested
     * @param amount the amount of the specified item that will be suggested
     */
    addSuggestion: async (itemId, amount) => {
      const authStore = useAuthStore();
      return axios.put(import.meta.env.VITE_BACKEND_URL + '/shoppinglist/suggestions/' + itemId + '/' + amount, "",
      {
        headers: { Authorization: "Bearer " + authStore.token }
      })
      .then(response => { return response.data; })      
      .catch(err => {console.log(err)})
    },


    /**
     * Accepts a suggestion and adds it to the shopping list, removing it from the suggestions list
     * @param id the id of the ingredient that will be added to the list
     */
    acceptSuggestion: async (id) => {
      const authStore = useAuthStore();
      return axios.put(import.meta.env.VITE_BACKEND_URL + '/shoppinglist/suggestions/accept/' + id, "",
      {
        headers: { Authorization: "Bearer " + authStore.token }
      })
      .then(response => { return response.data; })
      .catch(err => {console.log(err)})
    },

     /**
     * Declines a suggestion and removes it from the suggestions list
     * @param id the id of the ingredient that will be declined
     */
    declineSuggestion: async (id) => {
      const authStore = useAuthStore();
      return axios.delete(import.meta.env.VITE_BACKEND_URL + '/shoppinglist/suggestions/' + id,
      {
        headers: { Authorization: "Bearer " + authStore.token }
      })
      .then(response => { return response.data; })
      .catch(err => {console.log(err)})
    },


      // addIngredientsToFridge: async (ingredientIds) => {
      //   const authStore = useAuthStore();
      //   return axios.delete(`${import.meta.env.VITE_BACKEND_URL}/shoppinglist/purchased`, {
      //     headers: { Authorization: `Bearer ${authStore.token}`},
      //     data: { ingredientIds }
      //   })
      //   .then((response) => {return response.data})
      //   .catch(err => {console.log(err)})

      // },

      addIngredientsToFridge: async (ingredients) => {
        const authStore = useAuthStore();
        return axios.put(`${import.meta.env.VITE_BACKEND_URL}/shoppinglist/purchased`, ingredients, {
          headers: { Authorization: `Bearer ${authStore.token}`}
        })
        .then((response) => {return response.data})
        .catch(err => {console.log(err)})

      },

    /**
     * Get recipe based on id
     * @param id
     * @returns {Promise<*>}
     */
    getRecipe: async (id) => {
        return axios.get(`${import.meta.env.VITE_BACKEND_URL}/recipe/${id}`)
            .then((response) => {
                console.log(response.data);
                return response.data;
            })
            .catch((error) => {
                throw new Error(error);
            })
    }
Sondre Malerud's avatar
Sondre Malerud committed
}