diff --git a/src/components/App.js b/src/components/App.js
index efb1554..7f6ca2f 100644
--- a/src/components/App.js
+++ b/src/components/App.js
@@ -1,6 +1,5 @@
import React, { useEffect } from "react";
import { HashRouter, Route, Switch, Redirect } from "react-router-dom";
-import ToastContainer from "./Toast/ToastContainer";
// components
import Layout from "./Layout/Layout";
@@ -35,7 +34,6 @@ export default function App() {
-
);
diff --git a/src/components/toast/styles.js b/src/components/toast/styles.js
index 456f118..abd2d12 100644
--- a/src/components/toast/styles.js
+++ b/src/components/toast/styles.js
@@ -9,5 +9,18 @@ export default makeStyles((theme) => ({
notificationCloseButton: {
position: "absolute",
right: theme.spacing(2)
+ },
+ notificationComponent: {
+ paddingRight: theme.spacing(4)
+ },
+ progress: {
+ visibility: "hidden"
+ },
+ notification: {
+ display: "flex",
+ alignItems: "center",
+ background: "transparent",
+ boxShadow: "none",
+ overflow: "visible"
}
}));
diff --git a/src/context/ToastContext.js b/src/context/ToastContext.js
new file mode 100644
index 0000000..80ef189
--- /dev/null
+++ b/src/context/ToastContext.js
@@ -0,0 +1,143 @@
+import React, { useReducer, useMemo, useCallback } from "react";
+import { toast } from "react-toastify";
+import useStyles from "../components/Toast/styles";
+import ToastContainer from "../components/Toast/ToastContainer";
+import Notification from "../components/Notification";
+
+const positions = [
+ toast.POSITION.TOP_LEFT,
+ toast.POSITION.TOP_CENTER,
+ toast.POSITION.TOP_RIGHT,
+ toast.POSITION.BOTTOM_LEFT,
+ toast.POSITION.BOTTOM_CENTER,
+ toast.POSITION.BOTTOM_RIGHT
+];
+
+const ToastStateContext = React.createContext();
+const ToastDispatchContext = React.createContext();
+
+const toastInitialState = { position: 2 };
+const toastReducer = (state, action) => {
+ switch (action.type) {
+ case "onNotificationPositionChange":
+ return { ...state, position: action.payload.position };
+ default: {
+ return state;
+ }
+ }
+};
+
+export const toastDispatchActions = (dispatch) => ({
+ changeNotificationPosition: (position) =>
+ dispatch({ type: "onNotificationPositionChange", payload: { position } })
+});
+
+const ToastProvider = ({ children }) => {
+ // var [errorToastId, setErrorToastId] = useState(null);
+ const [state, dispatch] = useReducer(toastReducer, toastInitialState);
+ const dispatchActions = useMemo(() => toastDispatchActions(dispatch), [
+ dispatch
+ ]);
+
+ const classes = useStyles();
+
+ const sendNotification = useCallback(
+ (componentProps, options) => {
+ return toast(
+ ,
+ options
+ );
+ },
+ [classes]
+ );
+
+ const notify = useCallback(
+ (message, type, extraButtonClick) => {
+ // if (errorToastId && type === "error") return;
+
+ let componentProps;
+
+ switch (type) {
+ case "info":
+ componentProps = {
+ type: "feedback",
+ message,
+ variant: "contained",
+ color: "primary"
+ };
+ break;
+ case "error":
+ componentProps = {
+ type: "message",
+ message,
+ variant: "contained",
+ color: "secondary",
+ extraButton: "Resend",
+ extraButtonClick
+ };
+ break;
+ default:
+ componentProps = {
+ type: "shipped",
+ message,
+ variant: "contained",
+ color: "success"
+ };
+ }
+
+ const toastId = sendNotification(componentProps, {
+ type,
+ position: positions[state.position],
+ progressClassName: classes.progress,
+ // onClose: type === "error" && (() => setErrorToastId(null)),
+ className: classes.notification
+ });
+
+ // if (type === "error") setErrorToastId(toastId);
+
+ return toastId;
+ },
+ [sendNotification, classes, state.position]
+ );
+
+ const actions = useMemo(
+ () => ({
+ ...dispatchActions,
+ info: (message) => notify(message, "info"),
+ notify
+ }),
+ [dispatchActions, notify]
+ );
+
+ return (
+
+
+ <>
+ {children}
+
+ >
+
+
+ );
+};
+
+const useToast = () => {
+ const context = React.useContext(ToastDispatchContext);
+ if (context === undefined) {
+ throw new Error("useToast must be used within a ToastProvider");
+ }
+ return context;
+};
+
+const useToastState = () => {
+ var context = React.useContext(ToastStateContext);
+ if (context === undefined) {
+ throw new Error("useToastState must be used within a ToastProvider");
+ }
+ return context;
+};
+
+export { ToastProvider, useToast, useToastState };
diff --git a/src/index.js b/src/index.js
index 139a7fe..38be7a5 100644
--- a/src/index.js
+++ b/src/index.js
@@ -7,6 +7,7 @@ import App from "./components/App";
import * as serviceWorker from "./serviceWorker";
import { LayoutProvider } from "./context/LayoutContext";
import { UserProvider } from "./context/UserContext";
+import { ToastProvider } from "./context/ToastContext";
import "./utils/i18n";
ReactDOM.render(
@@ -15,7 +16,9 @@ ReactDOM.render(
Loading...}>
-
+
+
+
diff --git a/src/pages/notifications/Notifications.js b/src/pages/notifications/Notifications.js
index 80ff429..496fa79 100644
--- a/src/pages/notifications/Notifications.js
+++ b/src/pages/notifications/Notifications.js
@@ -15,20 +15,15 @@ import PageTitle from "../../components/PageTitle/PageTitle";
import Notification from "../../components/Notification";
import { Typography, Button } from "../../components/Wrappers/Wrappers";
-const positions = [
- toast.POSITION.TOP_LEFT,
- toast.POSITION.TOP_CENTER,
- toast.POSITION.TOP_RIGHT,
- toast.POSITION.BOTTOM_LEFT,
- toast.POSITION.BOTTOM_CENTER,
- toast.POSITION.BOTTOM_RIGHT
-];
+// context
+import { useToast, useToastState } from "../../context/ToastContext";
export default function NotificationsPage(props) {
- var classes = useStyles();
+ const classes = useStyles();
+ const { notify, changeNotificationPosition } = useToast();
+ const { position: notificationsPosition } = useToastState();
// local
- var [notificationsPosition, setNotificationPosition] = useState(2);
var [errorToastId, setErrorToastId] = useState(null);
return (
@@ -123,7 +118,7 @@ export default function NotificationsPage(props) {