Source: pages-sections/Profile-Sections/AccountInfo.js

import React, { useEffect } from "react";
import { makeStyles } from "@material-ui/core/styles";
import Button from "/components/CustomButtons/Button.js";
import { useAuth } from "../../context/AuthContext";
import { useRouter } from "next/router";
import Card from "/components/Card/Card.js";
import CardBody from "/components/Card/CardBody.js";
import CustomInput from "/components/CustomInput/CustomInput.js";
import InputAdornment from "@material-ui/core/InputAdornment";
import Icon from "@material-ui/core/Icon";
import { useState } from "react";
import {
  AccountCircle,
  FitnessCenter,
  SettingsApplications,
} from "@material-ui/icons";
import validatePassword from "../SignUp-Sections/validatePassword";

const useStyles = makeStyles({
  cardBody: {
    marginTop: "10px",
  },
  accountInfoContainer: {
    display: "flex",
    justifyContent: "space-between",
    alignItems: "center",
  },
  buttonContainer: {
    display: "flex",
    justifyContent: "center",
    marginTop: "15px",
  },
  formContainer: {
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    marginTop: "15px",
  },
  updatePasswordButton: {
    "&:hover": {
      backgroundColor: "rgba(0, 123, 255, 0.8)", // Adjust the color as needed
    },
  },
});

/**
 * The function `handleToggleForm` toggles the visibility of a change password form and changes the
 * color of the password field.
 */
export const handleToggleForm = () => {
  setShowChangePasswordForm((prev) => !prev);
  changePasswordColor == ""
    ? setChangePasswordColor("primary")
    : setChangePasswordColor("");
};

/**
 * The function `handleNewPasswordChange` updates the value of a new password based on user input.
 * @param event - The `event` parameter in the `handleNewPasswordChange` function is an object that
 * represents the event of changing the password input field.
 */
export const handleNewPasswordChange = (event) => {
  setNewPassword(event.target.value);
};

/**
 * The function `handleConfirmPasswordChange` sets the value of the confirm password based on the
 * input event.
 * @param event - The `event` parameter in the `handleConfirmPasswordChange` function is an object
 * that represents the event of changing the confirm password input field.
 */
export const handleConfirmPasswordChange = (event) => {
  setConfirmPassword(event.target.value);
};

/**
 * The handleSubmit function handles form submission for changing a password, including validation
 * and error handling.
 * @param event - The `event` parameter in the `handleSubmit` function is an event object that
 * represents an event of clicking the reset password button.
 * @returns The `handleSubmit` function is returning either an alert message for successful password
 * update or an error message for failed password update.
 */
export const handleSubmit = async (event) => {
  event.preventDefault();

  const validationError = validatePassword(newPassword, confirmPassword);

  if (validationError) {
    setNewPassword("");
    setConfirmPassword("");
    alert(validationError);
    return;
  }

  try {
    setError("");
    await changePassword(newPassword);
    alert("Password updated successfully!");
    setConfirmPassword("");
    setNewPassword("");
    router.push("/login");
  } catch (error) {
    setError("Failed to update password");
    alert("Failed to update password");
    setConfirmPassword("");
    setNewPassword("");
  }
};

/**
 * The `AccountInfo` function in JavaScript handles user information display and password change
 * functionality with validation and error handling.
 * @returns The `AccountInfo` component is returning a Card component containing user information such as
 * username and email. If the user is allowed to change their password, a "Change Password" button is
 * displayed. If the user clicks on the "Change Password" button, a form is shown where the user can
 * enter a new password and confirm it. There is also a button to update the password. Error messages
 * are displayed
 */
export function AccountInfo() {
  const classes = useStyles();
  const { currentUser, changePassword } = useAuth();
  const [showChangePasswordForm, setShowChangePasswordForm] = useState(false);
  const [allowChangePassword, setAllowChangePassword] = useState(false);
  const [newPassword, setNewPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [changePasswordColor, setChangePasswordColor] = useState("");
  const [error, setError] = useState("");
  const router = useRouter();

  /* The `useEffect` hook in the provided code snippet is checking if the user is logged in using
  email/password authentication. Here's a breakdown of what it does: */
  useEffect(() => {
    // Check if the user is logged in using email/password authentication
    if (currentUser) {
      const providerData = currentUser.providerData;
      const emailProvider = providerData.find(
        (provider) => provider.providerId === "password"
      );
      if (emailProvider && providerData.length === 1) {
        setAllowChangePassword(true);
      } else {
        setAllowChangePassword(false);
      }
    }
  }, [currentUser]);

  return (
    <Card>
      <CardBody className={classes.cardBody}>
        <div className={classes.accountInfoContainer}>
          <h5>Username: </h5>
          <h5>{currentUser.displayName}</h5>
        </div>
        <div className={classes.accountInfoContainer}>
          <h5>Email: </h5>
          <h5>{currentUser.email}</h5>
        </div>
        {allowChangePassword && (
          <div className={classes.accountInfoContainer}>
            <h5>Password: </h5>
            <Button onClick={handleToggleForm} color={changePasswordColor}>
              Change Password?
            </Button>
          </div>
        )}
        {showChangePasswordForm ? (
          <form action="">
            <div className={classes.formContainer}>
              <CustomInput
                labelText="New Password"
                id="pass"
                formControlProps={{
                  fullWidth: true,
                }}
                inputProps={{
                  type: "password",
                  value: newPassword,
                  onChange: handleNewPasswordChange,
                  endAdornment: (
                    <InputAdornment position="end">
                      <Icon className={classes.inputIconsColor}>
                        lock_outline
                      </Icon>
                    </InputAdornment>
                  ),
                  autoComplete: "off",
                }}
              />
              <CustomInput
                labelText="Reconfim Password"
                id="pass"
                formControlProps={{
                  fullWidth: true,
                }}
                inputProps={{
                  type: "password",
                  value: confirmPassword,
                  onChange: handleConfirmPasswordChange,
                  endAdornment: (
                    <InputAdornment position="end">
                      <Icon className={classes.inputIconsColor}>
                        lock_outline
                      </Icon>
                    </InputAdornment>
                  ),
                  autoComplete: "off",
                }}
              />
              <Button
                onClick={handleSubmit}
                className={classes.updatePasswordButton}
              >
                Update Password
              </Button>
              {error && <p>{error}</p>}
            </div>
          </form>
        ) : (
          ""
        )}
      </CardBody>
    </Card>
  );
}