import React, { useState, useEffect } from "react";
import { useRouter } from "next/router";
import classNames from "classnames";
import { makeStyles } from "@material-ui/core/styles";
import InputAdornment from "@material-ui/core/InputAdornment";
import People from "@material-ui/icons/People";
import Icon from "@material-ui/core/Icon";
import Button from "/components/CustomButtons/Button.js";
import Card from "/components/Card/Card.js";
import CardBody from "/components/Card/CardBody.js";
import CardFooter from "/components/Card/CardFooter.js";
import CustomInput from "/components/CustomInput/CustomInput.js";
import { useAuth } from "../../context/AuthContext";
import styles from "/styles/jss/nextjs-material-kit/pages/profilePage.js";
import { FormControl, Select, MenuItem, InputLabel } from "@material-ui/core";
import { getDatabase, ref, onValue, set } from "firebase/database";
import {
AccountCircle,
LocationOn,
FitnessCenter,
Height,
SettingsApplications,
Person,
Wc,
} from "@material-ui/icons";
const useStyles = makeStyles(styles);
const useStyly = makeStyles({
card: {
marginTop: "10px",
},
cardBody: {
marginTop: "10px",
},
inputIconsColor: {
color: "#9c27b0",
},
button: {
"&:hover": {
backgroundColor: "primary",
},
},
formContainer: {
display: "flex",
flexDirection: "column",
alignItems: "center",
marginTop: "15px",
},
container: {
display: "flex",
justifyContent: "space-between",
alignItems: "center",
},
data: {
textAlign: "center",
paddingRight: "5%",
flex: "1",
},
cardFooterEdit: {
display: "flex",
justifyContent: "space-between",
},
cardFooterInfo: {
display: "flex",
justifyContent: "flex-end",
},
});
/**
* The `handleSubmit` function handles the form submission when the user updates their information.
* It checks if the height and weight are valid numbers and within a certain range. If the values are
* not valid, an alert is shown, and the form is reset to the original values. If the values are valid,
* the data object is constructed with the new values, and the user's data is updated in the Firebase
* Realtime Database. An alert is shown upon successful update, and the edit mode is disabled.
* @param event - The form submission event
* @returns If the height or weight is not valid, an alert is shown, and the form is reset to the original
* values. If the height and weight are valid, the user's data is updated in the Firebase Realtime Database,
* and an alert is shown upon successful update. The edit mode is then disabled.
*/
export const handleSubmit = (event) => {
event.preventDefault();
// Check if height and weight are valid numbers
const isValidHeight =
height === "" ||
(!isNaN(parseFloat(height)) &&
isFinite(height) &&
height > 0 &&
height <= 300);
const isValidWeight =
weight === "" ||
(!isNaN(parseFloat(weight)) &&
isFinite(weight) &&
weight > 0 &&
weight <= 200);
// If height or weight is not valid, show an alert and reset to original values
if (!isValidHeight || !isValidWeight) {
alert("Please enter valid values for height and weight.");
setLocation(originalLocation);
setAtheleteType(originalAthleteType);
setHeight(originalHeight);
setWeight(originalWeight);
setGender(originalGender);
return;
}
// Construct the data object with the new values
const newData = {
gender,
location,
athleteType,
height,
weight,
};
// Get a reference to the Firebase Realtime Database
const db = getDatabase();
// Construct the path to the user's data in the database
const userRef = ref(db, `users/${currentUser.uid}`);
// Update user's data in the database
set(userRef, newData)
.then(() => {
alert("Data updated successfully!");
setIsEditMode(false); // Disable edit mode after submission
})
.catch((error) => {
alert("Error updating data: ", error);
// Handle error
});
};
/**
* The `handleEdit` function enables the edit mode when the user clicks the "Edit" button.
* The user can then edit their information.
*/
export const handleEdit = () => {
setIsEditMode(true);
};
/**
* The `handleCancel` function cancels the changes made by the user and resets the form to the original
* values.
*/
export const handleCancel = () => {
setIsEditMode(false);
// Reset to original values
setLocation(originalLocation);
setAtheleteType(originalAthleteType);
setHeight(originalHeight);
setWeight(originalWeight);
setGender(originalGender);
};
/**
* The `UserInfo` function in JavaScript handles user information display and edit functionality
* with validation and error handling.
* @returns The `UserInfo` component is returning a Card component containing user information such as
* location, athlete type, height, and weight. If the user has not entered their information, the fields
* will be empty. If the user has entered their information, the fields will be displayed. The user can
* edit their information by clicking the "Edit" button. The user can then save or cancel the changes.
* If the user saves the changes, the data is updated in the Firebase Realtime Database.
* If the user cancels the changes, the form is reset to the original values.
* If the user has not entered valid values for height and weight, an alert is shown.
* If the user has entered valid values, the data is updated in the Firebase Realtime Database.
* An alert is shown upon successful update, and the edit mode is disabled.
* The user can also cancel the changes, and the form is reset to the original values.
*/
export function UserInfo() {
const classes = useStyles();
const classess = useStyly();
const { currentUser } = useAuth();
const router = useRouter();
const [location, setLocation] = useState("");
const [originalLocation, setOriginalLocation] = useState("");
const [athleteType, setAtheleteType] = useState("");
const [originalAthleteType, setOriginalAthleteType] = useState("");
const [height, setHeight] = useState("");
const [originalHeight, setOriginalHeight] = useState("");
const [weight, setWeight] = useState("");
const [originalWeight, setOriginalWeight] = useState("");
const [gender, setGender] = useState("");
const [originalGender, setOriginalGender] = useState("");
const [isEditMode, setIsEditMode] = useState(false);
// Fetch user data from Firebase when component mounts
useEffect(() => {
if (currentUser) {
// Get a reference to the Firebase Realtime Database
const db = getDatabase();
// Construct the path to the user's data in the database
const userRef = ref(db, `users/${currentUser.uid}`);
// Fetch user's data from the database
onValue(userRef, (snapshot) => {
const userData = snapshot.val(); // Retrieve the user's data
if (userData) {
// If user data exists, update the state with the name
setGender(userData.gender);
setOriginalGender(userData.gender);
setLocation(userData.location);
setOriginalLocation(userData.location);
setAtheleteType(userData.athleteType);
setOriginalAthleteType(userData.athleteType);
setHeight(userData.height);
setOriginalHeight(userData.height);
setWeight(userData.weight);
setOriginalWeight(userData.weight);
}
});
}
}, [currentUser]);
return (
<Card className={classess.card}>
<form className={classes.form} onSubmit={handleSubmit}>
{!isEditMode ? (
<div>
{/* display mode */}
<CardBody className={classess.cardBody}>
<div className={classess.container}>
<h5>Biological Gender: </h5>
<h5 className={gender === "" ? classess.data : ""}>
{gender === "" ? "" : gender}
</h5>
</div>
<div className={classess.container}>
<h5>Location: </h5>
<h5 className={location === "" ? classess.data : ""}>
{location === "" ? "" : location}
</h5>
</div>
<div className={classess.container}>
<h5>Athelete Type: </h5>
<h5 className={athleteType === "" ? classess.data : ""}>
{athleteType === "" ? "" : athleteType}
</h5>
</div>
<div className={classess.container}>
<h5>Height (cm): </h5>
<h5 className={height === "" ? classess.data : ""}>
{height === "" ? "" : height}
</h5>
</div>
<div className={classess.container}>
<h5>Weight (kg): </h5>
<h5 className={weight === "" ? classess.data : ""}>
{weight === "" ? "" : weight}
</h5>
</div>
</CardBody>
<div className={classes.cardFooterInfo}>
<Button simple color="primary" size="lg" onClick={handleEdit}>
Edit
</Button>
</div>
</div>
) : (
<div>
{/* edit mode */}
<CardBody>
<div>
<FormControl fullWidth>
<InputLabel id="gender-label">Biological Gender</InputLabel>
<Select
labelId="gender-label"
id="gender"
value={gender}
onChange={(e) => setGender(e.target.value)}
endAdornment={
<InputAdornment position="end">
<Wc className={classes.inputIconsColor} />
</InputAdornment>
}
>
<MenuItem value={"Male"}>Male</MenuItem>
<MenuItem value={"Female"}>Female</MenuItem>
<MenuItem value={"Non-binary"}>Non-binary</MenuItem>
</Select>
</FormControl>
</div>
<div>
{/* <CustomInput
labelText="Athelete Type"
id="athleteType"
formControlProps={{
fullWidth: true,
}}
inputProps={{
type: "text",
value: athleteType,
onChange: (e) => setAtheleteType(e.target.value),
endAdornment: (
<InputAdornment position="end">
<FitnessCenter className={classes.inputIconsColor} />
</InputAdornment>
),
}}
/> */}
<FormControl fullWidth>
<InputLabel id="athelete-type-label">
Athelete Type
</InputLabel>
<Select
labelId="athelete-type-label"
id="gender"
value={athleteType}
onChange={(e) => setAtheleteType(e.target.value)}
endAdornment={
<InputAdornment position="end">
<FitnessCenter className={classes.inputIconsColor} />
</InputAdornment>
}
>
<MenuItem value={"Runner"}>Runner</MenuItem>
<MenuItem value={"Cyclist"}>Cyclist</MenuItem>
</Select>
</FormControl>
</div>
<div>
<CustomInput
labelText="Location"
id="location"
formControlProps={{
fullWidth: true,
}}
inputProps={{
type: "text",
value: location,
onChange: (e) => setLocation(e.target.value),
endAdornment: (
<InputAdornment position="end">
<LocationOn className={classes.inputIconsColor} />
</InputAdornment>
),
}}
/>
</div>
<div>
<CustomInput
labelText="Height (cm)"
id="height"
formControlProps={{
fullWidth: true,
}}
inputProps={{
type: "text",
value: height,
onChange: (e) => setHeight(e.target.value),
endAdornment: (
<InputAdornment position="end">
<Height className={classes.inputIconsColor} />
</InputAdornment>
),
}}
/>
</div>
<div>
<CustomInput
labelText="Weight (kg)"
id="weight"
formControlProps={{
fullWidth: true,
}}
inputProps={{
type: "text",
value: weight,
onChange: (e) => setWeight(e.target.value),
endAdornment: (
<InputAdornment position="end">
<Person className={classes.inputIconsColor} />
</InputAdornment>
),
}}
/>
</div>
</CardBody>
<div className={classes.cardFooterEdit}>
<Button simple color="primary" size="lg" onClick={handleCancel}>
Cancel
</Button>
<Button simple color="primary" size="lg" onClick={handleSubmit}>
Save
</Button>
</div>
</div>
)}
</form>
</Card>
);
}