108 lines
3.6 KiB
TypeScript
108 lines
3.6 KiB
TypeScript
import { Box, Button } from "@mui/material";
|
||
import { editSightStore, SelectMediaDialog, UploadMediaDialog } from "@shared";
|
||
import { Upload } from "lucide-react";
|
||
import { observer } from "mobx-react-lite";
|
||
import { useState, DragEvent, useRef } from "react";
|
||
|
||
export const MediaAreaForSight = observer(
|
||
({
|
||
onFilesDrop, // 👈 Проп для обработки загруженных файлов
|
||
onFinishUpload,
|
||
}: {
|
||
onFilesDrop?: (files: File[]) => void;
|
||
onFinishUpload?: (mediaId: string) => void;
|
||
}) => {
|
||
const [selectMediaDialogOpen, setSelectMediaDialogOpen] = useState(false);
|
||
const [uploadMediaDialogOpen, setUploadMediaDialogOpen] = useState(false);
|
||
const [isDragging, setIsDragging] = useState(false);
|
||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||
const { setFileToUpload } = editSightStore;
|
||
|
||
const handleDrop = (e: DragEvent<HTMLDivElement>) => {
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
setIsDragging(false);
|
||
|
||
const files = Array.from(e.dataTransfer.files);
|
||
if (files.length && onFilesDrop) {
|
||
setFileToUpload(files[0]);
|
||
}
|
||
|
||
setUploadMediaDialogOpen(true);
|
||
};
|
||
|
||
const handleDragOver = (e: DragEvent<HTMLDivElement>) => {
|
||
e.preventDefault();
|
||
setIsDragging(true);
|
||
};
|
||
|
||
const handleDragLeave = () => {
|
||
setIsDragging(false);
|
||
};
|
||
|
||
const handleClick = () => {
|
||
fileInputRef.current?.click();
|
||
};
|
||
|
||
const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||
const files = Array.from(event.target.files || []);
|
||
if (files.length && onFilesDrop) {
|
||
setFileToUpload(files[0]);
|
||
onFilesDrop(files);
|
||
setUploadMediaDialogOpen(true);
|
||
}
|
||
|
||
// Сбрасываем значение input, чтобы можно было выбрать тот же файл снова
|
||
event.target.value = "";
|
||
};
|
||
|
||
return (
|
||
<>
|
||
<input
|
||
type="file"
|
||
ref={fileInputRef}
|
||
onChange={handleFileSelect}
|
||
accept="image/*,video/*,.glb,.gltf"
|
||
multiple
|
||
style={{ display: "none" }}
|
||
/>
|
||
<Box className="w-full flex flex-col items-center justify-center border rounded-md p-4">
|
||
<div className="w-full flex flex-col items-center justify-center">
|
||
<div
|
||
className={`w-full h-40 flex text-center flex-col justify-center items-center text-gray-400 border-dashed border-2 rounded-md border-gray-400 p-4 cursor-pointer hover:bg-gray-50 ${
|
||
isDragging ? "bg-blue-100 border-blue-400" : ""
|
||
}`}
|
||
onDrop={handleDrop}
|
||
onDragOver={handleDragOver}
|
||
onDragLeave={handleDragLeave}
|
||
onClick={handleClick}
|
||
>
|
||
<Upload size={32} className="mb-2" />
|
||
Перетащите медиа файлы сюда или нажмите для выбора
|
||
</div>
|
||
<div>или</div>
|
||
<Button
|
||
variant="contained"
|
||
color="primary"
|
||
onClick={() => setSelectMediaDialogOpen(true)}
|
||
>
|
||
Выбрать существующие медиа файлы
|
||
</Button>
|
||
</div>
|
||
</Box>
|
||
|
||
<UploadMediaDialog
|
||
open={uploadMediaDialogOpen}
|
||
onClose={() => setUploadMediaDialogOpen(false)}
|
||
afterUploadSight={onFinishUpload}
|
||
/>
|
||
<SelectMediaDialog
|
||
open={selectMediaDialogOpen}
|
||
onClose={() => setSelectMediaDialogOpen(false)}
|
||
onSelectForSightMedia={onFinishUpload}
|
||
/>
|
||
</>
|
||
);
|
||
}
|
||
);
|