Files
Checkmate/Client/src/Components/Inputs/Image/index.jsx
T

147 lines
4.4 KiB
React
Raw Normal View History

2024-07-05 18:48:32 -04:00
import React, { useState } from "react";
2024-06-26 19:12:50 -04:00
import PropTypes from "prop-types";
2024-06-25 17:38:40 -04:00
import { Box, IconButton, Stack, TextField, Typography } from "@mui/material";
import { useTheme } from "@emotion/react";
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
import "./index.css";
import { checkImage } from "../../../Utils/fileUtils";
2024-06-25 17:38:40 -04:00
/**
* @param {Object} props - The component props.
2024-06-26 19:12:50 -04:00
* @param {string} props.id - The unique identifier for the input field.
2024-07-05 14:43:29 -04:00
* @param {string} props.src - The URL of the image to display.
2024-06-26 19:12:50 -04:00
* @param {function} props.onChange - The function to handle file input change.
2024-06-25 17:38:40 -04:00
* @returns {JSX.Element} The rendered component.
*/
2024-06-26 19:12:50 -04:00
2024-07-05 18:48:32 -04:00
const ImageField = ({ id, src, loading, onChange }) => {
2024-06-25 17:38:40 -04:00
const theme = useTheme();
const [isDragging, setIsDragging] = useState(false);
const handleDragEnter = () => {
setIsDragging(true);
};
const handleDragLeave = () => {
setIsDragging(false);
};
return (
2024-07-05 18:48:32 -04:00
<>
{!checkImage(src) || loading ? (
<>
<Box
className="image-field-wrapper"
2024-08-27 17:01:28 -04:00
mt={theme.spacing(8)}
2024-06-26 19:06:10 -04:00
sx={{
2024-07-05 18:48:32 -04:00
position: "relative",
height: "fit-content",
border: "dashed",
2024-08-27 17:01:28 -04:00
borderRadius: theme.shape.borderRadius,
2024-07-05 18:48:32 -04:00
borderColor: isDragging
? theme.palette.primary.main
2024-08-27 17:01:28 -04:00
: theme.palette.border.light,
2024-07-05 18:48:32 -04:00
borderWidth: "2px",
transition: "0.2s",
"&:hover": {
borderColor: theme.palette.primary.main,
2024-07-05 18:48:32 -04:00
backgroundColor: "hsl(215, 87%, 51%, 0.05)",
},
2024-06-26 19:06:10 -04:00
}}
2024-07-05 18:48:32 -04:00
onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave}
onDrop={handleDragLeave}
2024-06-26 19:06:10 -04:00
>
2024-07-05 18:48:32 -04:00
<TextField
id={id}
type="file"
onChange={onChange}
sx={{
width: "100%",
"& .MuiInputBase-input[type='file']": {
opacity: 0,
cursor: "pointer",
maxWidth: "500px",
minHeight: "175px",
},
"& fieldset": {
padding: 0,
border: "none",
},
}}
/>
<Stack
className="custom-file-text"
alignItems="center"
gap="4px"
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
zIndex: "-1",
width: "100%",
}}
>
<IconButton
sx={{
pointerEvents: "none",
2024-08-27 17:01:28 -04:00
borderRadius: theme.shape.borderRadius,
border: `solid ${theme.shape.borderThick}px ${theme.palette.border.light}`,
2024-07-05 18:48:32 -04:00
boxShadow: theme.shape.boxShadow,
}}
>
<CloudUploadIcon />
</IconButton>
2024-08-27 17:01:28 -04:00
<Typography component="h2" color={theme.palette.text.tertiary}>
<Typography
component="span"
fontSize="inherit"
color={theme.palette.primary.main}
2024-08-27 17:01:28 -04:00
fontWeight={500}
>
Click to upload
</Typography>{" "}
or drag and drop
</Typography>
<Typography
component="p"
color={theme.palette.text.tertiary}
sx={{ opacity: 0.6 }}
>
(maximum size: 3MB)
2024-07-05 18:48:32 -04:00
</Typography>
</Stack>
</Box>
2024-08-27 17:01:28 -04:00
<Typography
component="p"
color={theme.palette.text.tertiary}
sx={{ opacity: 0.6 }}
>
Supported formats: JPG, PNG
</Typography>
2024-07-05 18:48:32 -04:00
</>
) : (
2024-06-26 19:06:10 -04:00
<Stack direction="row" justifyContent="center">
<Box
sx={{
width: "250px",
height: "250px",
borderRadius: "50%",
overflow: "hidden",
2024-07-05 14:43:29 -04:00
backgroundImage: `url(${src})`,
2024-07-02 14:51:31 -04:00
backgroundSize: "cover",
2024-06-26 19:06:10 -04:00
}}
2024-07-02 14:51:31 -04:00
></Box>
2024-06-26 19:06:10 -04:00
</Stack>
)}
2024-07-05 18:48:32 -04:00
</>
2024-06-25 17:38:40 -04:00
);
2024-07-05 18:48:32 -04:00
};
2024-06-25 17:38:40 -04:00
2024-06-26 19:12:50 -04:00
ImageField.propTypes = {
id: PropTypes.string.isRequired,
2024-07-05 14:43:29 -04:00
src: PropTypes.string,
2024-06-26 19:12:50 -04:00
onChange: PropTypes.func.isRequired,
};
2024-06-25 17:38:40 -04:00
export default ImageField;