141 lines
4.6 KiB
JavaScript
141 lines
4.6 KiB
JavaScript
import { useEffect, useRef, useState } from "react";
|
|
import FilledButton from "../../md-components/FilledButton";
|
|
import Icon from "../../md-components/Icon";
|
|
import IconButton from "../../md-components/IconButton";
|
|
import axios from "axios";
|
|
import { toast } from "react-toastify";
|
|
|
|
function UploadBook() {
|
|
const fileSelectorRef = useRef();
|
|
const [uploadedFiles, setUploadedFiles] = useState([]);
|
|
const [uploadStatuses, setUploadStatuses] = useState([]);
|
|
const [isDragging, setIsDragging] = useState(false);
|
|
const [uploading, setUploading] = useState(false);
|
|
|
|
const handleFileChange = (e) => {
|
|
const files = Array.from(e.target.files);
|
|
setUploadedFiles((prev) => [...prev, ...files]);
|
|
};
|
|
|
|
const handleDrop = (e) => {
|
|
e.preventDefault();
|
|
setIsDragging(false);
|
|
const droppedFiles = Array.from(e.dataTransfer.files);
|
|
setUploadedFiles((prev) => [...prev, ...droppedFiles]);
|
|
};
|
|
|
|
const handleDragOver = (e) => {
|
|
e.preventDefault();
|
|
setIsDragging(true);
|
|
};
|
|
|
|
const handleDragLeave = () => {
|
|
setIsDragging(false);
|
|
};
|
|
useEffect(
|
|
() => setUploadStatuses(uploadedFiles.map(() => 0)),
|
|
[uploadedFiles]
|
|
);
|
|
|
|
const handleUpload = async () => {
|
|
setUploading(true);
|
|
console.log(uploading);
|
|
if (uploadedFiles.length === 0) {
|
|
alert("Нечего грузить, капитан.");
|
|
return;
|
|
}
|
|
|
|
for (const [i, file] of uploadedFiles.entries()) {
|
|
const formData = new FormData();
|
|
formData.append("files", file);
|
|
try {
|
|
console.log(uploadedFiles);
|
|
const res = await axios.post("/book/upload", formData);
|
|
console.log(res);
|
|
if (res.status === 200) {
|
|
// toast("Залили! 🧃");
|
|
setUploadStatuses((prev) => ({ ...prev, [i]: 1 }));
|
|
console.log(uploadStatuses);
|
|
} else {
|
|
toast("Ошибка на сервере, go дебажить.");
|
|
}
|
|
} catch (err) {
|
|
console.error("Ошибка:", err);
|
|
toast("Шатался интернет или сервер умер.");
|
|
}
|
|
}
|
|
|
|
setUploading(false);
|
|
setUploadedFiles([]);
|
|
};
|
|
if (!window.onLine) {
|
|
return <span>Недоступно оффлайн</span>;
|
|
}
|
|
return (
|
|
<div className="flex flex-col items-center justify-center h-screen">
|
|
<h1 className="text-2xl font-bold mb-4">Загрузка литературы</h1>
|
|
|
|
<div
|
|
className={`flex items-center justify-around w-full max-w-lg h-50 mb-4 rounded-xl flex-col gap-1 px-4 border-2 border-dashed transition-colors duration-200 cursor-pointer border-(--md-sys-color-outline) ${
|
|
isDragging
|
|
? "bg-(--md-sys-color-surface-variant)"
|
|
: "bg-(--md-sys-color-inverse-on-surface)"
|
|
}`}
|
|
onClick={() => fileSelectorRef.current.click()}
|
|
onDrop={handleDrop}
|
|
onDragOver={handleDragOver}
|
|
onDragLeave={handleDragLeave}
|
|
>
|
|
<>
|
|
<span className="font-bold">Перетащи файл сюда или кликни</span>
|
|
<IconButton className="w-24 h-24">
|
|
<Icon className="text-6xl w-24 h-24">upload_file</Icon>
|
|
</IconButton>
|
|
<span className="text-sm">Поддерживается .fb2 и .pdf</span>
|
|
</>
|
|
<input
|
|
type="file"
|
|
multiple
|
|
accept=".fb2,.pdf"
|
|
ref={fileSelectorRef}
|
|
className="hidden"
|
|
onChange={handleFileChange}
|
|
/>
|
|
</div>
|
|
<div className="w-full max-w-lg bg-(--md-sys-color-surface-variant) flex p-[18px] rounded-2xl flex-col max-h-60 overflow-scroll gap-3 mb-4">
|
|
{uploadedFiles.length === 0 ? <span>Нечего загружать</span> : <></>}
|
|
{uploadedFiles.map((file, i) => (
|
|
<div className="flex justify-between" key={i}>
|
|
<span className="truncate w-[calc(100%-42px)] inline-block">
|
|
{file.name}
|
|
</span>
|
|
{uploading ? (
|
|
<Icon className="text-(--md-sys-color-on-surface)">
|
|
{uploadStatuses[i] === 0
|
|
? "sync"
|
|
: uploadStatuses[i] === -1
|
|
? "error"
|
|
: "check_circle"}
|
|
</Icon>
|
|
) : (
|
|
<IconButton
|
|
onClick={() =>
|
|
setUploadedFiles((prev) => prev.filter((_, io) => io !== i))
|
|
}
|
|
>
|
|
<Icon>remove</Icon>
|
|
</IconButton>
|
|
)}
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<FilledButton onClick={handleUpload} disabled={uploading}>
|
|
Загрузить
|
|
</FilledButton>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default UploadBook;
|