123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- import React from "react";
- import styled from "styled-components";
- import toast from "react-hot-toast";
- import { useConfig } from "src/hocs/config";
- import { ConfigActionType } from "src/reducer/reducer";
- import { Modal } from "src/components/Modal";
- import { Button } from "src/components/Button";
- import { AiOutlineUpload } from "react-icons/ai";
- const StyledInput = styled.input`
- background: ${({ theme }) => theme.BACKGROUND_TERTIARY};
- color: ${({ theme }) => theme.INTERACTIVE_NORMAL};
- outline: none;
- border: none;
- border-radius: 5px;
- padding: 6px 8px;
- width: 100%;
- margin-bottom: 10px;
- `;
- const StyledModalContent = styled(Modal.Content)`
- display: flex;
- justify-content: center;
- align-items: center;
- flex-direction: column;
- `;
- const StyledUploadWrapper = styled.label`
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- background: ${({ theme }) => theme.BACKGROUND_SECONDARY};
- border: 2px dashed ${({ theme }) => theme.BACKGROUND_TERTIARY};
- border-radius: 5px;
- width: 100%;
- padding: 16px;
- cursor: pointer;
- input[type="file"] {
- display: none;
- }
- `;
- const StyledFileName = styled.span`
- color: ${({ theme }) => theme.INTERACTIVE_NORMAL};
- `;
- const StyledUploadMessage = styled.h3`
- color: ${({ theme }) => theme.INTERACTIVE_ACTIVE};
- margin-bottom: 0;
- `;
- export const ImportModal = ({ visible, setVisible }) => {
- const { dispatch } = useConfig();
- 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 handleImportFile = () => {
- if (url) {
- setJsonFile(null);
- const toastId = toast.loading("Loading...");
- return fetch(url)
- .then((res) => res.json())
- .then((json) => {
- dispatch({
- type: ConfigActionType.SET_JSON,
- payload: JSON.stringify(json),
- });
- toast.dismiss(toastId);
- setVisible(false);
- })
- .catch(() => toast.error("Failed to fetch JSON!"));
- }
- if (jsonFile) {
- const reader = new FileReader();
- reader.readAsText(jsonFile, "UTF-8");
- reader.onload = function (data) {
- dispatch({
- type: ConfigActionType.SET_JSON,
- payload: data.target?.result as string,
- });
- setVisible(false);
- };
- }
- };
- React.useEffect(() => {
- return () => {
- setJsonFile(null);
- setURL("");
- };
- }, [visible]);
- return (
- <Modal visible={visible} setVisible={setVisible}>
- <Modal.Header>Select An Import Method</Modal.Header>
- <StyledModalContent>
- <StyledInput
- value={url}
- onChange={(e) => setURL(e.target.value)}
- type="url"
- placeholder="URL of JSON to fetch"
- />
- <StyledUploadWrapper>
- <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>
- </StyledModalContent>
- <Modal.Controls setVisible={setVisible}>
- <Button
- status="SECONDARY"
- onClick={handleImportFile}
- disabled={!(jsonFile || url)}
- >
- Import
- </Button>
- </Modal.Controls>
- </Modal>
- );
- };
|