From 86ba1d6f68230e4c81b1a70ff0550cfab279fcd4 Mon Sep 17 00:00:00 2001
From: aliasaria <ali.asaria@gmail.com>
Date: Tue, 19 Mar 2024 11:48:25 -0400
Subject: [PATCH] add react drop-zone

---
 package-lock.json                             | 406 +++++-------------
 package.json                                  |   1 +
 .../components/Experiment/Documents/index.tsx | 344 ++++++++-------
 3 files changed, 310 insertions(+), 441 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index b4fe2fb7..f21481d3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,24 +24,20 @@
         "@uppy/react": "^3.1.3",
         "@uppy/status-bar": "^3.2.4",
         "@uppy/xhr-upload": "^3.3.2",
-        "basic-auth": "~2.0.1",
-        "cidr-matcher": "^2.1.1",
         "command-exists": "^1.2.9",
         "debug": "^4.3.4",
         "easy-peasy": "^6.0.2",
         "electron-debug": "^3.2.0",
-        "electron-download-manager": "^2.1.2",
         "electron-log": "^4.4.8",
         "electron-ssh2": "^0.1.2",
         "electron-store": "^8.1.0",
         "electron-updater": "^6.1.4",
-        "express": "^4.18.1",
-        "express-session": "^1.17.3",
         "lucide-react": "^0.287.0",
         "monaco-themes": "^0.4.4",
         "morgan": "~1.10.0",
         "react": "^18.2.0",
         "react-dom": "^18.2.0",
+        "react-dropzone": "^14.2.3",
         "react-icons": "^5.0.1",
         "react-markdown": "^8.0.7",
         "react-router-dom": "^6.11.2",
@@ -50,7 +46,6 @@
         "read-config-ng": "^3.0.5",
         "remark-gfm": "^3.0.1",
         "serve-favicon": "^2.5.0",
-        "socket.io": "^4.5.1",
         "swr": "^2.2.0",
         "tree-kill": "^1.2.2",
         "use-debounce": "^9.0.4",
@@ -3976,11 +3971,6 @@
         "@sinonjs/commons": "^3.0.0"
       }
     },
-    "node_modules/@socket.io/component-emitter": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
-      "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
-    },
     "node_modules/@svgr/babel-plugin-add-jsx-attribute": {
       "version": "8.0.0",
       "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
@@ -4542,19 +4532,6 @@
         "@types/node": "*"
       }
     },
-    "node_modules/@types/cookie": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
-      "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
-    },
-    "node_modules/@types/cors": {
-      "version": "2.8.15",
-      "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.15.tgz",
-      "integrity": "sha512-n91JxbNLD8eQIuXDIChAN1tCKNWCEgpceU9b7ZMbFA+P+Q4yIeh80jizFLEvolRPc1ES0VdwFlGv+kJTSirogw==",
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
     "node_modules/@types/debug": {
       "version": "4.1.9",
       "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.9.tgz",
@@ -4780,7 +4757,8 @@
     "node_modules/@types/node": {
       "version": "20.2.5",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz",
-      "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ=="
+      "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==",
+      "dev": true
     },
     "node_modules/@types/parse-json": {
       "version": "4.0.0",
@@ -5628,6 +5606,7 @@
       "version": "1.3.8",
       "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
       "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+      "dev": true,
       "dependencies": {
         "mime-types": "~2.1.34",
         "negotiator": "0.6.3"
@@ -6242,6 +6221,8 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
       "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
+      "dev": true,
+      "optional": true,
       "engines": {
         "node": ">=0.8"
       }
@@ -6317,6 +6298,14 @@
         "node": ">=10.12.0"
       }
     },
+    "node_modules/attr-accept": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz",
+      "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/available-typed-arrays": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
@@ -6575,14 +6564,6 @@
         }
       ]
     },
-    "node_modules/base64id": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
-      "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
-      "engines": {
-        "node": "^4.5.0 || >= 5.9"
-      }
-    },
     "node_modules/basic-auth": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
@@ -6670,6 +6651,7 @@
       "version": "1.20.1",
       "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
       "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
