diff --git a/front-end/peer-prep/src/components/UserPage/index.tsx b/front-end/peer-prep/src/components/UserPage/index.tsx
index ac5393f0..1ee7ab1e 100644
--- a/front-end/peer-prep/src/components/UserPage/index.tsx
+++ b/front-end/peer-prep/src/components/UserPage/index.tsx
@@ -1,211 +1,299 @@
import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
-import * as Styles from "./styles"
-import { TextField, Avatar, Snackbar,
- IconButton, Button, Dialog,
- DialogTitle, DialogActions, DialogContent, DialogContentText } from "@mui/material";
-import SaveIcon from '@mui/icons-material/Save';
-import CloseIcon from '@mui/icons-material/Close';
+import * as Styles from "./styles";
+import {
+ TextField,
+ Avatar,
+ Snackbar,
+ IconButton,
+ Button,
+ Dialog,
+ DialogTitle,
+ DialogActions,
+ DialogContent,
+ DialogContentText,
+} from "@mui/material";
+import SaveIcon from "@mui/icons-material/Save";
+import CloseIcon from "@mui/icons-material/Close";
import { useDispatch, useSelector } from "react-redux";
-import * as UserSlice from "../redux/reducers/User/UserSlice"
+import * as UserSlice from "../redux/reducers/User/UserSlice";
import axios from "axios";
import { auth } from "../Auth/Firebase";
const UserPage = () => {
- // for dispatching actions
- const dispatch = useDispatch()
- const navigate = useNavigate()
-
- // State for pop up box after editing user profile.
- const [isEditSuccess, setIsEditSuccess] = useState(false)
- const [hasEmptyDetails, setHasEmptyDetails] = useState(false)
-
- // State for deletion conformation pop up.
- const [deletionConfimation, setDeletionConfirmation] = useState(false)
-
- // Gets user details from firebase.
- const user = auth.currentUser;
- const authEmail = user?.providerData[0].email ?? ""
-
- const authUsername = user?.displayName ?? ""
- const authUid = user?.uid
-
- const isNewUser = useSelector(UserSlice.selectIsFirstTimeLogin)
- const currentUsername:string = useSelector(UserSlice.selectCurrentUsername)
- const currentEmail:string = useSelector(UserSlice.selectCurrentEmail)
- const currentFirstName:string = useSelector(UserSlice.selectCurrentFirstName)
- const currentLastName:string = useSelector(UserSlice.selectCurrentLastName)
- const currentAge:number = useSelector(UserSlice.selectCurrentAge)
-
- // Messages for user.
- const EditUserSuccess = "User profile edited!"
- const PromptUserDetails = "Please enter user details."
- const EmptyDetailsWarning = "User details cannot be empty!"
-
- // Gets user profile data.
- useEffect(() => {
- axios({
- method: 'get',
- url: `https://api.peerprepgroup51sem1y2023.xyz/users/${authUid}`
- }).then((response) => {
- const data = response.data.data;
- dispatch(UserSlice.updateUserData(data))
- }).catch((error) => {
- dispatch(UserSlice.updateCurrentEmail(authEmail))
- dispatch(UserSlice.updateCurrentUsername(authUsername))
- })
- },[])
-
- const openEditSuccessSnackbar = () => {
- setIsEditSuccess(true)
- };
-
- const closeEditSuccessSnackbar = () => {
- setIsEditSuccess(false)
- };
-
- const openDeleteConfirmation = () => {
- setDeletionConfirmation(true)
- }
-
- const closeDeleteConfirmation = () => {
- setDeletionConfirmation(false)
- }
-
- // First time creation for new user if user does not exist.
- const postUserData = () => {
- axios.post(`https://api.peerprepgroup51sem1y2023.xyz/users/`, {
- username: currentUsername,
- email: currentEmail,
- firstName: currentFirstName,
- lastName: currentLastName,
- age: currentAge,
- uid: authUid
- })
- .then(() => {
- setHasEmptyDetails(false)
- dispatch(UserSlice.setIsFirstTimeLogin(false))
- })
- .catch((error) => {
- const code = error.request.status
- if (code === 400) {
- setHasEmptyDetails(true)
- }
- });
- }
-
- // Updates user data after editing.
- const putUserData = () => axios.put(`https://api.peerprepgroup51sem1y2023.xyz/users/${authUid}`,
- {
- "username": currentUsername,
- "email": currentEmail,
- "firstName": currentFirstName,
- "lastName": currentLastName,
- "age": currentAge,
- "uid": authUid
- }).then(() => {
- setHasEmptyDetails(false)
- })
- .catch((error) => {
- const code = error.request.status
- if (code === 400) {
- setHasEmptyDetails(true)
- }
- })
-
- const handleEditUserData = () => {
- isNewUser ? postUserData() : putUserData()
- openEditSuccessSnackbar()
- }
-
- // Deletes user data from postgres database.
- const deleteUserData = () => {
- axios.delete(`https://api.peerprepgroup51sem1y2023.xyz/users/${authUid}`)
- .catch(() => {})
- }
-
- // Deletes user data from firebase.
- const deleteFirebaseUserData = () => {
- if (user) {
- user.delete()
- }
- }
-
- const handleDeleteUser = () => {
- closeDeleteConfirmation()
- navigate("/delete")
- deleteUserData()
- deleteFirebaseUserData()
- }
-
- return (
-
-
-
-
-
dispatch(UserSlice.updateCurrentUsername(event.target.value))}>
-
dispatch(UserSlice.updateCurrentEmail(event.target.value))}>
-
dispatch(UserSlice.updateCurrentFirstName(event.target.value))}>
-
dispatch(UserSlice.updateCurrentLastName(event.target.value))}>
-
dispatch(UserSlice.updateCurrentAge(event.target.value))}>
-
handleEditUserData()}>
-
-
-
-
-
-
- }/>
-
-
-
-
-
-
- )
-}
+ // for dispatching actions
+ const dispatch = useDispatch();
+ const navigate = useNavigate();
+
+ // State for pop up box after editing user profile.
+ const [isEditSuccess, setIsEditSuccess] = useState(false);
+ const [hasEmptyDetails, setHasEmptyDetails] = useState(false);
+
+ // State for deletion conformation pop up.
+ const [deletionConfimation, setDeletionConfirmation] = useState(false);
+
+ // Gets user details from firebase.
+ const user = auth.currentUser;
+ const authEmail = user?.providerData[0].email ?? "";
+
+ const authUsername = user?.displayName ?? "";
+ const authUid = user?.uid;
+
+ const isNewUser = useSelector(UserSlice.selectIsFirstTimeLogin);
+ const currentUsername: string = useSelector(
+ UserSlice.selectCurrentUsername
+ );
+ const currentEmail: string = useSelector(UserSlice.selectCurrentEmail);
+ const currentFirstName: string = useSelector(
+ UserSlice.selectCurrentFirstName
+ );
+ const currentLastName: string = useSelector(
+ UserSlice.selectCurrentLastName
+ );
+ const currentAge: number = useSelector(UserSlice.selectCurrentAge);
+
+ // Messages for user.
+ const EditUserSuccess = "User profile edited!";
+ const PromptUserDetails = "Please enter user details.";
+ const EmptyDetailsWarning = "User details cannot be empty!";
+
+ // Gets user profile data.
+ useEffect(() => {
+ axios({
+ method: "get",
+ url: `https://api.peerprepgroup51sem1y2023.xyz/users/${authUid}`,
+ })
+ .then((response) => {
+ const data = response.data.data;
+ dispatch(UserSlice.updateUserData(data));
+ })
+ .catch((error) => {
+ dispatch(UserSlice.updateCurrentEmail(authEmail));
+ dispatch(UserSlice.updateCurrentUsername(authUsername));
+ });
+ }, []);
+
+ const openEditSuccessSnackbar = () => {
+ setIsEditSuccess(true);
+ };
+
+ const closeEditSuccessSnackbar = () => {
+ setIsEditSuccess(false);
+ };
+
+ const openDeleteConfirmation = () => {
+ setDeletionConfirmation(true);
+ };
+
+ const closeDeleteConfirmation = () => {
+ setDeletionConfirmation(false);
+ };
+
+ // First time creation for new user if user does not exist.
+ const postUserData = () => {
+ axios
+ .post(`https://api.peerprepgroup51sem1y2023.xyz/users/`, {
+ username: currentUsername,
+ email: currentEmail,
+ firstName: currentFirstName,
+ lastName: currentLastName,
+ age: currentAge,
+ uid: authUid,
+ })
+ .then(() => {
+ setHasEmptyDetails(false);
+ dispatch(UserSlice.setIsFirstTimeLogin(false));
+ })
+ .catch((error) => {
+ const code = error.request.status;
+ if (code === 400) {
+ setHasEmptyDetails(true);
+ }
+ });
+ };
+
+ // Updates user data after editing.
+ const putUserData = () =>
+ axios
+ .put(`https://api.peerprepgroup51sem1y2023.xyz/users/${authUid}`, {
+ username: currentUsername,
+ email: currentEmail,
+ firstName: currentFirstName,
+ lastName: currentLastName,
+ age: currentAge,
+ uid: authUid,
+ })
+ .then(() => {
+ setHasEmptyDetails(false);
+ })
+ .catch((error) => {
+ const code = error.request.status;
+ if (code === 400) {
+ setHasEmptyDetails(true);
+ }
+ });
+
+ const handleEditUserData = () => {
+ isNewUser ? postUserData() : putUserData();
+ openEditSuccessSnackbar();
+ };
+
+ // Deletes user data from postgres database.
+ const deleteUserData = () => {
+ axios
+ .delete(`https://api.peerprepgroup51sem1y2023.xyz/users/${authUid}`)
+ .catch(() => {});
+ };
+
+ // Deletes user data from firebase.
+ const deleteFirebaseUserData = () => {
+ if (user) {
+ user.delete();
+ }
+ };
+
+ const handleDeleteUser = () => {
+ closeDeleteConfirmation();
+ navigate("/delete");
+ deleteUserData();
+ deleteFirebaseUserData();
+ };
+
+ return (
+
+
+
+
+
+ dispatch(
+ UserSlice.updateCurrentUsername(
+ event.target.value
+ )
+ )
+ }
+ >
+
+ dispatch(
+ UserSlice.updateCurrentEmail(event.target.value)
+ )
+ }
+ >
+
+ dispatch(
+ UserSlice.updateCurrentFirstName(
+ event.target.value
+ )
+ )
+ }
+ >
+
+ dispatch(
+ UserSlice.updateCurrentLastName(
+ event.target.value
+ )
+ )
+ }
+ >
+
+ dispatch(
+ UserSlice.updateCurrentAge(event.target.value)
+ )
+ }
+ >
+
handleEditUserData()}
+ >
+
+
+
+
+
+
+ }
+ />
+
+
+
+
+
+
+ );
+};
export default UserPage;
diff --git a/services/profile-service/src/controller/user-controller.ts b/services/profile-service/src/controller/user-controller.ts
index 0b5177f2..21ea0198 100644
--- a/services/profile-service/src/controller/user-controller.ts
+++ b/services/profile-service/src/controller/user-controller.ts
@@ -18,6 +18,7 @@ const ERR_MSG_BAD_REQUEST =
const ERR_MSG_AGE_NEGATIVE = "Invalid age: Age cannot be negative.";
const ERR_MSG_DUPLICATE =
"Update a resource that already exists or has conflicting information";
+const ERR_MSG_AGE_TOO_LARGE = "Invalid age: too large";
//helper function to validate data
async function validateData(userData: iUserData): Promise {
@@ -39,6 +40,9 @@ async function validateData(userData: iUserData): Promise {
if (userData.age < 0) {
return ERR_MSG_AGE_NEGATIVE;
}
+ if (userData.age >= 1000) {
+ return ERR_MSG_AGE_TOO_LARGE;
+ }
return null;
}