xinnni's picture
Upload 146 files
f909d7c verified
raw
history blame
3.34 kB
import React from "react";
import { Modal, Group, Button, TextInput, Stack, Divider, ModalProps } from "@mantine/core";
import styled from "styled-components";
import toast from "react-hot-toast";
import { AiOutlineUpload } from "react-icons/ai";
import useFile from "src/store/useFile";
const StyledUploadWrapper = styled.label`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: ${({ theme }) => theme.GRID_BG_COLOR};
border: 2px dashed ${({ theme }) => theme.BACKGROUND_TERTIARY};
border-radius: 5px;
min-height: 200px;
padding: 16px;
cursor: pointer;
input[type="file"] {
display: none;
}
`;
const StyledFileName = styled.span`
padding-top: 14px;
color: ${({ theme }) => theme.INTERACTIVE_NORMAL};
`;
const StyledUploadMessage = styled.h3`
color: ${({ theme }) => theme.INTERACTIVE_ACTIVE};
margin-bottom: 0;
`;
export const ImportModal: React.FC<ModalProps> = ({ opened, onClose }) => {
const setContents = useFile(state => state.setContents);
const [url, setURL] = React.useState("");
const [jsonFile, setJsonFile] = React.useState<File | null>(null);
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files) setJsonFile(e.target.files?.item(0));
};
const handleFileDrag = (e: React.DragEvent<HTMLLabelElement>) => {
e.preventDefault();
if (e.type === "drop" && e.dataTransfer.files.length) {
if (e.dataTransfer.files[0].type === "application/json") {
setJsonFile(e.dataTransfer.files[0]);
} else {
toast.error("Please upload JSON file!");
}
}
};
const handleImportFile = () => {
if (url) {
setJsonFile(null);
toast.loading("Loading...", { id: "toastFetch" });
return fetch(url)
.then(res => res.json())
.then(json => {
setContents({ contents: JSON.stringify(json, null, 2) });
onClose();
})
.catch(() => toast.error("Failed to fetch JSON!"))
.finally(() => toast.dismiss("toastFetch"));
}
if (jsonFile) {
const reader = new FileReader();
reader.readAsText(jsonFile, "UTF-8");
reader.onload = function (data) {
if (typeof data.target?.result === "string") setContents({ contents: data.target?.result });
onClose();
};
}
};
return (
<Modal title="Import JSON" opened={opened} onClose={onClose} centered>
<Stack py="sm">
<TextInput
value={url}
onChange={e => setURL(e.target.value)}
type="url"
placeholder="URL of JSON to fetch"
data-autofocus
/>
<StyledUploadWrapper onDrop={handleFileDrag} onDragOver={handleFileDrag}>
<input
key={jsonFile?.name}
onChange={handleFileChange}
type="file"
accept="application/JSON"
/>
<AiOutlineUpload size={48} />
<StyledUploadMessage>Click Here to Upload JSON</StyledUploadMessage>
<StyledFileName>{jsonFile?.name ?? "None"}</StyledFileName>
</StyledUploadWrapper>
</Stack>
<Divider my="xs" />
<Group justify="right">
<Button onClick={handleImportFile} disabled={!(jsonFile || url)}>
Import
</Button>
</Group>
</Modal>
);
};