import { observer } from "mobx-react"; import { NewDocumentIcon } from "outline-icons"; import * as React from "react"; import Dropzone from "react-dropzone"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import styled from "styled-components"; import { s } from "@shared/styles"; import { AttachmentPreset } from "@shared/types"; import Flex from "~/components/Flex"; import LoadingIndicator from "~/components/LoadingIndicator"; import useStores from "~/hooks/useStores"; import { uploadFile } from "~/utils/files"; type Props = { children: JSX.Element; format?: string; disabled?: boolean; activeClassName?: string; onSubmit: () => void; }; function DropToImport({ disabled, onSubmit, children, format }: Props) { const { t } = useTranslation(); const { collections } = useStores(); const [isImporting, setImporting] = React.useState(false); const handleFiles = React.useCallback( async (files) => { if (files.length > 1) { toast.error(t("Please choose a single file to import")); return; } const file = files[0]; setImporting(true); try { const attachment = await uploadFile(file, { name: file.name, preset: AttachmentPreset.Import, }); await collections.import(attachment.id, format); onSubmit(); toast.success( t("Your import is being processed, you can safely leave this page") ); } catch (err) { toast.error(err.message); } finally { setImporting(false); } }, [t, onSubmit, collections, format] ); const handleRejection = React.useCallback(() => { toast.error(t("File not supported – please upload a valid ZIP file")); }, [t]); if (disabled) { return children; } return ( <> {isImporting && } {({ getRootProps, getInputProps, isDragActive }) => ( {children} )} ); } const Icon = styled(NewDocumentIcon)` padding: 4px; border-radius: 50%; background: ${(props) => props.theme.brand.blue}; color: white; `; const DropzoneContainer = styled.div<{ $disabled: boolean; $isDragActive: boolean; }>` background: ${(props) => props.$isDragActive ? props.theme.secondaryBackground : props.theme.background}; border-radius: 8px; border: 1px dashed ${s("divider")}; padding: 52px; text-align: center; font-size: 15px; cursor: var(--pointer); opacity: ${(props) => (props.$disabled ? 0.5 : 1)}; &:hover { background: ${s("secondaryBackground")}; } `; export default observer(DropToImport);