import styled from "@emotion/styled"; import { BookOpen, FileUp } from "lucide-react"; import { type DragEvent, useRef, useState } from "react"; export function UploadFileDialog(properties: { onClose: () => void; onModelUpload: (blob: ArrayBuffer, fileName: string) => Promise; }) { const [hover, setHover] = useState(false); const [message, setMessage] = useState(""); const fileInputRef = useRef(null); const { onModelUpload } = properties; const handleClose = () => { properties.onClose(); }; const handleDragEnter = (event: DragEvent) => { event.preventDefault(); event.stopPropagation(); setHover(true); }; const handleDragOver = (event: DragEvent) => { event.preventDefault(); event.stopPropagation(); event.dataTransfer.dropEffect = "copy"; setHover(true); }; const handleDragLeave = (event: DragEvent) => { event.preventDefault(); event.stopPropagation(); setHover(false); }; const handleDrop = (event: DragEvent) => { event.preventDefault(); event.stopPropagation(); const dt = event.dataTransfer; const items = dt.items; if (items) { // Use DataTransferItemList to access the file(s) for (let i = 0; i < items.length; i++) { // If dropped items aren't files, skip them if (items[i].kind === "file") { const file = items[i].getAsFile(); if (file) { handleFileUpload(file); return; } } } } else { const files = dt.files; if (files.length > 0) { handleFileUpload(files[0]); } } }; const handleFileUpload = (file: File) => { setMessage(`Uploading ${file.name}...`); // Read the file as ArrayBuffer const reader = new FileReader(); reader.onload = async () => { try { await onModelUpload(reader.result as ArrayBuffer, file.name); handleClose(); } catch (e) { console.log("error", e); setMessage(`${e}`); } }; reader.readAsArrayBuffer(file); }; const root = document.getElementById("root"); if (root) { root.style.filter = "blur(4px)"; } return ( Import an .xlsx file {}} > Close {message === "" ? ( {!hover ? ( <>
Drag and drop a file here or{" "} { const files = event.target.files; if (files) { for (const file of files) { handleFileUpload(file); } } }} /> { if (fileInputRef.current) { fileInputRef.current.click(); } }} > click to browse
) : ( <>
Drop file here
)} ) : ( <>
{message}
)} Learn more about importing files into IronCalc ); } const Cross = styled("div")` &:hover { background-color: #f5f5f5; } display: flex; border-radius: 4px; height: 24px; width: 24px; cursor: pointer; align-items: center; justify-content: center; `; const DocLink = styled("span")` color: #f2994a; text-decoration: none; &:hover { text-decoration: underline; } `; const UploadFooter = styled("div")` height: 44px; border-top: 1px solid #e0e0e0; color: #757575; display: flex; align-items: center; `; const UploadFooterLink = styled("a")` font-size: 12px; font-weight: 400; color: #757575; text-decoration: none; &:hover { text-decoration: underline; } `; const UploadTitle = styled("div")` display: flex; align-items: center; border-bottom: 1px solid #e0e0e0; height: 44px; font-size: 14px; font-weight: 500; `; const UploadDialog = styled("div")` display: flex; flex-direction: column; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 460px; max-width: 90%; height: 285px; background: #fff; border: 1px solid #e0e0e0; border-radius: 8px; box-shadow: 0px 1px 3px 0px #0000001a; font-family: Inter; `; const DropZone = styled("div")` &:hover { border: 1px dashed #f2994a; transition: 0.2s ease-in-out; gap: 8px; background: linear-gradient( 180deg, rgba(242, 153, 74, 0.12) 0%, rgba(242, 153, 74, 0) 100% ); } flex-grow: 2; border-radius: 10px; text-align: center; margin: 12px; color: #aaa; font-family: Arial, sans-serif; cursor: pointer; background-color: #faebd7; border: 1px dashed #efaa6d; background: linear-gradient( 180deg, rgba(242, 153, 74, 0.08) 0%, rgba(242, 153, 74, 0) 100% ); display: flex; flex-direction: column; vertical-align: center; gap: 16px; transition: 0.2s ease-in-out; `;