Files
WhiteNightsAdminPanel/src/widgets/ImageUploadCard/index.tsx
2025-11-06 00:58:10 +03:00

189 lines
5.3 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 React, { useRef, DragEvent } from "react";
import { Paper, Box, Typography, Button, Tooltip } from "@mui/material";
import { X, Info, Plus } from "lucide-react";
import { editSightStore } from "@shared";
import { toast } from "react-toastify";
interface ImageUploadCardProps {
title: string;
imageKey?: "thumbnail" | "watermark_lu" | "watermark_rd" | "image";
imageUrl: string | null | undefined;
onImageClick: () => void;
onDeleteImageClick: () => void;
onSelectFileClick: () => void;
setUploadMediaOpen: (open: boolean) => void;
tooltipText?: string;
setHardcodeType?: (type: string) => void;
}
export const ImageUploadCard: React.FC<ImageUploadCardProps> = ({
title,
imageKey,
imageUrl,
onImageClick,
onDeleteImageClick,
onSelectFileClick,
setUploadMediaOpen,
setHardcodeType,
tooltipText,
}) => {
const fileInputRef = useRef<HTMLInputElement>(null);
const { setFileToUpload } = editSightStore;
const handleZoneClick = () => {
fileInputRef.current?.click();
};
const handleFileInputChange = async (
event: React.ChangeEvent<HTMLInputElement>
) => {
const file = event.target.files?.[0];
if (file) {
if (file.type.startsWith("image/") && file.type !== "image/gif") {
setFileToUpload(file);
setUploadMediaOpen(true);
if (imageKey && setHardcodeType) {
setHardcodeType(imageKey);
}
} else if (file.type === "image/gif") {
toast.error("GIF файлы не поддерживаются");
} else {
toast.error("Пожалуйста, выберите изображение");
}
}
event.target.value = "";
};
const token = localStorage.getItem("token");
const handleDragOver = (event: DragEvent<HTMLDivElement>) => {
event.preventDefault();
event.stopPropagation();
};
const handleDragLeave = (event: DragEvent<HTMLDivElement>) => {
event.preventDefault();
event.stopPropagation();
};
const handleDrop = async (event: DragEvent<HTMLDivElement>) => {
event.preventDefault();
event.stopPropagation();
const files = event.dataTransfer.files;
if (files && files.length > 0) {
const file = files[0];
if (file.type.startsWith("image/") && file.type !== "image/gif") {
setFileToUpload(file);
setUploadMediaOpen(true);
} else if (file.type === "image/gif") {
toast.error("GIF файлы не поддерживаются");
} else {
toast.error("Пожалуйста, выберите изображение");
}
}
};
return (
<Paper
elevation={2}
sx={{
padding: 2,
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: 1,
flex: 1,
minWidth: 150,
}}
>
<Box sx={{ display: "flex", alignItems: "center" }}>
<Typography variant="subtitle2" gutterBottom sx={{ mb: 0, mr: 0.5 }}>
{title}
</Typography>
{tooltipText && (
<Tooltip title={tooltipText}>
<Info size={16} color="gray" style={{ cursor: "pointer" }} />
</Tooltip>
)}
</Box>
<Box
sx={{
position: "relative",
width: "200px",
height: "200px",
display: "flex",
alignItems: "center",
justifyContent: "center",
borderRadius: 1,
mb: 1,
cursor: imageUrl ? "pointer" : "default",
}}
onClick={onImageClick}
>
{imageUrl && (
<button
className="absolute top-2 right-2"
onClick={(e) => {
e.stopPropagation();
onDeleteImageClick();
}}
>
<X color="red" />
</button>
)}
{imageUrl ? (
<img
src={`${
import.meta.env.VITE_KRBL_MEDIA
}${imageUrl}/download?token=${token}`}
alt={title}
style={{ maxWidth: "100%", maxHeight: "100%" }}
onClick={onImageClick}
/>
) : (
<div
className={`w-full flex flex-col items-center justify-center gap-3 `}
>
<div
className="flex flex-col p-5 items-center justify-center gap-3"
style={{
border: "2px dashed #ccc",
borderRadius: 1,
cursor: "pointer",
}}
onClick={handleZoneClick}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={handleDrop}
>
<p>Перетащите файл</p>
</div>
<p>или</p>
<Button
variant="contained"
color="primary"
startIcon={<Plus color="white" size={18} />}
onClick={(e) => {
e.stopPropagation();
onSelectFileClick();
}}
>
Выбрать файл
</Button>
{/* Hidden file input */}
<input
type="file"
ref={fileInputRef}
onChange={handleFileInputChange}
style={{ display: "none" }}
accept="image/*"
/>
</div>
)}
</Box>
</Paper>
);
};