diff --git a/Client/src/Components/Alert/index.css b/Client/src/Components/Alert/index.css
index 9f0c397e3..c65bfa38c 100644
--- a/Client/src/Components/Alert/index.css
+++ b/Client/src/Components/Alert/index.css
@@ -1,9 +1,7 @@
.alert {
margin: 0;
width: fit-content;
- padding: var(--env-var-spacing-1-plus);
+}
+.alert, .alert button{
font-size: var(--env-var-font-size-medium);
-}
-.alert .MuiStack-root {
- max-width: 85%;
-}
+}
\ No newline at end of file
diff --git a/Client/src/Components/Alert/index.jsx b/Client/src/Components/Alert/index.jsx
index bf2531bba..3fa0d82ab 100644
--- a/Client/src/Components/Alert/index.jsx
+++ b/Client/src/Components/Alert/index.jsx
@@ -1,10 +1,12 @@
import PropTypes from "prop-types";
import { useTheme } from "@emotion/react";
-import { Box, Stack } from "@mui/material";
+import { Box, IconButton, Stack } from "@mui/material";
import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";
import ErrorOutlineOutlinedIcon from "@mui/icons-material/ErrorOutlineOutlined";
import WarningAmberOutlinedIcon from "@mui/icons-material/WarningAmberOutlined";
+import CloseIcon from "@mui/icons-material/Close";
import "./index.css";
+import Button from "../Button";
/**
* Icons mapping for different alert variants.
@@ -22,10 +24,13 @@ const icons = {
* @param {'info' | 'error' | 'warning'} props.variant - The type of alert.
* @param {string} [props.title] - The title of the alert.
* @param {string} [props.body] - The body text of the alert.
+ * @param {boolean} [props.isToast] - Indicates if the alert is used as a toast notification.
+ * @param {boolean} [props.hasIcon] - Whether to display an icon in the alert.
+ * @param {function} props.onClick - Toast dismiss function.
* @returns {JSX.Element}
*/
-const Alert = ({ variant, title, body }) => {
+const Alert = ({ variant, title, body, isToast, hasIcon = true, onClick }) => {
const theme = useTheme();
const { bg, border, color } = theme.alert[variant];
const icon = icons[variant];
@@ -34,19 +39,67 @@ const Alert = ({ variant, title, body }) => {
- {icon && {icon}}
+ {hasIcon && {icon}}
{title && {title}}
{body && {body}}
+ {hasIcon && isToast && (
+
+ )}
+ {isToast && (
+
+
+
+ )}
);
};
@@ -55,6 +108,16 @@ Alert.propTypes = {
variant: PropTypes.oneOf(["info", "error", "warning"]).isRequired,
title: PropTypes.string,
body: PropTypes.string,
+ isToast: PropTypes.bool,
+ hasIcon: PropTypes.bool,
+ onClick: function (props, propName, componentName) {
+ if (props.isToast && !props[propName]) {
+ return new Error(
+ `Prop '${propName}' is required when 'isToast' is true in '${componentName}'.`
+ );
+ }
+ return null;
+ },
};
export default Alert;
diff --git a/Client/src/Components/TabPanels/Account/PasswordPanel.jsx b/Client/src/Components/TabPanels/Account/PasswordPanel.jsx
index d0f6e6f62..0e035f5cf 100644
--- a/Client/src/Components/TabPanels/Account/PasswordPanel.jsx
+++ b/Client/src/Components/TabPanels/Account/PasswordPanel.jsx
@@ -8,6 +8,7 @@ import { editPasswordValidation } from "../../../Validation/validation";
import Alert from "../../Alert";
import { update } from "../../../Features/Auth/authSlice";
import { useDispatch, useSelector } from "react-redux";
+import { createToast } from "../../../Utils/toastUtils";
/**
* PasswordPanel component manages the form for editing password.
@@ -78,15 +79,23 @@ const PasswordPanel = () => {
} else {
const action = await dispatch(update({ authToken, localData }));
if (action.payload.success) {
- // TODO: Add toast/notification for password update success
+ createToast({
+ variant: "info",
+ body: "Your password was changed successfully.",
+ hasIcon: false,
+ });
setLocalData({
password: "",
newPassword: "",
confirm: "",
});
} else {
- // TODO: Add toast/notification for password update rejected
// TODO: Check for other errors?
+ createToast({
+ variant: "info",
+ body: "Your password input was incorrect.",
+ hasIcon: false,
+ });
setErrors({ password: "*" + action.payload.msg + "." });
}
}
diff --git a/Client/src/Components/TabPanels/Account/ProfilePanel.jsx b/Client/src/Components/TabPanels/Account/ProfilePanel.jsx
index ab44b34b3..e96f507d9 100644
--- a/Client/src/Components/TabPanels/Account/ProfilePanel.jsx
+++ b/Client/src/Components/TabPanels/Account/ProfilePanel.jsx
@@ -22,6 +22,7 @@ import ImageIcon from "@mui/icons-material/Image";
import ProgressUpload from "../../ProgressBars";
import { formatBytes } from "../../../Utils/fileUtils";
import { clearMonitorState } from "../../../Features/Monitors/monitorsSlice";
+import { createToast } from "../../../Utils/toastUtils";
/**
* ProfilePanel component displays a form for editing user profile information
@@ -58,6 +59,7 @@ const ProfilePanel = () => {
// Handles input field changes and performs validation
const handleChange = (event) => {
+ errors["unchanged"] && clearError("unchanged");
const { value, id } = event.target;
const name = idToName[id];
setLocalData((prev) => ({
@@ -85,7 +87,7 @@ const ProfilePanel = () => {
delete: false,
});
- //TODO - potentitally remove once image compression functions are implemented
+ //TODO - potentitally remove, will revisit in the future
intervalRef.current = setInterval(() => {
const buffer = 12;
setProgress((prev) => {
@@ -151,14 +153,11 @@ const ProfilePanel = () => {
deleteProfileImage: false,
}));
setIsOpen("");
+ errors["unchanged"] && clearError("unchanged");
};
- console.log(
- localData.deleteProfileImage === false && localData.file === undefined
- );
-
// Handles form submission to update user profile
- const handleSaveProfile = (event) => {
+ const handleSaveProfile = async (event) => {
event.preventDefault();
if (
localData.firstname === user.firstname &&
@@ -166,12 +165,29 @@ const ProfilePanel = () => {
localData.deleteProfileImage === undefined &&
localData.file === undefined
) {
- // TODO: Add toast/notification for unchanged profile data
+ createToast({
+ variant: "warning",
+ body: "Unable to update profile: No changes detected.",
+ hasIcon: false,
+ });
+ setErrors({ unchanged: "unable to update profile" });
return;
}
- dispatch(update({ authToken, localData }));
- // TODO: Add toast/notification for profile update success
+ const action = await dispatch(update({ authToken, localData }));
+ if (action.payload.success) {
+ createToast({
+ variant: "info",
+ body: "Your profile data was changed successfully.",
+ hasIcon: false,
+ });
+ } else {
+ createToast({
+ variant: "error",
+ body: "There was an error updating your profile data.",
+ hasIcon: false,
+ });
+ }
};
// Removes current profile image from UI
@@ -180,6 +196,7 @@ const ProfilePanel = () => {
...prev,
deleteProfileImage: true,
}));
+ errors["unchanged"] && clearError("unchanged");
};
// Initiates the account deletion process
diff --git a/Client/src/Components/Toast/AnnouncementUpdateSubscription/AnnouncementUpdateSubscription.jsx b/Client/src/Components/Toast/AnnouncementUpdateSubscription/AnnouncementUpdateSubscription.jsx
deleted file mode 100644
index f3363e866..000000000
--- a/Client/src/Components/Toast/AnnouncementUpdateSubscription/AnnouncementUpdateSubscription.jsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import "./announcementUpdateSubscription.css";
-import React from "react";
-import PropTypes from "prop-types";
-import { useTheme } from "@mui/material";
-
-/**
- * @component
- * @param {Object} props
- * @param {string} props.title - Title text for the update subscription dialog (required)
- * @param {string} props.text - Body text for the update subscription dialog (required)
- * @param {string} props.cancel - Text for the negative (cancel) button (required)
- * @param {string} props.positive - Text for the positive button (required)
- * @param {string} props.header - Title text for the email subscription section (required)
- * @param {string} props.button - Text for the subscribe button (required)
- * @returns {JSX.Element} - Renders the announcement update subscription component
- */
-
-const AnnouncementUpdateSubscription = ({
- title,
- text,
- cancel,
- positive,
- header,
- button,
-}) => {
- const theme = useTheme();
-
- const fontLookup = {
- default: theme.font.default.font,
- };
-
- const fontFamily = fontLookup["default"];
-
- return (
-
-
-
{title}
-
-
{text}
-
-
-
-
-
-
-
-
-
{header}
-
-
-
-
-
-
- );
-};
-
-AnnouncementUpdateSubscription.propTypes = {
- title: PropTypes.string.isRequired,
- text: PropTypes.string.isRequired,
- cancel: PropTypes.string.isRequired,
- positive: PropTypes.string.isRequired,
- header: PropTypes.string.isRequired,
- button: PropTypes.string.isRequired,
-};
-
-export default AnnouncementUpdateSubscription;
diff --git a/Client/src/Components/Toast/AnnouncementUpdateSubscription/announcementUpdateSubscription.css b/Client/src/Components/Toast/AnnouncementUpdateSubscription/announcementUpdateSubscription.css
deleted file mode 100644
index 6064a86cd..000000000
--- a/Client/src/Components/Toast/AnnouncementUpdateSubscription/announcementUpdateSubscription.css
+++ /dev/null
@@ -1,86 +0,0 @@
-.update-subscription {
- margin: 20px;
-}
-
-.update-subscription,
-.update-subscription-dialog {
- max-width: 770px;
- border-radius: 4px;
- border: 1px solid #eaecf0;
-}
-
-.update-subscription-dialog {
- padding: 15px 30px;
-}
-
-.subscription-dialog-title {
- font-size: 1rem;
- font-weight: 700;
- color: var(--env-var-color-1);
-}
-
-.v-spacing-small {
- height: 10px;
-}
-
-.v-spacing-medium {
- height: 15px;
-}
-
-.subscription-dialog-text {
- font-size: 13px;
- color: var(--env-var-color-2);
-}
-
-.subscription-dialog-controls {
- display: flex;
-}
-
-.controls-negative {
- padding: 12px 16px;
- margin-right: 12px;
- border-radius: var(--env-var-radius-1);
- border: 1px solid var(--env-var-color-6);
- background-color: var(--env-var-color-8);
- font-size: var(--env-var-font-size-medium);
-}
-
-.controls-positive,
-.subscribe-button {
- padding: 12px 16px;
- margin-right: 12px;
- border-radius: var(--env-var-radius-1);
- border: 1px solid var(--env-var-color-7);
- background-color: var(--env-var-color-3);
- color: var(--env-var-color-8);
- font-size: var(--env-var-font-size-medium);
-}
-
-.update-subscription-title {
- color: var(--env-var-color-5);
- padding: 0 20px;
- font-weight: 700;
- font-size: 13px;
- margin-bottom: 10px;
-}
-
-.subscription-email {
- display: flex;
- padding: 0 20px;
-}
-
-.subscription-email-field {
- width: 290px;
- height: 24px;
- border-radius: var(--env-var-radius-1);
- border: 1px solid var(--env-var-color-4);
- box-shadow: 0px 1px 2px 0px rgba(101, 182, 28, 0.05);
- padding: 5px 15px;
- margin-right: 20px;
-}
-
-.subscribe-button {
- width: 100px;
- height: 34px;
- padding: 2px 15px;
-}
diff --git a/Client/src/Components/Toast/AnnouncementsDualButton/AnnouncementsDualButton.jsx b/Client/src/Components/Toast/AnnouncementsDualButton/AnnouncementsDualButton.jsx
deleted file mode 100644
index 2abbadb1e..000000000
--- a/Client/src/Components/Toast/AnnouncementsDualButton/AnnouncementsDualButton.jsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import "./announcementsDualButton.css";
-import React from "react";
-import CloseIcon from "@mui/icons-material/Close";
-import PropTypes from "prop-types";
-import { useTheme } from "@mui/material";
-
-/**
- * @component
- * @param {Object} props
- * @param {string} props.subject - The announcement subject text
- * @param {string} props.body - The announcement body text content
- * @param {string} props.esc - The text for the escape button
- * @param {string} props.primary - The text for the primary button
- * @returns {JSX.Element} - Renders the announcement dual button component
- */
-
-const AnnouncementsDualButton = ({ subject, body, esc, primary }) => {
- const theme = useTheme();
-
- const fontLookup = {
- default: theme.font.default.font,
- };
-
- const fontFamily = fontLookup["default"];
-
- return (
-
-
-
{subject}
-
-
{body}
-
-
-
-
-
-
-
- );
-};
-
-AnnouncementsDualButton.propTypes = {
- subject: PropTypes.string.isRequired,
- body: PropTypes.string.isRequired,
- esc: PropTypes.string.isRequired,
- primary: PropTypes.string.isRequired,
-};
-
-export default AnnouncementsDualButton;
diff --git a/Client/src/Components/Toast/AnnouncementsDualButton/announcementsDualButton.css b/Client/src/Components/Toast/AnnouncementsDualButton/announcementsDualButton.css
deleted file mode 100644
index aff02ab46..000000000
--- a/Client/src/Components/Toast/AnnouncementsDualButton/announcementsDualButton.css
+++ /dev/null
@@ -1,25 +0,0 @@
-.announcement-without-tile {
- margin: 20px;
- max-width: 343px;
- width: fit-content;
- display: flex;
- border: 1px solid var(--env-var-color-4);
- padding: 16px;
- border-radius: var(--env-var-radius-1);
-}
-
-.h-spacing {
- width: 20px;
-}
-
-.announcement-without-content-subject {
- font-size: var(--env-var-font-size-medium);
- color: var(--env-var-color-5);
- font-weight: 700;
- margin-bottom: 10px;
-}
-
-.announcement-without-content-body {
- font-size: var(--env-var-font-size-medium);
- color: var(--env-var-color-2);
-}
diff --git a/Client/src/Components/Toast/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon.jsx b/Client/src/Components/Toast/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon.jsx
deleted file mode 100644
index bd2675f4c..000000000
--- a/Client/src/Components/Toast/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon.jsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import "./announcementsDualButtonWithIcon.css";
-import CloseIcon from "@mui/icons-material/Close";
-import PropTypes from "prop-types";
-import { useTheme } from "@mui/material";
-
-/**
- * @component
- * @param {Object} props
- * @param {React.ReactNode} props.icon - Optional React node for an announcement icon
- * @param {string} props.subject - The announcement subject text
- * @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
- */
-
-const AnnouncementsDualButtonWithIcon = ({
- icon,
- subject,
- body,
- esc,
- primary,
- closeToast,
-}) => {
- const theme = useTheme();
-
- const fontLookup = {
- default: theme.font.default.font,
- };
-
- const fontFamily = fontLookup["default"];
-
- return (
-
- {icon &&
{icon}
}
-
- {subject && (
-
{subject}
- )}
- {body &&
{body}
}
- {(esc || primary) && (
-
- {esc && (
-
- {esc}
-
- )}
- {primary && (
-
{primary}
- )}
-
- )}
-
-
-
-
-
- );
-};
-
-AnnouncementsDualButtonWithIcon.propTypes = {
- icon: PropTypes.object,
- subject: PropTypes.string,
- body: PropTypes.string,
- esc: PropTypes.string,
- primary: PropTypes.string,
- closeToast: PropTypes.func.isRequired,
-};
-
-export default AnnouncementsDualButtonWithIcon;
diff --git a/Client/src/Components/Toast/AnnouncementsDualButtonWithIcon/announcementsDualButtonWithIcon.css b/Client/src/Components/Toast/AnnouncementsDualButtonWithIcon/announcementsDualButtonWithIcon.css
deleted file mode 100644
index 02f132374..000000000
--- a/Client/src/Components/Toast/AnnouncementsDualButtonWithIcon/announcementsDualButtonWithIcon.css
+++ /dev/null
@@ -1,58 +0,0 @@
-.announcement-tile {
- margin: 20px;
- width: fit-content;
- display: flex;
- border: 1px solid var(--env-var-color-4);
- padding: 16px;
- border-radius: var(--env-var-radius-1);
-}
-
-.info-icon-frame {
- display: flex;
- width: var(--env-var-default-2);
- height: var(--env-var-default-2);
- border: 1px solid var(--env-var-color-6);
- border-radius: var(--env-var-radius-2);
- justify-content: center;
- align-items: center;
-}
-
-.announcement-content {
- padding: 0 16px;
-}
-
-.announcement-content-subject {
- font-size: var(--env-var-font-size-medium);
- color: var(--env-var-color-5);
- font-weight: 700;
- margin-bottom: 10px;
-}
-
-.announcement-content-body {
- font-size: var(--env-var-font-size-medium);
- color: var(--env-var-color-2);
- font-weight: 300;
-}
-
-.announcement-content-controllers {
- display: flex;
- font-size: var(--env-var-font-size-medium);
- margin-top: 15px;
-}
-
-.controllers-button-esc {
- font-size: var(--env-var-font-size-medium);
- font-weight: 600;
- margin-right: 12px;
-}
-
-.controllers-button-primary {
- font-size: var(--env-var-font-size-medium);
- font-weight: 600;
- color: var(--env-var-color-3);
-}
-
-.announcement-close {
- width: var(--env-var-default-1);
- height: var(--env-var-default-1);
-}
diff --git a/Client/src/Components/Toast/AnnouncementsMessageBar/AnnouncementsMessageBar.jsx b/Client/src/Components/Toast/AnnouncementsMessageBar/AnnouncementsMessageBar.jsx
deleted file mode 100644
index 20a179052..000000000
--- a/Client/src/Components/Toast/AnnouncementsMessageBar/AnnouncementsMessageBar.jsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import "./announcementsMessageBar.css";
-import React from "react";
-import CloseIcon from "@mui/icons-material/Close";
-import PropTypes from "prop-types";
-import { useTheme } from "@mui/material";
-
-/**
- * @component
- * @param {Object} props
- * @param {string} props.message - The announcement message text content (required)
- * @returns {JSX.Element} - Renders the announcement message bar component
- */
-const AnnouncementsMessageBar = ({ message }) => {
- const theme = useTheme();
-
- const fontLookup = {
- default: theme.font.default.font,
- };
-
- const fontFamily = fontLookup["default"];
-
- return (
-
- );
-};
-
-AnnouncementsMessageBar.propTypes = {
- message: PropTypes.string.isRequired,
-};
-
-export default AnnouncementsMessageBar;
diff --git a/Client/src/Components/Toast/AnnouncementsMessageBar/announcementsMessageBar.css b/Client/src/Components/Toast/AnnouncementsMessageBar/announcementsMessageBar.css
deleted file mode 100644
index 7a6e30b0a..000000000
--- a/Client/src/Components/Toast/AnnouncementsMessageBar/announcementsMessageBar.css
+++ /dev/null
@@ -1,8 +0,0 @@
-.announcement-messagebar-body {
- margin: 20px;
- font-size: var(--env-var-font-size-medium);
- padding: 0 16px 0 0;
- justify-content: center;
- align-items: center;
- margin: auto;
-}
diff --git a/Client/src/Components/Toast/index.css b/Client/src/Components/Toast/index.css
deleted file mode 100644
index c778d22f5..000000000
--- a/Client/src/Components/Toast/index.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.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
deleted file mode 100644
index 41367ec11..000000000
--- a/Client/src/Components/Toast/index.jsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import PropTypes from "prop-types";
-import ComplexAlert from "../../Components/Icons/ComplexAlert/ComplexAlert";
-import AnnouncementsDualButtonWithIcon from "./AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon";
-import "react-toastify/dist/ReactToastify.css";
-import { toast, ToastContainer } from "react-toastify";
-import "./index.css";
-
-/**
- * ToastComponent displays a notification that is triggered by error messages.
- *
- * @component
- * @param {Object} props - The component props
- * @param {string} props.subject - The subject or title of the toast message
- * @param {string} props.body - The body content of the toast message
- * @param {string} props.esc - The text for the dismiss action button
- * @param {string} props.primary - The text for the primary action button
- * @returns {JSX.Element} JSX element representing the ToastComponent
- */
-
-const ToastComponent = ({ subject, body, esc, primary }) => {
- const displayMsg = () => {
- toast(
- ({ closeToast, toastProps }) => (
- }
- subject={subject}
- body={body}
- esc={esc}
- primary={primary}
- closeToast={closeToast}
- />
- ),
- { closeButton: false }
- );
- };
-
- return (
-
-
-
-
- );
-};
-
-ToastComponent.propTypes = {
- subject: PropTypes.string.isRequired,
- body: PropTypes.string.isRequired,
- esc: PropTypes.string.isRequired,
- primary: PropTypes.string.isRequired,
-};
-
-export default ToastComponent;
diff --git a/Client/src/Pages/Account/index.jsx b/Client/src/Pages/Account/index.jsx
index 2bb4dc018..ec010f006 100644
--- a/Client/src/Pages/Account/index.jsx
+++ b/Client/src/Pages/Account/index.jsx
@@ -8,6 +8,8 @@ import ProfilePanel from "../../Components/TabPanels/Account/ProfilePanel";
import PasswordPanel from "../../Components/TabPanels/Account/PasswordPanel";
import TeamPanel from "../../Components/TabPanels/Account/TeamPanel";
import { useNavigate } from "react-router";
+import "react-toastify/dist/ReactToastify.css";
+import { ToastContainer } from "react-toastify";
/**
* Account component renders a settings page with tabs for Profile, Password, and Team settings.
@@ -73,6 +75,7 @@ const Account = ({ open = "profile" }) => {
+
);
};
diff --git a/Client/src/Pages/Demo/Demo.jsx b/Client/src/Pages/Demo/Demo.jsx
index 42e30b6d2..6a7a07e11 100644
--- a/Client/src/Pages/Demo/Demo.jsx
+++ b/Client/src/Pages/Demo/Demo.jsx
@@ -40,6 +40,8 @@ import { getMonitorsByUserId } from "../../Features/Monitors/monitorsSlice";
import ImageField from "../../Components/TextFields/Image";
import ProgressUpload from "../../Components/ProgressBars";
import Alert from "../../Components/Alert";
+import { createToast } from "../../Utils/toastUtils";
+import { ToastContainer } from "react-toastify";
const cols = [
{
@@ -421,11 +423,20 @@ const Demo = () => {
-
+ console.log("changed")}
+ />
- } label="image.jpg" size="2 MB" />
+ }
+ label="image.jpg"
+ size="2 MB"
+ progress={50}
+ onClick={() => console.log("click")}
+ />
@@ -449,8 +460,38 @@ const Demo = () => {
body="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
/>
+
+
+
+
+
+
+
+
+
);
};
diff --git a/Client/src/Pages/PlayGround/PlayGround.jsx b/Client/src/Pages/PlayGround/PlayGround.jsx
index bde0b6761..247146362 100644
--- a/Client/src/Pages/PlayGround/PlayGround.jsx
+++ b/Client/src/Pages/PlayGround/PlayGround.jsx
@@ -4,16 +4,9 @@ import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
import HelpOutlineIcon from "@mui/icons-material/HelpOutline";
import WebsiteTextField from "../../Components/TextFields/Website/WebsiteTextField";
import DescriptionTextField from "../../Components/TextFields/Description/DescriptionTextField";
-import AnnouncementsDualButton from "../../Components/Toast/AnnouncementsDualButton/AnnouncementsDualButton";
-import AnnouncementsDualButtonWithIcon from "../../Components/Toast/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon";
-import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";
-import ComplexAlert from "../../Components/Icons/ComplexAlert/ComplexAlert";
-import AnnouncementsMessageBar from "../../Components/Toast/AnnouncementsMessageBar/AnnouncementsMessageBar";
-import AnnouncementUpdateSubscription from "../../Components/Toast/AnnouncementUpdateSubscription/AnnouncementUpdateSubscription";
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
@@ -53,7 +46,6 @@ function PlayGround() {
hasCopyButton={true}
hintText="This is a hint text to help user."
/>
-
{/* Now, illustration of the Description text fields */}
@@ -66,55 +58,6 @@ function PlayGround() {
hasError={true}
hintText="This is a hint text to help user."
/>
-
-
-
- }
- subject="We’ve just released a new feature"
- body="Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid
- pariatur, ipsum dolor."
- esc="Dismiss"
- primary="View changes"
- />
-
- }
- 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"
- />
-
- }
- subject="Successfully updated profile"
- body="Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid
- pariatur, ipsum dolor."
- esc="Dismiss"
- primary="Learn more"
- />
-
-
-
-
-
-
diff --git a/Client/src/Utils/Theme.js b/Client/src/Utils/Theme.js
index 60273cd95..4b345c9de 100644
--- a/Client/src/Utils/Theme.js
+++ b/Client/src/Utils/Theme.js
@@ -109,9 +109,9 @@ const theme = createTheme({
border: "#f04438",
},
warning: {
- color: "#f79009",
- bg: "#fffaef",
- border: "#fecf60"
+ color: "#DC6803",
+ bg: "#fffcf5",
+ border: "#fec84b"
},
},
});
diff --git a/Client/src/Utils/toastUtils.jsx b/Client/src/Utils/toastUtils.jsx
new file mode 100644
index 000000000..73c21c260
--- /dev/null
+++ b/Client/src/Utils/toastUtils.jsx
@@ -0,0 +1,44 @@
+import PropTypes from "prop-types";
+import { toast } from "react-toastify";
+import Alert from "../Components/Alert";
+
+/**
+ * @param {object} props
+ * @param {'info' | 'error' | 'warning'} - The variant of the alert (e.g., "info", "error").
+ * @param {string} props.title - The title of the alert.
+ * @param {string} props.body - The body/content of the alert.
+ * @param {boolean} props.hasIcon - Whether the alert should include an icon.
+ * @param {object} [props.config] - Additional configuration props for the toast.
+ */
+
+export const createToast = ({ variant, title, body, hasIcon, config = {} }) => {
+ const toastConfig = {
+ position: "bottom-right",
+ autoClose: 3000,
+ hideProgressBar: true,
+ closeButton: false,
+ ...config,
+ };
+
+ toast(
+ ({ closeToast }) => (
+
+ ),
+ toastConfig
+ );
+};
+
+createToast.propTypes = {
+ variant: PropTypes.oneOf(["info", "error", "warning"]).isRequired,
+ title: PropTypes.string,
+ body: PropTypes.string,
+ hasIcon: PropTypes.bool,
+ config: PropTypes.object,
+};
diff --git a/Client/src/index.css b/Client/src/index.css
index 4af5f4e84..086692678 100644
--- a/Client/src/index.css
+++ b/Client/src/index.css
@@ -124,6 +124,18 @@ button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
+.Toastify__toast-container {
+ width: auto;
+}
+.Toastify [class^="Toastify__toast"] {
+ padding: 0;
+ margin: 0;
+}
+.Toastify__toast{
+ min-height: 0;
+ border-radius: 4px;
+}
+
@media (prefers-color-scheme: light) {
:root {
color: #213547;