Files
Checkmate/Client/src/Components/ProgressBars/index.jsx
T

183 lines
5.2 KiB
React
Raw Normal View History

2024-06-26 19:12:50 -04:00
import React from "react";
2024-06-26 19:06:10 -04:00
import { useTheme } from "@emotion/react";
2024-06-26 19:12:50 -04:00
import PropTypes from "prop-types";
2024-06-26 19:06:10 -04:00
import {
Box,
IconButton,
LinearProgress,
Stack,
Typography,
} from "@mui/material";
import CloseIcon from "@mui/icons-material/Close";
2024-07-02 14:51:31 -04:00
import ErrorOutlineOutlinedIcon from "@mui/icons-material/ErrorOutlineOutlined";
2024-06-26 19:06:10 -04:00
import "./index.css";
/**
* @param {Object} props - The component props.
2024-06-26 19:12:50 -04:00
* @param {JSX.Element} props.icon - The icon element to display (optional).
* @param {string} props.label - The label text for the progress item.
* @param {string} props.size - The size information for the progress item.
* @param {number} props.progress - The current progress value (0-100).
* @param {function} props.onClick - The function to handle click events on the remove button.
2024-07-02 14:56:02 -04:00
* @param {string} props.error - Error message to display if there's an error (optional).
2024-06-26 19:06:10 -04:00
* @returns {JSX.Element} The rendered component.
*/
2024-07-02 14:51:31 -04:00
const ProgressUpload = ({
icon,
label,
size,
progress = 0,
onClick,
error,
}) => {
2024-06-26 19:06:10 -04:00
const theme = useTheme();
2024-08-27 17:01:28 -04:00
2024-06-26 19:06:10 -04:00
return (
<Box
className="progress-bar-container"
2024-08-27 17:01:28 -04:00
mt={theme.spacing(10)}
p={theme.spacing(8)}
2024-06-26 19:06:10 -04:00
sx={{
minWidth: "200px",
height: "fit-content",
2024-08-27 17:01:28 -04:00
borderRadius: theme.shape.borderRadius,
border: 1,
borderColor: theme.palette.border.light,
2024-09-06 18:13:38 -04:00
backgroundColor: theme.palette.background.fill,
2024-08-27 17:01:28 -04:00
"&:has(.input-error)": {
borderColor: theme.palette.error.main,
backgroundColor: theme.palette.error.bg,
py: theme.spacing(4),
px: theme.spacing(8),
"& > .MuiStack-root > svg": {
fill: theme.palette.error.text,
width: "20px",
height: "20px",
},
},
2024-06-26 19:06:10 -04:00
}}
>
2024-07-02 14:51:31 -04:00
<Stack
direction="row"
2024-08-27 17:01:28 -04:00
mb={error ? 0 : theme.spacing(5)}
gap={theme.spacing(5)}
2024-09-06 18:13:38 -04:00
alignItems={error ? "center" : "flex-start"}
2024-07-02 14:51:31 -04:00
>
{error ? (
<ErrorOutlineOutlinedIcon />
) : icon ? (
2024-09-06 18:13:38 -04:00
<Box
2024-06-26 19:06:10 -04:00
sx={{
2024-09-06 18:13:38 -04:00
position: "relative",
height: 30,
minWidth: 30,
border: 1,
borderColor: theme.palette.border.dark,
borderRadius: 2,
2024-08-27 17:01:28 -04:00
backgroundColor: theme.palette.background.main,
2024-09-06 18:13:38 -04:00
"& svg": {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 23,
height: 23,
"& path": {
fill: theme.palette.other.icon,
},
},
2024-06-26 19:06:10 -04:00
}}
>
{icon}
2024-09-06 18:13:38 -04:00
</Box>
2024-06-26 19:06:10 -04:00
) : (
""
)}
2024-07-02 14:51:31 -04:00
{error ? (
2024-08-27 17:01:28 -04:00
<Typography
component="p"
className="input-error"
color={theme.palette.error.text}
>
2024-07-02 14:51:31 -04:00
{error}
2024-06-26 19:06:10 -04:00
</Typography>
2024-07-02 14:51:31 -04:00
) : (
2024-08-27 17:01:28 -04:00
<Box color={theme.palette.text.tertiary}>
<Typography component="h2" mb={theme.spacing(1.5)}>
2024-07-02 14:51:31 -04:00
{error ? error : label}
</Typography>
2024-08-27 17:01:28 -04:00
<Typography component="p" sx={{ opacity: 0.6 }}>
{!error && size}
</Typography>
2024-07-02 14:51:31 -04:00
</Box>
)}
2024-06-26 19:06:10 -04:00
<IconButton
onClick={onClick}
2024-07-02 14:51:31 -04:00
sx={
!error
? {
alignSelf: "flex-start",
ml: "auto",
2024-08-27 17:01:28 -04:00
mr: theme.spacing(-2.5),
mt: theme.spacing(-2.5),
padding: theme.spacing(2.5),
2024-07-02 14:51:31 -04:00
"&:focus": {
outline: "none",
},
}
: {
ml: "auto",
"&:focus": {
outline: "none",
},
2024-07-02 14:51:31 -04:00
}
}
2024-06-26 19:06:10 -04:00
>
<CloseIcon
sx={{
fontSize: "20px",
}}
/>
</IconButton>
</Stack>
2024-07-02 14:51:31 -04:00
{!error ? (
<Stack direction="row" alignItems="center">
2024-08-27 17:01:28 -04:00
<Box sx={{ width: "100%", mr: theme.spacing(5) }}>
2024-07-02 14:51:31 -04:00
<LinearProgress
variant="determinate"
value={progress}
sx={{
width: "100%",
height: "10px",
2024-08-27 17:01:28 -04:00
borderRadius: theme.shape.borderRadius,
2024-07-02 14:51:31 -04:00
maxWidth: "500px",
2024-08-27 17:01:28 -04:00
backgroundColor: theme.palette.border.light,
2024-07-02 14:51:31 -04:00
}}
/>
</Box>
2024-08-27 17:01:28 -04:00
<Typography
component="p"
sx={{ minWidth: "max-content", opacity: 0.6 }}
>
2024-07-02 14:51:31 -04:00
{progress}
<span>%</span>
</Typography>
</Stack>
) : (
""
)}
2024-06-26 19:06:10 -04:00
</Box>
);
};
2024-06-26 19:12:50 -04:00
ProgressUpload.propTypes = {
icon: PropTypes.element, // JSX element for the icon (optional)
label: PropTypes.string.isRequired, // Label text for the progress item
size: PropTypes.string.isRequired, // Size information for the progress item
progress: PropTypes.number.isRequired, // Current progress value (0-100)
onClick: PropTypes.func.isRequired, // Function to handle click events on the remove button
2024-07-02 14:56:02 -04:00
error: PropTypes.string, // Error message to display if there's an error (optional)
2024-06-26 19:12:50 -04:00
};
2024-06-26 19:06:10 -04:00
export default ProgressUpload;