userActions.js 10.7 KB
import {
  LOAD_USER_REQUEST,
  LOAD_USER_SUCCESS,
  LOAD_USER_FAIL,
  FORGOT_PASSWORD_REQUEST,
  FORGOT_PASSWORD_SUCCESS,
  FORGOT_PASSWORD_FAIL,
  RESET_PASSWORD_REQUEST,
  RESET_PASSWORD_SUCCESS,
  RESET_PASSWORD_FAIL,
  UPDATE_USER_PROFILE_REQUEST,
  UPDATE_USER_PROFILE_SUCCESS,
  UPDATE_USER_PROFILE_FAIL,
  REGISTER_USER_REQUEST,
  REGISTER_USER_SUCCESS,
  REGISTER_USER_FAIL,
  CLEAR_ERRORS
} from "../constants/userConstants";
import axios from "axios";
import { getSession } from "next-auth/react";

// register a new user.
export const registerUser = userData => async dispatch => {
  try {
    dispatch({
      type: REGISTER_USER_REQUEST
    });

    // 1. # # # # # # # # # # # # #
    // First save the main user record.
    const config = {
      headers: {
        "Content-Type": "multipart/form-data"
      }
    };

    const userFormData = new FormData();
    userFormData.append("username", userData.mobile);
    userFormData.append("email", userData.email);
    userFormData.append("password", userData.password);
    userFormData.append("role", userData.role);

    const response = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/auth/local/register`, userFormData, config);

    console.log(`Register user done:`);
    console.log(response);

    if (response?.data?.status == "fail") {
      return response;
    }
    // Immediately after user creation based on the role of the user we need to create entry into the corresponding extension table.

    // Do for End user
    if (userData.role === "Channel Partner") {
      userData["userId"] = response.data.user.id;
      await registerChannelPartner(userData);
    }
    if (userData.role === "vendor") {
      console.log("userdata", userData);
      // userData["userId"] = response.data.user.id;
      await registerVendor({ ...userData, userId: response.data.user.id });
    }

    // console.log(`About to dispatch REGISTER_USER_SUCCESS`);
    dispatch({
      type: REGISTER_USER_SUCCESS
    });
  } catch (error) {
    console.log("Error while registering a user: ");
    console.log(error);

    dispatch({
      type: REGISTER_USER_FAIL,
      payload: error.response.data
    });
  }
};

const registerVendor = async vendorData => {
  const authUser = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/auth/local`, {
    identifier: vendorData.email,
    password: vendorData.password
  });
  console.log("jwt", authUser);
  const config = {
    headers: {
      Authorization: `Bearer ${authUser.data.jwt}`,
      "Content-Type": "application/json"
    }
  };

  const data = {
    data: {
      mobileNo: vendorData.mobile,
      name: vendorData.fullname,
      email: vendorData.email,
      user: authUser.data.user.id
    }
  };

  const response = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/vendors`, data, config);
  return response;
};

// register a new user.
export const loadUser = () => async dispatch => {
  const session = await getSession();

  if (session) {
    try {
      dispatch({
        type: LOAD_USER_REQUEST
      });

      const config = {
        headers: {
          Authorization: `Bearer ${session.jwt}`
        }
      };

      // Load the user.
      const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/users/me?populate[0]=profileImage`, config);

      dispatch({
        type: LOAD_USER_SUCCESS,
        payload: { ...response.data }
      });
    } catch (error) {
      console.log("Error while loading a user: ");
      console.log(error);

      dispatch({
        type: LOAD_USER_FAIL,
        payload: error.response.data
      });
    }
  }
};

