feat: Improving page loading

This commit is contained in:
2025-11-20 20:17:52 +03:00
parent 6f32c6e671
commit 85c71563c1
17 changed files with 545 additions and 273 deletions

View File

@@ -11,52 +11,72 @@ import { observer } from "mobx-react-lite";
import { useState, DragEvent, useRef } from "react";
import { toast } from "react-toastify";
type ContextType =
| "sight"
| "city"
| "carrier"
| "country"
| "vehicle"
| "station";
interface MediaAreaForSightProps {
onFilesDrop?: (files: File[]) => void;
onFinishUpload?: (mediaId: string) => void;
contextObjectName?: string;
contextType?: ContextType;
isArticle?: boolean;
articleName?: string;
}
export const MediaAreaForSight = observer(
({
onFilesDrop, // 👈 Проп для обработки загруженных файлов
onFilesDrop,
onFinishUpload,
contextObjectName,
contextType,
isArticle,
articleName,
}: {
onFilesDrop?: (files: File[]) => void;
onFinishUpload?: (mediaId: string) => void;
contextObjectName?: string;
contextType?:
| "sight"
| "city"
| "carrier"
| "country"
| "vehicle"
| "station";
isArticle?: boolean;
articleName?: string;
}) => {
const [selectMediaDialogOpen, setSelectMediaDialogOpen] = useState(false);
const [uploadMediaDialogOpen, setUploadMediaDialogOpen] = useState(false);
const [isDragging, setIsDragging] = useState(false);
}: MediaAreaForSightProps) => {
const [selectMediaDialogOpen, setSelectMediaDialogOpen] =
useState<boolean>(false);
const [uploadMediaDialogOpen, setUploadMediaDialogOpen] =
useState<boolean>(false);
const [isDragging, setIsDragging] = useState<boolean>(false);
const fileInputRef = useRef<HTMLInputElement>(null);
const { setFileToUpload } = editSightStore;
const processFiles = (files: File[]) => {
if (!files.length) {
return;
}
const { validFiles, errors } = filterValidFiles(files);
if (errors.length > 0) {
errors.forEach((error: string) => toast.error(error));
}
if (validFiles.length > 0) {
// Сохраняем первый файл для загрузки
setFileToUpload(validFiles[0]);
// Вызываем колбэк, если он передан
if (onFilesDrop) {
onFilesDrop(validFiles);
}
// Открываем диалог загрузки
setUploadMediaDialogOpen(true);
}
};
const handleDrop = (e: DragEvent<HTMLDivElement>) => {
e.preventDefault();
e.stopPropagation();
setIsDragging(false);
const files = Array.from(e.dataTransfer.files);
if (files.length) {
const { validFiles, errors } = filterValidFiles(files);
if (errors.length > 0) {
errors.forEach((error: string) => toast.error(error));
}
if (validFiles.length > 0 && onFilesDrop) {
setFileToUpload(validFiles[0]);
setUploadMediaDialogOpen(true);
}
}
processFiles(files);
};
const handleDragOver = (e: DragEvent<HTMLDivElement>) => {
@@ -74,22 +94,12 @@ export const MediaAreaForSight = observer(
const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
const files = Array.from(event.target.files || []);
if (files.length) {
const { validFiles, errors } = filterValidFiles(files);
if (errors.length > 0) {
errors.forEach((error: string) => toast.error(error));
}
if (validFiles.length > 0 && onFilesDrop) {
setFileToUpload(validFiles[0]);
onFilesDrop(validFiles);
setUploadMediaDialogOpen(true);
}
}
processFiles(files);
// Сбрасываем значение input, чтобы можно было выбрать тот же файл снова
event.target.value = "";
if (event.target) {
event.target.value = "";
}
};
return (
@@ -105,7 +115,7 @@ export const MediaAreaForSight = observer(
<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 ${
className={`w-full h-40 flex 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 transition-colors ${
isDragging ? "bg-blue-100 border-blue-400" : ""
}`}
onDrop={handleDrop}
@@ -114,9 +124,11 @@ export const MediaAreaForSight = observer(
onClick={handleClick}
>
<Upload size={32} className="mb-2" />
Перетащите медиа файлы сюда или нажмите для выбора
<span className="text-center">
Перетащите медиа файлы сюда или нажмите для выбора
</span>
</div>
<div>или</div>
<div className="my-2">или</div>
<Button
variant="contained"
color="primary"