+      "dev": true,
       "dependencies": {
         "bytes": "3.1.2",
         "content-type": "~1.0.4",
@@ -6693,6 +6675,7 @@
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
       "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+      "dev": true,
       "engines": {
         "node": ">= 0.8"
       }
@@ -6701,6 +6684,7 @@
       "version": "2.6.9",
       "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
       "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
       "dependencies": {
         "ms": "2.0.0"
       }
@@ -6709,6 +6693,7 @@
       "version": "0.4.24",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
       "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
       "dependencies": {
         "safer-buffer": ">= 2.1.2 < 3"
       },
@@ -6719,7 +6704,8 @@
     "node_modules/body-parser/node_modules/ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true
     },
     "node_modules/bonjour-service": {
       "version": "1.1.1",
@@ -7076,6 +7062,7 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
       "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+      "dev": true,
       "dependencies": {
         "function-bind": "^1.1.1",
         "get-intrinsic": "^1.0.2"
@@ -7285,14 +7272,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/cidr-matcher": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/cidr-matcher/-/cidr-matcher-2.1.1.tgz",
-      "integrity": "sha512-QPJRz4HDQxpB8AZWEqd6ejVp+siArXh3u1MYaUFV85cd293StGSMb87jVe0z9gS92KsFwxCxjb3utO3e5HKHTw==",
-      "dependencies": {
-        "ip6addr": "^0.2.2"
-      }
-    },
     "node_modules/cjs-module-lexer": {
       "version": "1.2.3",
       "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz",
@@ -7805,6 +7784,7 @@
       "version": "0.5.4",
       "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
       "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+      "dev": true,
       "dependencies": {
         "safe-buffer": "5.2.1"
       },
@@ -7816,6 +7796,7 @@
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
       "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+      "dev": true,
       "engines": {
         "node": ">= 0.6"
       }
@@ -7829,6 +7810,7 @@
       "version": "0.5.0",
       "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
       "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+      "dev": true,
       "engines": {
         "node": ">= 0.6"
       }
@@ -7836,7 +7818,8 @@
     "node_modules/cookie-signature": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
-      "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
+      "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+      "dev": true
     },
     "node_modules/core-js": {
       "version": "3.32.2",
@@ -7876,19 +7859,8 @@
     "node_modules/core-util-is": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
-    },
-    "node_modules/cors": {
-      "version": "2.8.5",
-      "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
-      "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
-      "dependencies": {
-        "object-assign": "^4",
-        "vary": "^1"
-      },
-      "engines": {
-        "node": ">= 0.10"
-      }
+      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
+      "dev": true
     },
     "node_modules/cosmiconfig": {
       "version": "8.3.6",
@@ -8776,6 +8748,7 @@
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
       "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+      "dev": true,
       "engines": {
         "node": ">= 0.8",
         "npm": "1.2.8000 || >= 1.4.16"
@@ -9290,11 +9263,6 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/electron-download-manager": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/electron-download-manager/-/electron-download-manager-2.1.2.tgz",
-      "integrity": "sha512-9v8aeMVZTX69NjEveKlKfTlJY74twpKktTXrmDI+UcQHZg7FtwuqxWw0ZNrjtVAOBcVNKzwG4ekn44B+xhz1tg=="
-    },
     "node_modules/electron-is-accelerator": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz",
@@ -9489,6 +9457,7 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
       "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+      "dev": true,
       "engines": {
         "node": ">= 0.8"
       }
@@ -9512,62 +9481,6 @@
         "once": "^1.4.0"
       }
     },