// update profile.
export const updateUserProfile = userData => async dispatch => {
  const session = await getSession();
  if (!session) {
    throw new Error("You are not authenticated currently. Only authenticated users can update their own profile.");
  }

  try {
    dispatch({
      type: UPDATE_USER_PROFILE_REQUEST
    });

    const config = {
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${session.jwt}`
      }
    };

    const response = await axios.put(
      `${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/users-permissions/users/me`,
      {
        password: userData.password,
        fullName: userData.fullName,
        aboutMe: userData.aboutMe
      },
      config
    );

    const profileImageFormData = new FormData();
    profileImageFormData.append("field", "profileImage");
    profileImageFormData.append("ref", "plugin::users-permissions.user");
    profileImageFormData.append("refId", response.data.id);
    profileImageFormData.append("files", userData.avatarFiles[0]);
    const profileImageUploadResponse = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/upload`, profileImageFormData, {
      headers: {
        Authorization: `Bearer ${session.jwt}`
      }
    });
    // console.log("Profile image update response:");
    // console.log(profileImageUploadResponse);

    dispatch({
      type: UPDATE_USER_PROFILE_SUCCESS,
      payload: response.data
    });
  } catch (error) {
    console.log("Error while updating a user profile: ");
    console.log(error);

    dispatch({
      type: UPDATE_USER_PROFILE_FAIL,
      payload: error.response.data
    });
  }
};

// forgot password.
export const forgotPassword = email => async dispatch => {
  try {
    dispatch({
      type: FORGOT_PASSWORD_REQUEST
    });

    const config = {
      headers: {
        "Content-Type": "application/json"
      }
    };

    const response = await axios.post(
      `${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/auth/forgot-password`,
      {
        email
      },
      config
    );

    dispatch({
      type: FORGOT_PASSWORD_SUCCESS,
      payload: response.data.ok ? "Please check your inbox for instructions to reset your password." : "Error generating reset password link"
    });
  } catch (error) {
    console.log("Error while generating password reset link: ");
    console.log(error);

    dispatch({
      type: FORGOT_PASSWORD_FAIL,
      payload: error.response.data
    });
  }
};

// reset password.
export const resetPassword = (code, password, passwordConfirmation) => async dispatch => {
  try {
    dispatch({
      type: RESET_PASSWORD_REQUEST
    });

    const config = {
      headers: {
        "Content-Type": "application/json"
      }
    };

    const response = await axios.post(
      `${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/auth/reset-password`,
      {
        code,
        password,
        passwordConfirmation
      },
      config
    );

    const { user, jwt } = response.data;

    dispatch({
      type: RESET_PASSWORD_SUCCESS,
      payload: jwt ? "Password reset successfully." : "Error while resetting password."
    });
  } catch (error) {
    console.log("Error while resetting password: ");
    console.log(error);

    dispatch({
      type: RESET_PASSWORD_FAIL,
      payload: error.response.data
    });
  }
};

// Clear errors
export const clearErrors = () => async dispatch => {
  dispatch({
    type: CLEAR_ERRORS
  });
};

/** Channel partner record to be created alongwith user creation. */
/** This is an internal utility method which creates a CP when a user is created. */
const registerChannelPartner = async channelPartnerData => {
  const {
    data: { user, jwt }
  } = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/auth/local`, {
    identifier: channelPartnerData.email,
    password: channelPartnerData.password
  });

  // First save the main cp record.
  const config = {
    headers: {
      Authorization: `Bearer ${jwt}`,
      "Content-Type": "application/json"
    }
  };

  const cpData = {
    data: {
      companyName: channelPartnerData.companyName,
      companyType: channelPartnerData.companyType,
      contactPersonName: channelPartnerData.contactPersonName,
      email: channelPartnerData.email,
      communicationAddress: channelPartnerData.communicationAddress,
      mobileNo: channelPartnerData.mobileNo,
      city: channelPartnerData.city,
      state: channelPartnerData.state,
      reraNumber: channelPartnerData.reraNumber,
      regionOfOperation: channelPartnerData.regionOfOperation,
      sourcingManager: channelPartnerData.sourcingManager,
      pan: channelPartnerData.pan,
      memberOf: channelPartnerData.memberOf,
      termsAndConditions: channelPartnerData.termsAndConditions,
      /** userId is added after user is created in the registerUser method. */
      user: channelPartnerData.userId,
      publishedAt: null
    }
  };

  const response = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/channel-partners`, cpData, config);

  // Immediately after cp creation we can now go ahead and login with this user to generate a token, and use that to upload the image.
  if (channelPartnerData.panFile && channelPartnerData.panFile.length !== 0) {
    const panFileFormData = new FormData();
    panFileFormData.append("field", "panFile");
    panFileFormData.append("ref", "api::channel-partner.channel-partner");
    panFileFormData.append("refId", response.data.data.id);
    panFileFormData.append("files", channelPartnerData.panFile[0]);
    await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/upload`, panFileFormData, {
      headers: {
        Authorization: `Bearer ${jwt}`,
        "Content-Type": "multipart/form-data"
      }
    });
  }
};

/** End user record to be created alongwith user creation. */
/** This is an internal utility method which creates a end user when a user is created. */
const registerEndUser = async euData => {
  const {
    data: { user, jwt }
  } = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/auth/local`, {
    identifier: euData.email,
    password: euData.password
  });

  // First save the main cp record.
  const config = {
    headers: {
      Authorization: `Bearer ${jwt}`,
      "Content-Type": "application/json"
    }
  };

  const endUserData = {
    data: {
      mobileNo: euData.mobileNo,
      fullName: euData.fullName,
      whatsappAccepted: euData.whatsappAccepted,
      email: euData.email,
      /** userId is added after user is created in the registerUser method. */
      user: euData.userId,
      publishedAt: null
    }
  };

  const response = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/end-users`, endUserData, config);
};

/** End user record to be created alongwith user creation. */
/** This is an internal utility method which creates a end user when a user is created. */
export const finishEndUserOtpVerification = async verificationData => {
  // First save the main cp record.
  const config = {
    headers: {
      "Content-Type": "application/json"
    }
  };

  return await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/end-users/finish-otp-verification`, verificationData, config);
};