frontAnswerer/lib/components/ViewPublicationPage/questions/Images/OwnImage.tsx

165 lines
4.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Box, ButtonBase, IconButton, Typography, useTheme } from "@mui/material";
import { useState, useRef, useEffect } from "react";
import CloseIcon from "@mui/icons-material/Close";
type OwnImageProps = {
imageUrl?: string;
};
export const OwnImage = ({ imageUrl }: OwnImageProps) => {
const theme = useTheme();
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const [isDropzoneHighlighted, setIsDropzoneHighlighted] = useState(false);
const fileInputRef = useRef<HTMLInputElement>(null);
// Sync state if external imageUrl changes
useEffect(() => {
if (imageUrl) {
setSelectedFile(null); // Clear local file selection when external URL is provided
}
}, [imageUrl]);
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (file && file.type.startsWith("image/")) {
setSelectedFile(file);
}
};
const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
event.stopPropagation();
setIsDropzoneHighlighted(false);
const file = event.dataTransfer.files?.[0];
if (file && file.type.startsWith("image/")) {
setSelectedFile(file);
}
};
const handleDragOver = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
event.stopPropagation();
};
const handleDragEnter = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
event.stopPropagation();
setIsDropzoneHighlighted(true);
};
const handleDragLeave = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
event.stopPropagation();
setIsDropzoneHighlighted(false);
};
const handleClick = (e: React.MouseEvent) => {
e.stopPropagation();
if (fileInputRef.current) {
fileInputRef.current.value = "";
}
fileInputRef.current?.click();
};
const handleRemoveImage = (e: React.MouseEvent) => {
e.stopPropagation();
setSelectedFile(null);
};
const imageToDisplay = selectedFile ? URL.createObjectURL(selectedFile) : imageUrl;
return (
<ButtonBase
component="div"
onClick={handleClick}
onDrop={handleDrop}
onDragOver={handleDragOver}
onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave}
sx={{
width: "100%",
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
borderRadius: "12px",
transition: "border-color 0.3s, background-color 0.3s",
overflow: "hidden",
position: "relative",
"&:hover .overlay": {
opacity: 1,
},
}}
>
<input
type="file"
ref={fileInputRef}
onChange={handleFileChange}
accept="image/*"
hidden
/>
{imageToDisplay ? (
<>
<Box sx={{ width: "100%", height: "100%", position: "relative" }}>
<img
src={imageToDisplay}
alt="Preview"
style={{ width: "100%", height: "100%", objectFit: "cover" }}
/>
</Box>
<Box
className="overlay"
sx={{
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%",
backgroundColor: "rgba(0, 0, 0, 0.4)",
opacity: 0,
transition: "opacity 0.3s",
pointerEvents: "none",
}}
/>
{selectedFile && (
<IconButton
onClick={handleRemoveImage}
sx={{
position: "absolute",
top: 8,
right: 8,
zIndex: 1,
backgroundColor: "rgba(0, 0, 0, 0.5)",
color: "white",
"&:hover": {
backgroundColor: "rgba(0, 0, 0, 0.7)",
},
}}
>
<CloseIcon />
</IconButton>
)}
</>
) : (
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
opacity: 0.5,
}}
>
<Typography
variant="body2"
color="text.secondary"
sx={{ p: 2, textAlign: "center" }}
>
добавьте свою картинку
</Typography>
</Box>
)}
</ButtonBase>
);
};