From bdf9529e8062f8a7b87e1d3143e27cd9e8588314 Mon Sep 17 00:00:00 2001
From: Sean Hatfield <seanhatfield5@gmail.com>
Date: Tue, 22 Aug 2023 21:14:24 -0700
Subject: [PATCH] Implement toast for upload event (#214)

* WIP success fail messages for upload document

* added success/error msgs for uploading feedback and disabled fileUploadProgress in backend

* implemented toast instead of success/error msg on modal for upload

* left over merge

---------

Co-authored-by: timothycarambat <rambat1010@gmail.com>
---
 frontend/package.json                         |  3 +-
 frontend/src/App.jsx                          |  3 ++
 .../Modals/MangeWorkspace/Upload/index.jsx    | 33 ++----------------
 frontend/src/utils/toast.js                   | 34 +++++++++++++++++++
 frontend/yarn.lock                            | 12 +++++++
 5 files changed, 54 insertions(+), 31 deletions(-)
 create mode 100644 frontend/src/utils/toast.js

diff --git a/frontend/package.json b/frontend/package.json
index 41ef50324..eb3af3cff 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -24,6 +24,7 @@
     "react-loading-icons": "^1.1.0",
     "react-loading-skeleton": "^3.1.0",
     "react-router-dom": "^6.3.0",
+    "react-toastify": "^9.1.3",
     "text-case": "^1.0.9",
     "truncate": "^3.0.0",
     "uuid": "^9.0.0"
@@ -43,4 +44,4 @@
     "tailwindcss": "^3.3.1",
     "vite": "^4.3.0"
   }
-}
\ No newline at end of file
+}
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index f5d534262..df74f73eb 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -2,6 +2,8 @@ import React, { lazy, Suspense } from "react";
 import { Routes, Route } from "react-router-dom";
 import { ContextWrapper } from "./AuthContext";
 import PrivateRoute, { AdminRoute } from "./components/PrivateRoute";
+import { ToastContainer } from "react-toastify";
+import "react-toastify/dist/ReactToastify.css";
 
 const Main = lazy(() => import("./pages/Main"));
 const InvitePage = lazy(() => import("./pages/Invite"));
@@ -51,6 +53,7 @@ export default function App() {
             element={<AdminRoute Component={AdminAppearance} />}
           />
         </Routes>
+        <ToastContainer />
       </ContextWrapper>
     </Suspense>
   );
diff --git a/frontend/src/components/Modals/MangeWorkspace/Upload/index.jsx b/frontend/src/components/Modals/MangeWorkspace/Upload/index.jsx
index b7a8bc37c..a4d042066 100644
--- a/frontend/src/components/Modals/MangeWorkspace/Upload/index.jsx
+++ b/frontend/src/components/Modals/MangeWorkspace/Upload/index.jsx
@@ -6,21 +6,18 @@ import { useDropzone } from "react-dropzone";
 import { v4 } from "uuid";
 import System from "../../../../models/system";
 import { Frown } from "react-feather";
+import showToast from "../../../../utils/toast";
 
 export default function UploadToWorkspace({ workspace, fileTypes }) {
   const [ready, setReady] = useState(null);
   const [files, setFiles] = useState([]);
-  const [successMsg, setSuccessMsg] = useState("");
-  const [errorMsg, setErrorMsg] = useState("");
 
   const handleUploadSuccess = () => {
-    setSuccessMsg("File uploaded successfully");
-    setErrorMsg(null);
+    showToast("File uploaded successfully", "success");
   };
 
   const handleUploadError = (message) => {
-    setErrorMsg(`Upload failed: ${message}`);
-    setSuccessMsg(null);
+    showToast(`Error uploading file: ${message}`, "error");
   };
 
   const onDrop = useCallback(async (acceptedFiles, rejections) => {
@@ -50,20 +47,6 @@ export default function UploadToWorkspace({ workspace, fileTypes }) {
     checkProcessorOnline();
   }, []);
 
-  useEffect(() => {
-    if (!!successMsg) {
-      setTimeout(() => {
-        setSuccessMsg("");
-      }, 3_500);
-    }
-
-    if (!!errorMsg) {
-      setTimeout(() => {
-        setErrorMsg("");
-      }, 3_500);
-    }
-  }, [successMsg, errorMsg]);
-
   const { getRootProps, getInputProps } = useDropzone({
     onDrop,
     accept: {
@@ -173,16 +156,6 @@ export default function UploadToWorkspace({ workspace, fileTypes }) {
           {Object.values(fileTypes).flat().join(" ")}
         </code>
       </p>
-      {successMsg && (
-        <p className="text-green-600 dark:text-green-400 text-sm text-center pt-2">
-          {successMsg}
-        </p>
-      )}
-      {errorMsg && (
-        <p className="text-red-600 dark:text-red-400 text-sm text-center pt-2">
-          {errorMsg}
-        </p>
-      )}
     </ModalWrapper>
   );
 }
diff --git a/frontend/src/utils/toast.js b/frontend/src/utils/toast.js
new file mode 100644
index 000000000..6a39f006c
--- /dev/null
+++ b/frontend/src/utils/toast.js
@@ -0,0 +1,34 @@
+import { toast } from "react-toastify";
+import usePrefersDarkMode from "../hooks/usePrefersDarkMode";
+
+const showToast = (message, type = "default") => {
+  const prefersDarkMode = usePrefersDarkMode();
+  const options = {
+    position: "bottom-center",
+    autoClose: 5000,
+    hideProgressBar: false,
+    closeOnClick: true,
+    pauseOnHover: true,
+    draggable: true,
+    theme: prefersDarkMode ? "dark" : "light",
+  };
+
+  switch (type) {
+    case "success":
+      toast.success(message, options);
+      break;
+    case "error":
+      toast.error(message, options);
+      break;
+    case "info":
+      toast.info(message, options);
+      break;
+    case "warning":
+      toast.warn(message, options);
+      break;
+    default:
+      toast(message, options);
+  }
+};
+
+export default showToast;
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 2e7a7601f..c4199eb39 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -729,6 +729,11 @@ clone@^1.0.2:
   resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz"
   integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
 
+clsx@^1.1.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
+  integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
+
 color-convert@^1.3.0, color-convert@^1.9.0:
   version "1.9.3"
   resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz"
@@ -2043,6 +2048,13 @@ react-router@6.12.1:
   dependencies:
     "@remix-run/router" "1.6.3"
 
+react-toastify@^9.1.3:
+  version "9.1.3"
+  resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-9.1.3.tgz#1e798d260d606f50e0fab5ee31daaae1d628c5ff"
+  integrity sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==
+  dependencies:
+    clsx "^1.1.1"
+
 react@^18.2.0:
   version "18.2.0"
   resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
-- 
GitLab