-    "node_modules/engine.io": {
-      "version": "6.5.3",
-      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.3.tgz",
-      "integrity": "sha512-IML/R4eG/pUS5w7OfcDE0jKrljWS9nwnEfsxWCIJF5eO6AHo6+Hlv+lQbdlAYsiJPHzUthLm1RUjnBzWOs45cw==",
-      "dependencies": {
-        "@types/cookie": "^0.4.1",
-        "@types/cors": "^2.8.12",
-        "@types/node": ">=10.0.0",
-        "accepts": "~1.3.4",
-        "base64id": "2.0.0",
-        "cookie": "~0.4.1",
-        "cors": "~2.8.5",
-        "debug": "~4.3.1",
-        "engine.io-parser": "~5.2.1",
-        "ws": "~8.11.0"
-      },
-      "engines": {
-        "node": ">=10.2.0"
-      }
-    },
-    "node_modules/engine.io-parser": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz",
-      "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==",
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
-    "node_modules/engine.io/node_modules/cookie": {
-      "version": "0.4.2",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
-      "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/engine.io/node_modules/ws": {
-      "version": "8.11.0",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
-      "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
-      "engines": {
-        "node": ">=10.0.0"
-      },
-      "peerDependencies": {
-        "bufferutil": "^4.0.1",
-        "utf-8-validate": "^5.0.2"
-      },
-      "peerDependenciesMeta": {
-        "bufferutil": {
-          "optional": true
-        },
-        "utf-8-validate": {
-          "optional": true
-        }
-      }
-    },
     "node_modules/enhanced-resolve": {
       "version": "5.15.0",
       "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
@@ -9796,7 +9709,8 @@
     "node_modules/escape-html": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
-      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+      "dev": true
     },
     "node_modules/escape-string-regexp": {
       "version": "4.0.0",
@@ -10960,6 +10874,7 @@
       "version": "4.18.2",
       "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
       "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+      "dev": true,
       "dependencies": {
         "accepts": "~1.3.8",
         "array-flatten": "1.1.1",
@@ -10997,54 +10912,17 @@
         "node": ">= 0.10.0"
       }
     },
-    "node_modules/express-session": {
-      "version": "1.17.3",
-      "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz",
-      "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==",
-      "dependencies": {
-        "cookie": "0.4.2",
-        "cookie-signature": "1.0.6",
-        "debug": "2.6.9",
-        "depd": "~2.0.0",
-        "on-headers": "~1.0.2",
-        "parseurl": "~1.3.3",
-        "safe-buffer": "5.2.1",
-        "uid-safe": "~2.1.5"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/express-session/node_modules/cookie": {
-      "version": "0.4.2",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
-      "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/express-session/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/express-session/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
-    },
     "node_modules/express/node_modules/array-flatten": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
-      "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+      "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+      "dev": true
     },
     "node_modules/express/node_modules/debug": {
       "version": "2.6.9",
       "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
       "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
       "dependencies": {
         "ms": "2.0.0"
       }
@@ -11052,7 +10930,8 @@
     "node_modules/express/node_modules/ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true
     },
     "node_modules/extend": {
       "version": "3.0.2",
@@ -11237,6 +11116,17 @@
         "webpack": "^4.0.0 || ^5.0.0"
       }
     },
+    "node_modules/file-selector": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz",
+      "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==",
+      "dependencies": {
+        "tslib": "^2.4.0"
+      },
+      "engines": {
+        "node": ">= 12"
+      }
+    },
     "node_modules/filelist": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
@@ -11262,6 +11152,7 @@
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
       "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+      "dev": true,
       "dependencies": {
         "debug": "2.6.9",
         "encodeurl": "~1.0.2",
@@ -11279,6 +11170,7 @@
       "version": "2.6.9",
       "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
       "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
       "dependencies": {
         "ms": "2.0.0"
       }
@@ -11286,7 +11178,8 @@
     "node_modules/finalhandler/node_modules/ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true
     },
     "node_modules/find-root": {
       "version": "1.1.0",
@@ -11427,6 +11320,7 @@
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
       "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+      "dev": true,
       "engines": {
         "node": ">= 0.6"
       }
@@ -11581,6 +11475,7 @@
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
       "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
+      "dev": true,
       "dependencies": {
         "function-bind": "^1.1.1",
         "has": "^1.0.3",
@@ -11885,6 +11780,7 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
       "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+      "dev": true,
       "engines": {
         "node": ">= 0.4"
       },
@@ -11896,6 +11792,7 @@
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
       "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+      "dev": true,
       "engines": {
         "node": ">= 0.4"
       },
@@ -12227,6 +12124,7 @@
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
       "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+      "dev": true,
       "dependencies": {
         "depd": "2.0.0",
         "inherits": "2.0.4",
@@ -12547,7 +12445,8 @@
     "node_modules/inherits": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true
     },
     "node_modules/inline-style-parser": {
       "version": "0.1.1",
@@ -12583,15 +12482,6 @@
       "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==",
       "dev": true
     },
-    "node_modules/ip6addr": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/ip6addr/-/ip6addr-0.2.5.tgz",
-      "integrity": "sha512-9RGGSB6Zc9Ox5DpDGFnJdIeF0AsqXzdH+FspCfPPaU/L/4tI6P+5lIoFUFm9JXs9IrJv1boqAaNCQmoDADTSKQ==",
-      "dependencies": {
-        "assert-plus": "^1.0.0",
-        "jsprim": "^2.0.2"
-      }
-    },
     "node_modules/ipaddr.js": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz",
@@ -14263,11 +14153,6 @@
       "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
       "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
     },
