import React, { useCallback, useState } from "react";
import { DAOForm, MembersForm } from "@dorgtech/daocreator-lib";
import { useDropzone } from "react-dropzone";
import {
MDBIcon,
MDBModal,
MDBModalHeader,
MDBModalBody,
MDBModalFooter,
MDBCol,
MDBContainer,
MDBRow
} from "mdbreact";
import './styles.css';
interface ImportError {
file: string;
message: string;
}
interface Props {
title: string;
form: DAOForm;
reviewStep: any;
setTitle: any;
}
function Dropzone(props: any) {
const { isMembersImport, fileAdded, onFilePicked } = props;
const onDrop = useCallback(
acceptedFiles => {
onFilePicked(acceptedFiles, isMembersImport);
},
[isMembersImport, onFilePicked]
);
const MembersDropzone = () => (
<>
Make sure your CSV file has an address, reputation and token column
{fileAdded
? "File format accepted! Click on import button"
: "Drag & drop your CSV file here"}
>
);
const ParamsDropzone = () => (
{fileAdded
? "File format accepted! Click on import button"
: "Drag & drop your JSON file here"}
);
const { getRootProps, getInputProps } = useDropzone({ onDrop });
return (
);
}
export function ImporterModal(props: Props) {
const { title, form, reviewStep, setTitle } = props;
const open = title ? true : false;
const [error, setError] = useState();
const [fileAdded, setFileAdded] = useState(false);
const isMembersImport = title === "Import CSV";
const handleParamsImport = async (acceptedFiles: File[]) => {
if (acceptedFiles === null) {
return;
}
const files = Array.from(acceptedFiles);
if (files.length === 0) {
return;
}
const file: File = files[0];
try {
await form.fromMigrationParamsFile(file);
await form.validate();
} catch (e) {
onError(file.name, e.message);
return;
}
setFileAdded(true);
};
const handleMembersImport = async (files: File[]) => {
const memberForm = form.$.members;
const formClone = new MembersForm(memberForm.getDAOTokenSymbol);
formClone.$ = [...memberForm.$];
for (const file of files) {
const importedMembers = new MembersForm(memberForm.getDAOTokenSymbol);
try {
await importedMembers.fromCSV(file);
} catch (e) {
onError(file.name, e.message);
return;
}
// Try adding these members to the full list
formClone.$ = [...formClone.$, ...importedMembers.$];
await formClone.validate();
if (formClone.hasError && formClone.error) {
onError(file.name, formClone.error);
return;
}
}
memberForm.$ = [...formClone.$];
onClose();
};
const onFilePicked = async (
acceptedFiles: File[],
isMembersImport: boolean
) => {
if (isMembersImport) {
handleMembersImport(acceptedFiles);
} else {
handleParamsImport(acceptedFiles);
}
};
const onImport = (isMembersImport: boolean) => {
if (!error && fileAdded) {
if (!isMembersImport) reviewStep(3);
onClose();
}
};
const onError = (file: string, message: string) => {
setError({
file,
message
});
};
const ImportErrors = (props: { error: ImportError }) => (
<>
We encountered an issue during the import process:
{props.error.file}: {props.error.message}
>
);
const onClose = () => {
setTitle("");
setError(null);
setFileAdded(false);
};
return (
{" "}
{title}
{error ? (
) : (
)}
);
}
const styles = {
titlePadding: {
padding: "26px"
},
bold: {
fontWeight: 700,
fontSize: "18px"
},
cancelButton: {
backgroundColor: "white",
color: "darkgrey",
fontSize: "smaller",
fontWeight: 700,
borderRadius: "0.37rem",
height: "45px",
width: "110px",
marginRight: "243px"
},
importButton: {
backgroundColor: "#1976d2",
color: "white",
fontSize: "smaller",
fontWeight: 300,
borderRadius: "0.37rem",
height: "45px",
width: "145px"
},
dropzoneContainer: {
height: "150px",
top: "0",
left: "0"
},
paramsDropzoneInput: {
width: "90%",
height: "50%",
top: "25%",
margin: "0 auto",
position: "relative",
borderStyle: "dotted",
borderWidth: "1px",
textAlign: "center",
fontWeight: 300,
borderColor: "lightgray"
},
memberDropzoneInput: {
width: "90%",
height: "50%",
top: "13%",
margin: "0 auto",
position: "relative",
borderStyle: "dotted",
borderWidth: "1px",
textAlign: "center",
fontWeight: 300,
borderColor: "lightgray"
},
memberWarning: {
fontSize: "14px",
borderColor: "lightgray",
marginLeft: "10px",
marginTop: "13px"
}
};