From 3f418a45f51f32e51b8b4d8a364e83e6d70dc592 Mon Sep 17 00:00:00 2001 From: M M Date: Tue, 11 Jun 2024 15:15:32 -0700 Subject: [PATCH 1/5] Implemented the toastify notifications. --- Client/package-lock.json | 16 ++++++++++++++-- Client/package.json | 3 ++- Client/src/Components/Notifications/index.css | 0 Client/src/Components/Notifications/index.jsx | 10 ++++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 Client/src/Components/Notifications/index.css create mode 100644 Client/src/Components/Notifications/index.jsx diff --git a/Client/package-lock.json b/Client/package-lock.json index 73edbf7fb..9fc7a39c1 100644 --- a/Client/package-lock.json +++ b/Client/package-lock.json @@ -25,7 +25,8 @@ "react-dom": "^18.2.0", "react-redux": "9.1.2", "react-router": "^6.23.0", - "react-router-dom": "^6.23.1" + "react-router-dom": "^6.23.1", + "react-toastify": "^10.0.5" }, "devDependencies": { "@types/react": "^18.2.66", @@ -2647,7 +2648,6 @@ "integrity": "sha512-NglN/xprcM+SHD2XCli4oC6bWe6kHoytcyLKCWXmRL854F0qhPhaYgUswUsglnPxYaNQIg2uMY4BvaomIf3kLA==", "dev": true, "license": "ISC" - }, "node_modules/error-ex": { "version": "1.3.2", @@ -4672,6 +4672,18 @@ "react-dom": ">=16.8" } }, + "node_modules/react-toastify": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz", + "integrity": "sha512-mNKt2jBXJg4O7pSdbNUfDdTsK9FIdikfsIE/yUCxbAEXl4HMyJaivrVFcn3Elvt5xvCQYhUZm+hqTIu1UXM3Pw==", + "dependencies": { + "clsx": "^2.1.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", diff --git a/Client/package.json b/Client/package.json index 505fe25d8..546b138cf 100644 --- a/Client/package.json +++ b/Client/package.json @@ -27,7 +27,8 @@ "react-dom": "^18.2.0", "react-redux": "9.1.2", "react-router": "^6.23.0", - "react-router-dom": "^6.23.1" + "react-router-dom": "^6.23.1", + "react-toastify": "^10.0.5" }, "devDependencies": { "@types/react": "^18.2.66", diff --git a/Client/src/Components/Notifications/index.css b/Client/src/Components/Notifications/index.css new file mode 100644 index 000000000..e69de29bb diff --git a/Client/src/Components/Notifications/index.jsx b/Client/src/Components/Notifications/index.jsx new file mode 100644 index 000000000..b2bf09fb9 --- /dev/null +++ b/Client/src/Components/Notifications/index.jsx @@ -0,0 +1,10 @@ +import { ToastContainer, toast } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.css'; + +const Notification = () => { + return ; +}; + +export const notify = (message) => toast(message); + +export default Notification; From 58313dde5ce7f2d1955bd8e2d372420ff77edb4a Mon Sep 17 00:00:00 2001 From: M M Date: Wed, 12 Jun 2024 16:12:18 -0700 Subject: [PATCH 2/5] Matched toast notification to existing error notifications. --- Client/src/Components/Notifications/index.css | 0 Client/src/Components/Notifications/index.jsx | 10 -- Client/src/Components/Toast/index.css | 103 ++++++++++++++++++ Client/src/Components/Toast/index.jsx | 63 +++++++++++ Client/src/Pages/PlayGround/PlayGround.jsx | 2 + 5 files changed, 168 insertions(+), 10 deletions(-) delete mode 100644 Client/src/Components/Notifications/index.css delete mode 100644 Client/src/Components/Notifications/index.jsx create mode 100644 Client/src/Components/Toast/index.css create mode 100644 Client/src/Components/Toast/index.jsx diff --git a/Client/src/Components/Notifications/index.css b/Client/src/Components/Notifications/index.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/Client/src/Components/Notifications/index.jsx b/Client/src/Components/Notifications/index.jsx deleted file mode 100644 index b2bf09fb9..000000000 --- a/Client/src/Components/Notifications/index.jsx +++ /dev/null @@ -1,10 +0,0 @@ -import { ToastContainer, toast } from 'react-toastify'; -import 'react-toastify/dist/ReactToastify.css'; - -const Notification = () => { - return ; -}; - -export const notify = (message) => toast(message); - -export default Notification; diff --git a/Client/src/Components/Toast/index.css b/Client/src/Components/Toast/index.css new file mode 100644 index 000000000..0653f3d27 --- /dev/null +++ b/Client/src/Components/Toast/index.css @@ -0,0 +1,103 @@ +.toast-container { + position: fixed; + bottom: 20px; /* Adjust as needed */ + right: 20px; /* Adjust as needed */ + z-index: 1000; /* Ensure it's above other content */ + } + + .toast { + background-color: #ffffff; + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2); + border-radius: 8px; + padding: 16px; + min-width: 300px; /* Adjust minimum width as needed */ + max-width: 600px; /* Adjust maximum width as needed */ + position: relative; + animation: slideIn 0.3s ease forwards; + overflow: hidden; /* Ensure progress bar stays within bounds */ + display: flex; /* Use flexbox for layout */ + align-items: center; /* Center items vertically */ + } + + @keyframes slideIn { + 0% { + transform: translateY(-100%); + opacity: 0; + } + 100% { + transform: translateY(0%); + opacity: 1; + } + } + + .toast .info-icon-frame { + position: absolute; + top: 15px; /* Adjust top position as needed */ + left: 20px; /* Adjust left position as needed */ + } + + .icon { + position: absolute; + top: 15px; /* Adjust top position as needed */ + left: 20px; /* Adjust left position as needed */ + } + + .toast .toast-content { + flex-grow: 1; /* Allow content to expand */ + } + + .toast .announcement-content { + display: flex; + flex-direction: column; + margin-left: 10px; + } + + .toast .announcement-content-subject { + font-weight: bold; + margin-bottom: 8px; /* Space below subject */ + margin-left: 40px; /* Adjust left margin for more space */ + } + + .toast .announcement-content-body { + color: #555; + white-space: nowrap; /* Prevent text from wrapping */ + overflow: hidden; /* Hide any overflow */ + text-overflow: ellipsis; /* Show ellipsis (...) if the text overflows */ + margin-left: 40px; /* Adjust left margin for more space */ + } + + .toast .announcement-content-body-title { + display: inline-block; + margin-right: 5px; /* Adjust spacing between title and body */ + } + + .toast .announcement-content-controllers { + margin-top: 12px; + } + + .toast .controllers-button-esc, + .toast .controllers-button-primary { + cursor: pointer; + padding: 8px 16px; + margin-left: 23px; /* Adjust left margin for closer proximity */ + } + + + .toast-progress { + position: absolute; + bottom: 0; + left: 0; + height: 4px; + background-color: #29b6f6; /* Adjust color as needed */ + transition: width 0.1s linear; + } + + .close-button { + position: absolute; + top: 1px; + right: 10px; + cursor: pointer; + font-size: 35px; + color: #aaa; + } + \ No newline at end of file diff --git a/Client/src/Components/Toast/index.jsx b/Client/src/Components/Toast/index.jsx new file mode 100644 index 000000000..37870a970 --- /dev/null +++ b/Client/src/Components/Toast/index.jsx @@ -0,0 +1,63 @@ +import { useState, useEffect } from "react"; +import ComplexAlert from "../../Components/Icons/ComplexAlert/ComplexAlert"; +import "./index.css"; // Import your CSS file for toast styles + +const Toast = () => { + const [showToast, setShowToast] = useState(false); + const [progress, setProgress] = useState(100); // Start with full progress + + useEffect(() => { + let timer; + if (showToast) { + timer = setTimeout(() => { + setShowToast(false); + }, 5000); // 5000 milliseconds = 5 seconds + + // Interval to update progress bar + const interval = setInterval(() => { + setProgress((prevProgress) => prevProgress - (100 / 5000 * 100)); // Decrease progress based on time + }, 100); // Update every 100 milliseconds + + return () => { + clearTimeout(timer); + clearInterval(interval); + }; + } + }, [showToast]); + + const toggleToast = () => { + setShowToast(!showToast); + setProgress(100); // Reset progress when showing toast + }; + + return ( +
+ + {showToast && ( +
+ × +
+ {} +
+
+
+
+ There was a problem with that action +
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid pariatur, ipsum dolor. +
+
+
Dismiss
+
View changes
+
+
+
+
+
+ )} +
+ ); +}; + +export default Toast; diff --git a/Client/src/Pages/PlayGround/PlayGround.jsx b/Client/src/Pages/PlayGround/PlayGround.jsx index b5e439aed..5f46af08d 100644 --- a/Client/src/Pages/PlayGround/PlayGround.jsx +++ b/Client/src/Pages/PlayGround/PlayGround.jsx @@ -13,6 +13,7 @@ import AnnouncementUpdateSubscription from "../../Components/Announcements/Annou import PlayGroundCharts from "./PlayGround-Charts"; import PlayGroundPopupModals from "./PlayGround-Popup-Modals"; import PlayGroundTooltips from "./PlayGround-Tooltips"; +import Toast from "../../Components/Toast"; // This Component is just for the development and test // purposes and just to see what my components look like while development @@ -52,6 +53,7 @@ function PlayGround() { hasCopyButton={true} hintText="This is a hint text to help user." /> +
{/* Now, illustration of the Description text fields */} From 18fe82b04853bb7c147c0adfe2912aff1a3313cd Mon Sep 17 00:00:00 2001 From: M M Date: Sat, 15 Jun 2024 16:39:05 -0700 Subject: [PATCH 3/5] Committing changes to build_images.sh before switching branches --- Server/docker/build_images.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 Server/docker/build_images.sh diff --git a/Server/docker/build_images.sh b/Server/docker/build_images.sh old mode 100755 new mode 100644 From 2de2b359afc0766e654038c148e7855af791383f Mon Sep 17 00:00:00 2001 From: M M Date: Sat, 15 Jun 2024 19:06:51 -0700 Subject: [PATCH 4/5] Refactored Toast Component into a custom React Toastify component. --- Client/src/App.jsx | 2 + Client/src/Components/Toast/index.css | 106 +------------------------- Client/src/Components/Toast/index.jsx | 75 +++++------------- 3 files changed, 26 insertions(+), 157 deletions(-) diff --git a/Client/src/App.jsx b/Client/src/App.jsx index 16774c60a..367a66758 100644 --- a/Client/src/App.jsx +++ b/Client/src/App.jsx @@ -15,6 +15,7 @@ import ForgotPassword from "./Pages/ForgotPassword"; import CheckEmail from "./Pages/CheckEmail"; import SetNewPassword from "./Pages/SetNewPassword"; import NewPasswordConfirmed from "./Pages/NewPasswordConfirmed"; +import ToastComponent from "./Components/Toast"; function App() { return ( @@ -30,6 +31,7 @@ function App() { } /> } /> } /> + } /> } /> } /> } /> diff --git a/Client/src/Components/Toast/index.css b/Client/src/Components/Toast/index.css index 0653f3d27..c778d22f5 100644 --- a/Client/src/Components/Toast/index.css +++ b/Client/src/Components/Toast/index.css @@ -1,103 +1,3 @@ -.toast-container { - position: fixed; - bottom: 20px; /* Adjust as needed */ - right: 20px; /* Adjust as needed */ - z-index: 1000; /* Ensure it's above other content */ - } - - .toast { - background-color: #ffffff; - box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2); - border-radius: 8px; - padding: 16px; - min-width: 300px; /* Adjust minimum width as needed */ - max-width: 600px; /* Adjust maximum width as needed */ - position: relative; - animation: slideIn 0.3s ease forwards; - overflow: hidden; /* Ensure progress bar stays within bounds */ - display: flex; /* Use flexbox for layout */ - align-items: center; /* Center items vertically */ - } - - @keyframes slideIn { - 0% { - transform: translateY(-100%); - opacity: 0; - } - 100% { - transform: translateY(0%); - opacity: 1; - } - } - - .toast .info-icon-frame { - position: absolute; - top: 15px; /* Adjust top position as needed */ - left: 20px; /* Adjust left position as needed */ - } - - .icon { - position: absolute; - top: 15px; /* Adjust top position as needed */ - left: 20px; /* Adjust left position as needed */ - } - - .toast .toast-content { - flex-grow: 1; /* Allow content to expand */ - } - - .toast .announcement-content { - display: flex; - flex-direction: column; - margin-left: 10px; - } - - .toast .announcement-content-subject { - font-weight: bold; - margin-bottom: 8px; /* Space below subject */ - margin-left: 40px; /* Adjust left margin for more space */ - } - - .toast .announcement-content-body { - color: #555; - white-space: nowrap; /* Prevent text from wrapping */ - overflow: hidden; /* Hide any overflow */ - text-overflow: ellipsis; /* Show ellipsis (...) if the text overflows */ - margin-left: 40px; /* Adjust left margin for more space */ - } - - .toast .announcement-content-body-title { - display: inline-block; - margin-right: 5px; /* Adjust spacing between title and body */ - } - - .toast .announcement-content-controllers { - margin-top: 12px; - } - - .toast .controllers-button-esc, - .toast .controllers-button-primary { - cursor: pointer; - padding: 8px 16px; - margin-left: 23px; /* Adjust left margin for closer proximity */ - } - - - .toast-progress { - position: absolute; - bottom: 0; - left: 0; - height: 4px; - background-color: #29b6f6; /* Adjust color as needed */ - transition: width 0.1s linear; - } - - .close-button { - position: absolute; - top: 1px; - right: 10px; - cursor: pointer; - font-size: 35px; - color: #aaa; - } - \ No newline at end of file +.Toastify__toast-container { + width: auto; +} \ No newline at end of file diff --git a/Client/src/Components/Toast/index.jsx b/Client/src/Components/Toast/index.jsx index 37870a970..f3a06bdb1 100644 --- a/Client/src/Components/Toast/index.jsx +++ b/Client/src/Components/Toast/index.jsx @@ -1,63 +1,30 @@ -import { useState, useEffect } from "react"; import ComplexAlert from "../../Components/Icons/ComplexAlert/ComplexAlert"; -import "./index.css"; // Import your CSS file for toast styles +import AnnouncementsDualButtonWithIcon from "../../Components/Announcements/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon"; +import "react-toastify/dist/ReactToastify.css"; +import { toast, ToastContainer } from "react-toastify"; +import "./index.css"; -const Toast = () => { - const [showToast, setShowToast] = useState(false); - const [progress, setProgress] = useState(100); // Start with full progress - - useEffect(() => { - let timer; - if (showToast) { - timer = setTimeout(() => { - setShowToast(false); - }, 5000); // 5000 milliseconds = 5 seconds - - // Interval to update progress bar - const interval = setInterval(() => { - setProgress((prevProgress) => prevProgress - (100 / 5000 * 100)); // Decrease progress based on time - }, 100); // Update every 100 milliseconds - - return () => { - clearTimeout(timer); - clearInterval(interval); - }; - } - }, [showToast]); - - const toggleToast = () => { - setShowToast(!showToast); - setProgress(100); // Reset progress when showing toast +const ToastComponent = () => { + const displayMsg = () => { + toast( + } + subject="There was a problem with that action" + body="Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid pariatur, ipsum dolor." + esc="Dismiss" + primary="Learn more" + dismiss={() => toast.dismiss()} + />, + { closeButton: false } + ); }; return ( -
- - {showToast && ( -
- × -
- {} -
-
-
-
- There was a problem with that action -
-
- Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid pariatur, ipsum dolor. -
-
-
Dismiss
-
View changes
-
-
-
-
-
- )} +
+ +
); }; -export default Toast; +export default ToastComponent; From de04a99bf7d501fd93a17246f13cfbffa65a448a Mon Sep 17 00:00:00 2001 From: M M Date: Sun, 16 Jun 2024 13:49:25 -0700 Subject: [PATCH 5/5] Modified the AnnouncementsDualButtonWithIcon to handle closing the toast. --- .../AnnouncementsDualButtonWithIcon.jsx | 12 +++++++++--- Client/src/Components/Toast/index.jsx | 18 ++++++++++-------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Client/src/Components/Announcements/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon.jsx b/Client/src/Components/Announcements/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon.jsx index 574c255a0..bd2675f4c 100644 --- a/Client/src/Components/Announcements/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon.jsx +++ b/Client/src/Components/Announcements/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon.jsx @@ -1,5 +1,4 @@ import "./announcementsDualButtonWithIcon.css"; -import React from "react"; import CloseIcon from "@mui/icons-material/Close"; import PropTypes from "prop-types"; import { useTheme } from "@mui/material"; @@ -12,6 +11,7 @@ import { useTheme } from "@mui/material"; * @param {string} props.body - The announcement body text content * @param {string} props.esc - The text for the escape button (usually "Close") * @param {string} props.primary - The text for the primary button + * @param {function} props.closeToast - Function to close the toast notification * @returns {JSX.Element} - Renders the announcement dual button with icon component */ @@ -21,6 +21,7 @@ const AnnouncementsDualButtonWithIcon = ({ body, esc, primary, + closeToast, }) => { const theme = useTheme(); @@ -40,14 +41,18 @@ const AnnouncementsDualButtonWithIcon = ({ {body &&
{body}
} {(esc || primary) && (
- {esc &&
{esc}
} + {esc && ( +
+ {esc} +
+ )} {primary && (
{primary}
)}
)}
-
+
@@ -60,6 +65,7 @@ AnnouncementsDualButtonWithIcon.propTypes = { body: PropTypes.string, esc: PropTypes.string, primary: PropTypes.string, + closeToast: PropTypes.func.isRequired, }; export default AnnouncementsDualButtonWithIcon; diff --git a/Client/src/Components/Toast/index.jsx b/Client/src/Components/Toast/index.jsx index f3a06bdb1..ceb7a6f60 100644 --- a/Client/src/Components/Toast/index.jsx +++ b/Client/src/Components/Toast/index.jsx @@ -7,14 +7,16 @@ import "./index.css"; const ToastComponent = () => { const displayMsg = () => { toast( - } - subject="There was a problem with that action" - body="Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid pariatur, ipsum dolor." - esc="Dismiss" - primary="Learn more" - dismiss={() => toast.dismiss()} - />, + ({ closeToast, toastProps }) => ( + } + subject="There was a problem with that action" + body="Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid pariatur, ipsum dolor." + esc="Dismiss" + primary="Learn more" + closeToast={closeToast} + /> + ), { closeButton: false } ); };