-    "node_modules/json-schema": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
-      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
-    },
     "node_modules/json-schema-compare": {
       "version": "0.2.2",
       "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz",
@@ -14343,41 +14228,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/jsprim": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz",
-      "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==",
-      "engines": [
-        "node >=0.6.0"
-      ],
-      "dependencies": {
-        "assert-plus": "1.0.0",
-        "extsprintf": "1.3.0",
-        "json-schema": "0.4.0",
-        "verror": "1.10.0"
-      }
-    },
-    "node_modules/jsprim/node_modules/extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
-      "engines": [
-        "node >=0.6.0"
-      ]
-    },
-    "node_modules/jsprim/node_modules/verror": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-      "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
-      "engines": [
-        "node >=0.6.0"
-      ],
-      "dependencies": {
-        "assert-plus": "^1.0.0",
-        "core-util-is": "1.0.2",
-        "extsprintf": "^1.2.0"
-      }
-    },
     "node_modules/jsx-ast-utils": {
       "version": "3.3.5",
       "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
@@ -15160,6 +15010,7 @@
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
       "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+      "dev": true,
       "engines": {
         "node": ">= 0.6"
       }
@@ -15190,7 +15041,8 @@
     "node_modules/merge-descriptors": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
-      "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
+      "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
+      "dev": true
     },
     "node_modules/merge-stream": {
       "version": "2.0.0",
@@ -15211,6 +15063,7 @@
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
       "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+      "dev": true,
       "engines": {
         "node": ">= 0.6"
       }
@@ -15779,6 +15632,7 @@
       "version": "1.52.0",
       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
       "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "dev": true,
       "engines": {
         "node": ">= 0.6"
       }
@@ -15795,6 +15649,7 @@
       "version": "2.1.35",
       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
       "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dev": true,
       "dependencies": {
         "mime-db": "1.52.0"
       },
@@ -16251,6 +16106,7 @@
       "version": "0.6.3",
       "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
       "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+      "dev": true,
       "engines": {
         "node": ">= 0.6"
       }
@@ -16453,6 +16309,7 @@
       "version": "1.12.3",
       "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
       "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
+      "dev": true,
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
       }
@@ -16583,6 +16440,7 @@
       "version": "2.4.1",
       "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
       "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+      "dev": true,
       "dependencies": {
         "ee-first": "1.1.1"
       },
