Source: pages/profile.js

import React from "react";
// nodejs library that concatenates classes
import classNames from "classnames";
// @material-ui/core components
import { makeStyles } from "@material-ui/core/styles";
// @material-ui/icons
import Camera from "@material-ui/icons/Camera";
import Palette from "@material-ui/icons/Palette";
import Favorite from "@material-ui/icons/Favorite";
import IconButton from "@material-ui/core/IconButton";
import PhotoCamera from "@material-ui/icons/PhotoCamera";
import InputAdornment from "@material-ui/core/InputAdornment";
import People from "@material-ui/icons/People";
import Icon from "@material-ui/core/Icon";
// core components
import Header from "/components/Header/Header.js";
import Footer from "/components/Footer/Footer.js";
import Button from "/components/CustomButtons/Button.js";
import GridContainer from "/components/Grid/GridContainer.js";
import GridItem from "/components/Grid/GridItem.js";
import HeaderLinks from "/components/Header/HeaderLinks.js";
import NavPills from "/components/NavPills/NavPills.js";
import Parallax from "/components/Parallax/Parallax.js";
import { useAuth } from "../context/AuthContext";
import { useState, useEffect } from "react";
import { Router, useRouter } from "next/router";
import app from "../firebase";
import UserInfo from "../pages-sections/Profile-Sections/UserInfo";
import AccountInfo from "../pages-sections/Profile-Sections/AccountInfo";
import BMI from "../pages-sections/Profile-Sections/BMI";

import styles from "/styles/jss/nextjs-material-kit/pages/profilePage.js";
import {
  AccountCircle,
  FitnessCenter,
  SettingsApplications,
  Accessibility,
} from "@material-ui/icons";

const useStyles = makeStyles(styles);

/**
 * The function `handleProfilePicChange` sets loading state to true, calls `changeProfilePic`
 * function from context, and sets loading state to false after the update or if there is an error.
 * @param event - The `event` parameter in the `handleProfilePicChange` function represents an
 * event object that is passed when a profile picture change event occurs.
 */
export const handleProfilePicChange = async (event) => {
  try {
    setLoading(true); // Set loading state to true

    // Call changeProfilePic function from the context
    await changeProfilePic(event);

    setLoading(false); // Set loading state to false after the update
  } catch (error) {
    setLoading(false); // Set loading state to false if there is an error
  }
};

/**
 * The `ProfilePage` function is a React component that displays a user's profile information and
 * allows them to change their profile picture.
 * @param props - The `ProfilePage` function is a React component that takes `props` as a parameter.
 * @returns The `ProfilePage` component is being returned. It includes JSX elements for rendering a
 * user profile page with profile picture, user information, account details, and navigation tabs for
 * Body Mass Index, User Information, and Account Details. The component also handles authentication,
 * profile picture change functionality, and redirects to the login page if the user is not logged in.
 */
export function ProfilePage(props) {
  const classes = useStyles();
  const { ...rest } = props;
  const imageClasses = classNames(
    classes.imgRaised,
    classes.imgRoundedCircle,
    classes.imgFluid
  );
  const navImageClasses = classNames(classes.imgRounded, classes.imgGallery);
  const { currentUser, changeProfilePic } = useAuth();
  const [loading, setLoading] = useState(true);
  const router = useRouter();

  // Redirect if not logged in
  useEffect(() => {
    const checkAuth = async () => {
      try {
        if (currentUser === undefined) {
          // User not logged in, redirect to login page
          router.push("/login");
        } else {
          setLoading(false);
        }
      } catch (error) {
        console.error("Error checking authentication:", error);
        setLoading(false);
      }
    };

    checkAuth();
  }, [currentUser, Router]);

  // Render nothing if not authenticated or still loading
  if (currentUser === null || loading) {
    console.log("Loading");
    return <div></div>; // You can also render a loading spinner or message here
  }

  return (
    <div>
      <Header
        color="transparent"
        brand="ThisIsNotFair"
        rightLinks={<HeaderLinks />}
        fixed
        brandlink="/mainmenu"
        changeColorOnScroll={{
          height: 200,
          color: "white",
        }}
        {...rest}
      />
      <Parallax small filter image="/img/profile-bg.jpg" />
      <div className={classNames(classes.main, classes.mainRaised)}>
        <div>
          <div className={classes.container}>
            <GridContainer justify="center">
              <GridItem xs={12} sm={12} md={6}>
                <div className={classes.profile}>
                  <div>
                    <img
                      src={
                        currentUser.photoURL != undefined &&
                        currentUser.photoURL != null
                          ? currentUser.photoURL
                          : "/img/faces/avatar.jpg"
                      }
                      alt="..."
                      className={imageClasses}
                      style={{
                        borderRadius: "50%",
                        width: "120px",
                        height: "120px",
                        objectFit: "cover",
                      }}
                      onError={(e) => {
                        e.target.onerror = null; // Prevent infinite loop
                        e.target.src = "/img/faces/avatar.jpg"; // Set default image if an error occurs
                      }}
                    />

                    <div
                      className={classes.uploadIcon}
                      style={{ position: "relative", display: "inline-block" }}
                    >
                      <input
                        accept="image/*"
                        className={classes.input}
                        id="icon-button-file"
                        type="file"
                        style={{ display: "none" }}
                        onChange={(event) => handleProfilePicChange(event)}
                      />
                      <label htmlFor="icon-button-file">
                        <IconButton
                          color="primary"
                          aria-label="upload picture"
                          component="span"
                          style={{
                            position: "absolute",
                            bottom: 0,
                            right: 0,
                            backgroundColor: "#f5efd3",
                          }}
                        >
                          <PhotoCamera />
                        </IconButton>
                      </label>
                    </div>
                  </div>
                  <div className={classes.name}>
                    <h3 className={classes.title}>{currentUser.displayName}</h3>
                    <h6>ThisIsNotFair Family Member</h6>
                  </div>
                </div>
              </GridItem>
            </GridContainer>
            <GridContainer justify="center">
              <GridItem xs={12} sm={12} md={8} className={classes.navWrapper}>
                <NavPills
                  alignCenter
                  color="primary"
                  tabs={[
                    {
                      tabButton: "Body Mass Index",
                      tabIcon: FitnessCenter,
                      tabContent: <BMI />,
                    },
                    {
                      tabButton: "   User Information",
                      tabIcon: Accessibility,
                      tabContent: <UserInfo />,
                    },
                    {
                      tabButton: "Account Details",
                      tabIcon: AccountCircle,
                      tabContent: <AccountInfo />,
                    },
                  ]}
                  active={1}
                />
              </GridItem>
            </GridContainer>
          </div>
        </div>
      </div>
      <Footer />
    </div>
  );
}