diff --git a/Client/src/Components/ProgressBars/index.css b/Client/src/Components/ProgressBars/index.css
new file mode 100644
index 000000000..37317228f
--- /dev/null
+++ b/Client/src/Components/ProgressBars/index.css
@@ -0,0 +1,18 @@
+.progress-bar-container{
+ background-color: #fafafa;
+ padding: var(--env-var-spacing-1-plus);
+}
+.progress-bar-container h2.MuiTypography-root,
+.progress-bar-container p.MuiTypography-root {
+ color: var(--env-var-color-2);
+ font-size: var(--env-var-font-size-medium);
+}
+.progress-bar-container p.MuiTypography-root {
+ opacity: 0.6;
+}
+.progress-bar-container p.MuiTypography-root:has(span){
+ font-size: 12px;
+}
+.progress-bar-container p.MuiTypography-root span {
+ padding-left: 2px;
+}
\ No newline at end of file
diff --git a/Client/src/Components/ProgressBars/index.jsx b/Client/src/Components/ProgressBars/index.jsx
new file mode 100644
index 000000000..3bcd31b16
--- /dev/null
+++ b/Client/src/Components/ProgressBars/index.jsx
@@ -0,0 +1,104 @@
+import React, { useState } from "react";
+import { useTheme } from "@emotion/react";
+import {
+ Box,
+ IconButton,
+ LinearProgress,
+ Stack,
+ Typography,
+} from "@mui/material";
+import CloseIcon from "@mui/icons-material/Close";
+import "./index.css";
+
+/**
+ * @param {Object} props - The component props.
+ * @returns {JSX.Element} The rendered component.
+ */
+
+const ProgressUpload = ({
+ icon,
+ label,
+ size,
+ progress = 0,
+ onClick,
+}) => {
+ const theme = useTheme();
+ return (
+
+
+ {icon ? (
+
+ {icon}
+
+ ) : (
+ ""
+ )}
+
+
+ {label}
+
+
+ {size}
+
+
+
+
+
+
+
+
+
+
+
+ {progress}
+ %
+
+
+
+ );
+};
+
+export default ProgressUpload;
diff --git a/Client/src/Components/TabPanels/ProfileSettings/ProfilePanel.jsx b/Client/src/Components/TabPanels/ProfileSettings/ProfilePanel.jsx
index 5bf540775..2675aedd9 100644
--- a/Client/src/Components/TabPanels/ProfileSettings/ProfilePanel.jsx
+++ b/Client/src/Components/TabPanels/ProfileSettings/ProfilePanel.jsx
@@ -1,14 +1,7 @@
import { useTheme } from "@emotion/react";
import { useState } from "react";
import TabPanel from "@mui/lab/TabPanel";
-import {
- Box,
- Divider,
- IconButton,
- Modal,
- Stack,
- Typography,
-} from "@mui/material";
+import { Box, Divider, Modal, Stack, Typography } from "@mui/material";
import ButtonSpinner from "../../ButtonSpinner";
import Button from "../../Button";
import EmailTextField from "../../TextFields/Email/EmailTextField";
@@ -18,8 +11,8 @@ import { editProfileValidation } from "../../../Validation/validation";
import { useDispatch, useSelector } from "react-redux";
import { update } from "../../../Features/Auth/authSlice";
import ImageField from "../../TextFields/Image";
-import DoDisturbAltIcon from "@mui/icons-material/DoDisturbAlt";
-import CloseIcon from "@mui/icons-material/Close";
+import ImageIcon from "@mui/icons-material/Image";
+import ProgressUpload from "../../ProgressBars";
/**
* ProfilePanel component displays a form for editing user profile information
@@ -78,15 +71,64 @@ const ProfilePanel = () => {
});
};
- //TODO - implement delete profile picture function
+ //TODO - add setPicture state to localData
+ const [picture, setPicture] = useState();
+ const [uploadProgress, setUploadProgress] = useState(0);
+ const [isUploading, setIsUploading] = useState(false);
+ const handlePicture = (event) => {
+ const pic = event.target.files[0];
+ console.log(pic);
+ //TODO - add setPicture state to localData
+ setPicture({ name: pic.name, type: pic.type, size: formatBytes(pic.size) });
+ setIsUploading(true);
+
+ setTimeout(() => {
+ //TODO - add setPicture state to localData
+ setPicture((prev) => ({ ...prev, src: URL.createObjectURL(pic) }));
+ }, 1500);
+
+ let progress = 0;
+ const interval = setInterval(() => {
+ progress += 10;
+ setUploadProgress(progress);
+ if (progress >= 100) {
+ clearInterval(interval);
+ }
+ }, 150);
+ };
+ const formatBytes = (bytes) => {
+ if (bytes === 0) return "0 Bytes";
+ const k = 1024;
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " MB";
+ };
+ const handleCancelUpload = () => {
+ //TODO - add setPicture state to localData
+ setPicture(null);
+ setUploadProgress(0);
+ setIsUploading(false);
+ };
+ const handleClosePictureModal = () => {
+ setIsOpen("");
+ setUploadProgress(0);
+ setIsUploading(false);
+ };
+
+ //TODO - revisit once localData is set up properly
const handleDeletePicture = () => {
setLoading(true);
setTimeout(() => {
+ //TODO - add setPicture state to localData
+ setPicture(null);
setLoading(false);
}, 2000);
};
//TODO - implement update profile function
- const handleUpdatePicture = () => {};
+ const handleUpdatePicture = () => {
+ setIsOpen("");
+ setUploadProgress(0);
+ setIsUploading(false);
+ };
//TODO - implement delete account function
const handleDeleteAccount = () => {};
//TODO - implement save profile function
@@ -199,7 +241,7 @@ const ProfilePanel = () => {
{/* TODO - Update placeholder values with redux data */}
{
onClick={handleDeletePicture}
isLoading={loading}
/>
- {/* TODO - modal popup for update pfp? */}