@@ -16965,7 +16823,8 @@
     "node_modules/path-to-regexp": {
       "version": "0.1.7",
       "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
-      "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
+      "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==",
+      "dev": true
     },
     "node_modules/path-type": {
       "version": "4.0.0",
@@ -17865,6 +17724,7 @@
       "version": "2.0.7",
       "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
       "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+      "dev": true,
       "dependencies": {
         "forwarded": "0.2.0",
         "ipaddr.js": "1.9.1"
@@ -17877,6 +17737,7 @@
       "version": "1.9.1",
       "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
       "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+      "dev": true,
       "engines": {
         "node": ">= 0.10"
       }
@@ -17925,6 +17786,7 @@
       "version": "6.11.0",
       "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
       "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+      "dev": true,
       "dependencies": {
         "side-channel": "^1.0.4"
       },
@@ -17973,14 +17835,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/random-bytes": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
-      "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==",
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
     "node_modules/randombytes": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -17994,6 +17848,7 @@
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
       "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+      "dev": true,
       "engines": {
         "node": ">= 0.6"
       }
@@ -18002,6 +17857,7 @@
       "version": "2.5.1",
       "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
       "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+      "dev": true,
       "dependencies": {
         "bytes": "3.1.2",
         "http-errors": "2.0.0",
@@ -18016,6 +17872,7 @@
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
       "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+      "dev": true,
       "engines": {
         "node": ">= 0.8"
       }
@@ -18024,6 +17881,7 @@
       "version": "0.4.24",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
       "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
       "dependencies": {
         "safer-buffer": ">= 2.1.2 < 3"
       },
@@ -18054,6 +17912,22 @@
         "react": "^18.2.0"
       }
     },
+    "node_modules/react-dropzone": {
+      "version": "14.2.3",
+      "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz",
+      "integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==",
+      "dependencies": {
+        "attr-accept": "^2.2.2",
+        "file-selector": "^0.6.0",
+        "prop-types": "^15.8.1"
+      },
+      "engines": {
+        "node": ">= 10.13"
+      },
+      "peerDependencies": {
+        "react": ">= 16.8 || 18.0.0"
+      }
+    },
     "node_modules/react-icons": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.0.1.tgz",
@@ -18798,6 +18672,7 @@
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
       "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "dev": true,
       "funding": [
         {
           "type": "github",
@@ -18997,6 +18872,7 @@
       "version": "0.18.0",
       "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
       "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+      "dev": true,
       "dependencies": {
         "debug": "2.6.9",
         "depd": "2.0.0",
@@ -19020,6 +18896,7 @@
       "version": "2.6.9",
       "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
       "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
       "dependencies": {
         "ms": "2.0.0"
       }
@@ -19027,12 +18904,14 @@
     "node_modules/send/node_modules/debug/node_modules/ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true
     },
     "node_modules/send/node_modules/mime": {
       "version": "1.6.0",
       "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
       "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "dev": true,
       "bin": {
         "mime": "cli.js"
       },
@@ -19043,7 +18922,8 @@
     "node_modules/send/node_modules/ms": {
       "version": "2.1.3",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "dev": true
     },
     "node_modules/serialize-error": {
       "version": "7.0.1",
@@ -19190,6 +19070,7 @@
       "version": "1.15.0",
       "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
       "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+      "dev": true,
       "dependencies": {
         "encodeurl": "~1.0.2",
         "escape-html": "~1.0.3",
@@ -19229,7 +19110,8 @@
     "node_modules/setprototypeof": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
-      "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+      "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+      "dev": true
     },
     "node_modules/shallow-clone": {
       "version": "3.0.1",
@@ -19277,6 +19159,7 @@
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
       "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+      "dev": true,
       "dependencies": {
         "call-bind": "^1.0.0",
         "get-intrinsic": "^1.0.2",
@@ -19368,63 +19251,6 @@
         "tslib": "^2.0.3"
       }
     },
-    "node_modules/socket.io": {
-      "version": "4.7.2",
-      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz",
-      "integrity": "sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==",
-      "dependencies": {
-        "accepts": "~1.3.4",
-        "base64id": "~2.0.0",
-        "cors": "~2.8.5",
-        "debug": "~4.3.2",
-        "engine.io": "~6.5.2",
-        "socket.io-adapter": "~2.5.2",
-        "socket.io-parser": "~4.2.4"
-      },
-      "engines": {
-        "node": ">=10.2.0"
-      }
-    },
-    "node_modules/socket.io-adapter": {
-      "version": "2.5.2",
-      "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz",
-      "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==",
-      "dependencies": {
-        "ws": "~8.11.0"
-      }
-    },
-    "node_modules/socket.io-adapter/node_modules/ws": {
-      "version": "8.11.0",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
-      "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
-      "engines": {
-        "node": ">=10.0.0"
-      },
-      "peerDependencies": {
-        "bufferutil": "^4.0.1",
-        "utf-8-validate": "^5.0.2"
-      },
-      "peerDependenciesMeta": {
-        "bufferutil": {
-          "optional": true
-        },
-        "utf-8-validate": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/socket.io-parser": {
-      "version": "4.2.4",
-      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
-      "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
-      "dependencies": {
-        "@socket.io/component-emitter": "~3.1.0",
-        "debug": "~4.3.1"
-      },
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
     "node_modules/sockjs": {
       "version": "0.3.24",
       "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
@@ -19618,6 +19444,7 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
       "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+      "dev": true,
       "engines": {
         "node": ">= 0.8"
       }
@@ -20346,6 +20173,7 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
       "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+      "dev": true,
       "engines": {
         "node": ">=0.6"
       }
@@ -20625,8 +20453,7 @@
     "node_modules/tslib": {
       "version": "2.6.2",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
-      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
-      "dev": true
+      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
     },
     "node_modules/tsutils": {
       "version": "3.21.0",
@@ -20690,6 +20517,7 @@
       "version": "1.6.18",
       "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
       "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "dev": true,
       "dependencies": {
         "media-typer": "0.3.0",
         "mime-types": "~2.1.24"
@@ -20776,17 +20604,6 @@
         "node": ">=14.17"
       }
     },
-    "node_modules/uid-safe": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
-      "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
-      "dependencies": {
-        "random-bytes": "~1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
     "node_modules/unbox-primitive": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
@@ -20992,6 +20809,7 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
       "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+      "dev": true,
       "engines": {
         "node": ">= 0.8"
       }
@@ -21144,6 +20962,7 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
       "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+      "dev": true,
       "engines": {
         "node": ">= 0.4.0"
       }
@@ -21254,6 +21073,7 @@
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
       "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+      "dev": true,
       "engines": {
         "node": ">= 0.8"
       }
diff --git a/package.json b/package.json
index f9170550..958caa24 100644
--- a/package.json
+++ b/package.json
@@ -117,6 +117,7 @@
     "morgan": "~1.10.0",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
+    "react-dropzone": "^14.2.3",
     "react-icons": "^5.0.1",
     "react-markdown": "^8.0.7",
     "react-router-dom": "^6.11.2",
diff --git a/src/renderer/components/Experiment/Documents/index.tsx b/src/renderer/components/Experiment/Documents/index.tsx
index 56fc6e5f..eed6a417 100644
--- a/src/renderer/components/Experiment/Documents/index.tsx
+++ b/src/renderer/components/Experiment/Documents/index.tsx
@@ -38,6 +38,7 @@ import useSWR from 'swr';
 import { formatBytes } from 'renderer/lib/utils';
 
 import * as chatAPI from '../../../lib/transformerlab-api-sdk';
+import Dropzone from 'react-dropzone';
 
 function descendingComparator<T>(a: T, b: T, orderBy: keyof T) {
   if (b[orderBy] < a[orderBy]) {
@@ -109,6 +110,8 @@ export default function OrderTable({ experimentInfo }) {
   const [selected, setSelected] = React.useState<readonly string[]>([]);
   const [open, setOpen] = React.useState(false);
 
+  const [dropzoneActive, setDropzoneActive] = React.useState(false);
+
   const { data: rows, isLoading } = useSWR(
     chatAPI.Endpoints.Documents.List(experimentInfo?.id),
     fetcher
@@ -212,157 +215,202 @@ export default function OrderTable({ experimentInfo }) {
         </FormControl>
         {renderFilters()}
       </Box>
-      <Sheet
-        className="DocTableContainer"
-        variant="outlined"
-        sx={{
-          display: { xs: 'none', sm: 'initial' },
-          width: '100%',
-          borderRadius: 'sm',
-          flexShrink: 1,
-          overflow: 'auto',
-          minHeight: 0,
-          height: '100%',
-          marginBottom: 3,
+      <Dropzone
+        onDrop={(acceptedFiles) => {
+          console.log(acceptedFiles);
+          setDropzoneActive(false);
+        }}
+        onDragEnter={() => {
+          setDropzoneActive(true);
         }}
+        onDragLeave={() => {
+          setDropzoneActive(false);
+        }}
+        noClick
       >
-        <Table
-          aria-labelledby="tableTitle"
-          stickyHeader
-          hoverRow
-          sx={{
-            '--TableCell-headBackground':
-              'var(--joy-palette-background-level1)',
-            '--Table-headerUnderlineThickness': '1px',
-            '--TableRow-hoverBackground':
-              'var(--joy-palette-background-level1)',
-            '--TableCell-paddingY': '4px',
-            '--TableCell-paddingX': '8px',
-          }}
-        >
-          <thead>
-            <tr>
-              <th
-                style={{ width: 48, textAlign: 'center', padding: '12px 6px' }}
+        {({ getRootProps, getInputProps }) => (
+          <div
+            {...getRootProps()}
+            style={{
+              display: 'flex',
+              flexDirection: 'column',
+              marginBottom: '2rem',
+              overflow: 'hidden',
+              height: '100%',
+              border: dropzoneActive
+                ? '2px solid red'
+                : '2px solid transparent',
+            }}
+          >
+            <Sheet
+              className="DocTableContainer"
+              variant="outlined"
+              sx={{
+                display: { xs: 'none', sm: 'initial' },
+                width: '100%',
+                borderRadius: 'sm',
+                flexShrink: 1,
+                overflow: 'auto',
+                minHeight: 0,
+                height: '100%',
+              }}
+            >
+              <Table
+                aria-labelledby="tableTitle"
+                stickyHeader
+                hoverRow
+                sx={{
+                  '--TableCell-headBackground':
+                    'var(--joy-palette-background-level1)',
+                  '--Table-headerUnderlineThickness': '1px',
+                  '--TableRow-hoverBackground':
+                    'var(--joy-palette-background-level1)',
+                  '--TableCell-paddingY': '4px',
+                  '--TableCell-paddingX': '8px',
+                }}
               >
-                <Checkbox
-                  size="sm"
-                  indeterminate={
-                    selected.length > 0 && selected.length !== rows?.length
-                  }
-                  checked={selected.length === rows?.length}
-                  onChange={(event) => {
-                    setSelected(
-                      event.target.checked ? rows?.map((row) => row?.name) : []
-                    );
-                  }}
-                  color={
-                    selected.length > 0 || selected.length === rows?.length
-                      ? 'primary'
-                      : undefined
-                  }
-                  sx={{ verticalAlign: 'text-bottom' }}
-                />
-              </th>
-              <th style={{ width: 120, padding: '12px 6px' }}>
-                <Link
-                  underline="none"
-                  color="primary"
-                  component="button"
-                  onClick={() => setDoc(doc === 'asc' ? 'desc' : 'asc')}
-                  fontWeight="lg"
-                  endDecorator={<ArrowDropDownIcon />}
-                  sx={{
-                    '& svg': {
-                      transition: '0.2s',
-                      transform:
-                        doc === 'desc' ? 'rotate(0deg)' : 'rotate(180deg)',
-                    },
-                  }}
-                >
-                  File Name
-                </Link>
-              </th>
-              <th style={{ width: 140, padding: '12px 6px' }}>Date</th>
-              <th style={{ width: 140, padding: '12px 6px' }}>Type</th>{' '}
-              <th style={{ width: 140, padding: '12px 6px' }}>Size</th>
-              <th style={{ width: 100, padding: '12px 6px' }}> </th>
-            </tr>
-          </thead>
-          <tbody>
-            {stableSort(rows, getComparator(doc, 'id'))?.map((row) => (
-              <tr key={row?.name}>
-                <td style={{ textAlign: 'center', width: 120 }}>
-                  <Checkbox
-                    size="sm"
-                    checked={selected.includes(row?.name)}
-                    color={selected.includes(row?.name) ? 'primary' : undefined}
-                    onChange={(event) => {
-                      setSelected((ids) =>
-                        event.target.checked
-                          ? ids.concat(row?.name)
-                          : ids.filter((itemId) => itemId !== row?.name)
-                      );
-                    }}
-                    slotProps={{ checkbox: { sx: { textAlign: 'left' } } }}
-                    sx={{ verticalAlign: 'text-bottom' }}
-                  />
-                </td>
-                <td>
-                  <Typography level="body-xs">{row?.name}</Typography>
-                </td>
-                <td>
-                  <Typography level="body-xs">{row?.date}</Typography>
-                </td>
-                <td>
-                  <Chip
-                    variant="soft"
-                    size="sm"
-                    startDecorator={
-                      {
-                        '.txt': <FileTextIcon />,
-                        '.pdf': <AutorenewRoundedIcon />,
-                        '.jsonl': <BlockIcon />,
-                      }[row?.type]
-                    }
-                    color={
-                      {
-                        '.txt': 'success',
-                        '.pdf': 'neutral',
-                        '.jsonl': 'danger',
-                      }[row?.type] as ColorPaletteProp
-                    }
-                  >
-                    {row?.type}
-                  </Chip>
-                </td>
-                <td>
-                  {row?.size && (
-                    <Typography level="body-xs" color="neutral">
-                      {formatBytes(row?.size)}
-                    </Typography>
-                  )}
-                </td>
-                <td>
-                  <Box
-                    sx={{
-                      display: 'flex',
-                      gap: 2,
-                      alignItems: 'center',
-                      justifyContent: 'flex-end',
-                    }}
-                  >
-                    <Link level="body-xs" component="button">
-                      Preview
-                    </Link>
-                    <RowMenu />
-                  </Box>
-                </td>
-              </tr>
-            ))}
-          </tbody>
-        </Table>
-      </Sheet>
+                <thead>
+                  <tr>
+                    <th
+                      style={{
+                        width: 48,
+                        textAlign: 'center',
+                        padding: '12px 6px',
+                      }}
+                    >
+                      <Checkbox
+                        size="sm"
+                        indeterminate={
+                          selected.length > 0 &&
+                          selected.length !== rows?.length
+                        }
+                        checked={selected.length === rows?.length}
+                        onChange={(event) => {
+                          setSelected(
+                            event.target.checked
+                              ? rows?.map((row) => row?.name)
+                              : []
+                          );
+                        }}
+                        color={
+                          selected.length > 0 ||
+                          selected.length === rows?.length
+                            ? 'primary'
+                            : undefined
+                        }
+                        sx={{ verticalAlign: 'text-bottom' }}
+                      />
+                    </th>
+                    <th style={{ width: 120, padding: '12px 6px' }}>
+                      <Link
+                        underline="none"
+                        color="primary"
+                        component="button"
+                        onClick={() => setDoc(doc === 'asc' ? 'desc' : 'asc')}
+                        fontWeight="lg"
+                        endDecorator={<ArrowDropDownIcon />}
+                        sx={{
+                          '& svg': {
+                            transition: '0.2s',
+                            transform:
+                              doc === 'desc'
+                                ? 'rotate(0deg)'
+                                : 'rotate(180deg)',
+                          },
+                        }}
+                      >
+                        File Name
+                      </Link>
+                    </th>
+                    <th style={{ width: 140, padding: '12px 6px' }}>Date</th>
+                    <th style={{ width: 140, padding: '12px 6px' }}>
+                      Type
+                    </th>{' '}
+                    <th style={{ width: 140, padding: '12px 6px' }}>Size</th>
+                    <th style={{ width: 100, padding: '12px 6px' }}> </th>
+                  </tr>
+                </thead>
+                <tbody>
+                  {stableSort(rows, getComparator(doc, 'id'))?.map((row) => (
+                    <tr key={row?.name}>
+                      <td style={{ textAlign: 'center', width: 120 }}>
+                        <Checkbox
+                          size="sm"
+                          checked={selected.includes(row?.name)}
+                          color={
+                            selected.includes(row?.name) ? 'primary' : undefined
+                          }
+                          onChange={(event) => {
+                            setSelected((ids) =>
+                              event.target.checked
+                                ? ids.concat(row?.name)
+                                : ids.filter((itemId) => itemId !== row?.name)
+                            );
+                          }}
+                          slotProps={{
+                            checkbox: { sx: { textAlign: 'left' } },
+                          }}
+                          sx={{ verticalAlign: 'text-bottom' }}
+                        />
+                      </td>
+                      <td>
+                        <Typography level="body-xs">{row?.name}</Typography>
+                      </td>
+                      <td>
+                        <Typography level="body-xs">{row?.date}</Typography>
+                      </td>
+                      <td>
+                        <Chip
+                          variant="soft"
+                          size="sm"
+                          startDecorator={
+                            {
+                              '.txt': <FileTextIcon />,
+                              '.pdf': <AutorenewRoundedIcon />,
+                              '.jsonl': <BlockIcon />,
+                            }[row?.type]
+                          }
+                          color={
+                            {
+                              '.txt': 'success',
+                              '.pdf': 'neutral',
+                              '.jsonl': 'danger',
+                            }[row?.type] as ColorPaletteProp
+                          }
+                        >
+                          {row?.type}
+                        </Chip>
+                      </td>
+                      <td>
+                        {row?.size && (
+                          <Typography level="body-xs" color="neutral">
+                            {formatBytes(row?.size)}
+                          </Typography>
+                        )}
+                      </td>
+                      <td>
+                        <Box
+                          sx={{
+                            display: 'flex',
+                            gap: 2,
+                            alignItems: 'center',
+                            justifyContent: 'flex-end',
+                          }}
+                        >
+                          <Link level="body-xs" component="button">
+                            Preview
+                          </Link>
+                          <RowMenu />
+                        </Box>
+                      </td>
+                    </tr>
+                  ))}
+                </tbody>
+              </Table>
+            </Sheet>
+          </div>
+        )}
+      </Dropzone>
     </React.Fragment>
   );
 }
-- 
GitLab